0
$\begingroup$

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.

$\endgroup$

1 Answer 1

0
$\begingroup$

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.

$\endgroup$
3
  • $\begingroup$ 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? $\endgroup$
    – fishfinder
    Commented May 28, 2022 at 23:09
  • $\begingroup$ yep, as I wrote. $\endgroup$ Commented May 28, 2022 at 23:10
  • $\begingroup$ only that your number_samples_in_seq is ... strangely calculated. You should just use len(data). Not sampling_rate*(len(data)/sampling_rate)... $\endgroup$ Commented May 28, 2022 at 23:11

Your Answer

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

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