diff --git a/friture/spectrum.py b/friture/spectrum.py index 6e93f553..bc7a1982 100644 --- a/friture/spectrum.py +++ b/friture/spectrum.py @@ -166,7 +166,7 @@ def handle_new_data(self, floatdata): # likely to correspond to a fundamental frequency. harmonic_products = self.harmonic_product_spectrum(sp1) pitch_idx = argmax(harmonic_products) - fpitch = self.freq[pitch_idx] + fpitch = max(self.freq[pitch_idx], 1e-20) self.PlotZoneSpect.setdata(self.freq, dB_spectrogram, fmax, fpitch) diff --git a/friture/spectrumPlotWidget.py b/friture/spectrumPlotWidget.py index d1841fba..bf1a4e09 100644 --- a/friture/spectrumPlotWidget.py +++ b/friture/spectrumPlotWidget.py @@ -137,6 +137,18 @@ def set_baseline_displayUnits(self, baseline): def set_baseline_dataUnits(self, baseline): self._baseline = Baseline.DATA_ZERO + + def freq_to_note(self, freq: float) -> str: + if freq == 0: + return "" + # number of semitones from C4 + # A4 = 440Hz and is 9 semitones above C4 + semitone = round(np.log2(freq/440) * 12) + 9 + octave = int(np.floor(semitone / 12)) + 4 + notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] + return f'{notes[semitone % 12]}{octave}' + + def setdata(self, x, y, fmax, fpitch): if not self.paused: if fmax < 2e2: @@ -145,7 +157,7 @@ def setdata(self, x, y, fmax, fpitch): text = "%d Hz" % (np.rint(fmax)) self._spectrum_data.setFmax(text, self.normHorizontalScaleTransform.toScreen(fmax)) self._spectrum_data.setFpitch( - f'{int(fpitch)} Hz', + f'{int(fpitch)} Hz ({self.freq_to_note(fpitch)})', self.normHorizontalScaleTransform.toScreen(fpitch) )