0

I am looking to determine whether a given audio file contains a certain frequency, similar to this question. However, as a beginner, I need help understanding the output.

If I am understanding the linked question correctly, we start by observing the fftfreq output, which is the x axis if understood graphically. Since my sampling rate is 44kHz, the fftfreq contains approximately 22,000 bins. If I wanted to query what magnitude occurred at 800hz, I would simply access value = fftfreq_output[800], then index the actual fft values using this new value like so: fft_output[value]. However, I am confused by the values that are returned. My code is below:

from scipy.io import wavfile
from scipy.fft import fft, fftfreq
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd

user_in = input("Please enter the relative path to your wav file --> ") sampling_rate, data = wavfile.read(user_in) print("sampling rate:", sampling_rate)

duration = len(data) / float(sampling_rate) print("duration:", duration)

number_samples_in_seg = int(sampling_rate * duration) fft_of_data = fft(data) fft_bins_from_data = fftfreq(number_samples_in_seg, 1 / sampling_rate) fft_bins_from_data = fft_bins_from_data[0:number_samples_in_seg//2] fft_of_data = abs(fft_of_data[0:number_samples_in_seg//2])

value = fft_bins_from_data[800] print(value)

output = fft_of_data[int(value)]

print(output)

inputing a random wav file of a conversation, my output is this:

6.1500615006150054
71544.37927836686

My questions are:

  1. Am I properly indexing the fft_output?

  2. How can I interpret these numbers to observe what is the magnitude of the signal at a frequency of 800hz?

Thank you for any help.

1 Answers1

0

no, it's the other way around: value contains the frequency that the 800th entry in your FFT represents.

Honestly, fftfreqs is not ... useful. An FFT of length $N$ always divides the sample rate in $N$ equal pieces, $\Delta f = \frac{f_{\text{sample}}}N$. With 0Hz being the 0.th element, and the $k$th element representing frequency $k\cdot \Delta f$.

So, if you want to know which bin represents a frequency $f$, you just divide that by $\Delta f = \frac{f_{\text{sample}}}N$ to get the number of the bin you should look into. Division by $\frac{f_{\text{sample}}}N$ is the same as multiplication by $\frac N{f_{\text{sample}}}$.

So, not quite sure why there's a function for that.

Marcus Müller
  • 30,525
  • 4
  • 34
  • 58
  • Thank you very much! So, just to confirm, if I was looking for frequency 800hz, I could find that bin by computing: 800 * (number_samples_in_seg / fsample) where fsample is equal to the sampling rate? – fishfinder May 28 '22 at 23:09
  • yep, as I wrote. – Marcus Müller May 28 '22 at 23:10
  • only that your number_samples_in_seq is ... strangely calculated. You should just use len(data). Not sampling_rate*(len(data)/sampling_rate)... – Marcus Müller May 28 '22 at 23:11