0

To perform this task why can't I just import the file, and directly perform the fft and use the stem plot to determine the note? From the index k of the peak I can do w = 2pi*k/N where N is total number of points.

Fs, x = wavfile.read('piano.wav')
X = np.fft.fft(x)
plt.plot(abs(X))
plt.show()

However I'm not sure about the correct way to map the fourier coefficients from the plot to the frequency to determine the note.

Please advise. Thanks.

Sid
  • 103
  • 1

2 Answers2

2

An FFT magnitude peak frequency (derived from a single FFT result index) is not reliably the same thing as the music pitch frequency or the musical note. Note pitch is a psychoacoustic phenomena, and more reliably related to periodicity than the (sinusoidal) spectral peak frequency (e.g. a periodic/repeating waveform shape does not need to look like a sine wave). See FFT Pitch Detection methods: Autocorrelation or other? for a list of some better methods for estimating note pitch frequency or the musical note.

hotpaw2
  • 35,346
  • 9
  • 47
  • 90
-1

this was taken from this article here: http://pythonforengineers.com/audio-and-digital-signal-processingdsp-in-python/

frame_rate = 48000.0
infile = "test.wav"
num_samples = 48000
wav_file = wave.open(infile, 'r')
data = wav_file.readframes(num_samples)
wav_file.close()
data = struct.unpack('{n}h'.format(n=num_samples), data)
data = np.array(data)
data_fft = np.fft.fft(data)
# This will give us the frequency we want
frequencies = np.abs(data_fft)
print("The frequency is {} Hz".format(np.argmax(frequencies)))
  • PySoundFile is a lot simpler way to open wav files 2. Your code outputs an entire spectrum, not a frequency.
  • – endolith May 22 '17 at 16:25
  • @endolith the last line finds the loudest frequency in the file – Carter Cole May 25 '17 at 16:48
  • ah yes, but only because the sample is exactly 1 second long – endolith May 25 '17 at 17:10