I've written a simple program to take an audio file, and calculate the most prominent frequency for every 0.1s interval.
My audio file has a sampling rate of 48000, and am taking datapoint windows of 4800.
Using np.fft.fft
, I am trying to find the most prominent frequency in that 0.1s window. When checking the output, my FFT works perfectly for frequencies above 100Hz, but for any value lower than that, I am getting incorrect results. For instance, at 75Hz, I get an output of 225Hz. Even after changing the resolution of the FFT, I am getting 225 as the output.
Some help would be great. Here is the code:
def fft_abs(audio):
audio_fft = np.fft.fft(audio)
audio_fft_p1 = audio_fft[0: int(len(audio_fft) / 2)] # FFT output is symmetrical along the middle. Only need first half of data
audio_abs = np.abs(audio_fft_p1)
return audio_abs
def freq_time(audio, sr):
tr = int(0.1*sr) #sr = num datapoints for 1s. tr = sr / 2
frequencies = []
for i in range(int(len(audio) / tr)):
freqs = np.fft.fftfreq(tr, 1/sr) # FFT output to frequency mapping
valid_is = np.where(freqs[0:tr//2] < 300) # Only freqs < 300 Hz are valid human voices
i_max = np.argmax( fft_abs(audio[(tr*i):tr*(i + 1)])[valid_is] ) # Index of Max FFT Output
freq = freqs[i_max] # Find Corresponding Frequency
frequencies.append(freq)
frequencies = np.array(frequencies)
return frequencies