0
$\begingroup$

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
$\endgroup$

1 Answer 1

0
$\begingroup$

hat's hard to tell without seeing your actual signal and looking at your entire signal chain. A few observations and ideas:

  1. Spectral analysis works much better with proper windowing. However, lack of windowing tends to be more of a high frequency problem, so this is probably or your specific issue.
  2. 225Hz is the third harmonic of 75Hz. For many audio signal it's perfectly normal to have more energy in the harmonics than in the fundamental frequency. Example would be a note played on a guitar.
  3. Something in your signal chain might be clipping or some other non-linear distortion happens.
  4. You have a high pass somewhere in you signal chain. Almost all audio hardware has a high pass somewhere and for voice applications 80Hz or 100Hz or typically choices since human voices don't go lower than that.

I suggest capturing your signal as a wave file and then looking at it with a "known good" signal editor and spectral analyzer such as Audactity.

$\endgroup$
2
  • $\begingroup$ Thanks, I looked at it in more detail. My signal is just a tone of 75Hz. I also noticed that 75 Hz is a harmonic. Is there a way I can find lower harmonics and use that instead? The issue I am facing is that sometimes I detect 226Hz, so can't divide by 3 to find the other harmonic. Also, I sometimes get the 2nd harmonic as well, so any suggestions? $\endgroup$
    – Ayush Goel
    Jul 27, 2021 at 13:31
  • $\begingroup$ My suggestion is in the last sentence of my answer. You need to take a closer look at your signals and signal chain $\endgroup$
    – Hilmar
    Jul 28, 2021 at 15:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.