1
$\begingroup$

I am fairly new to python and signal processing and I was given a task to record audio for 'x' seconds and then find the peak frequency in the audio file.

So far I have successfully implemented the recording part (records as a .wav file, sample rate = 44.1 kHz) but I am unable to correctly find and output the peak frequency in that file.

The goal of this task is that if a frequency above a certain threshold is found, other actions will take place. Could anyone please assist me on how to find the peak frequency.

So far I have attempted this using the scipy fft package and some pieces of code taken from research.

from scipy import signal
from scipy.io import wavfile
from scipy.fftpack import fft, ifft,fftfreq
import matplotlib.pyplot as plt
import wave 
import numpy as np
import sys
import struct

frate,data = wavfile.read('output.wav')
print(frate)

w = np.fft.fft(data)
freqs = np.fft.fftfreq(len(w))

# Find the peak in the coefficients
idx = np.argmax(np.abs(w))
print(idx)
freq = freqs[idx]
freq_in_hertz = abs(freq * frate)

print(freq_in_hertz)
print("HZ")

When audio is recorded, the above code sometimes works but however, an incorrect peak frequency is detected (for example I record something that I know has frequencies of 10kHz but it says peak frequency detected is 6kHz)

Other times when I record audio and try to find the peak frequency, i get the following error message: Exception has occurred: IndexError index 547388 is out of bounds for axis 0 with size 480000 File "C:\Users\aviso\Documents\VS Code Projects\FinalDesign\HighFreqTest.py", line 22, in freq = freqs[idx]

$\endgroup$
7
  • $\begingroup$ Sorry, forgot to add that I tried other sample rates as well such as 96 kHz and 48 kHz and still the above persists $\endgroup$
    – AvizzS
    Aug 10, 2019 at 23:34
  • 1
    $\begingroup$ This is more of a programming question so it might be more appropriate to post it on stack overflow. $\endgroup$
    – PAK-9
    Aug 11, 2019 at 0:49
  • $\begingroup$ I understand, I am sorry @PAK-9, I only came here because I asked this question on stack overflow but I have not received any response for 25 days. $\endgroup$
    – AvizzS
    Aug 11, 2019 at 15:22
  • $\begingroup$ You got any solution for this ? $\endgroup$
    – Nair
    Jan 23, 2020 at 8:24
  • $\begingroup$ I have example code for this published already, but I'm not sure what the policy is for homework questions. The most important thing is to plot each step and understand what you're looking at, and then you'll figure out why it's giving the wrong numbers. $\endgroup$
    – endolith
    Jan 23, 2020 at 21:17

1 Answer 1

1
$\begingroup$
import sounddevice as sd
import scipy
import numpy as np
from scipy.io import wavfile as wav
from scipy.io.wavfile import write ,read
from scipy import fftpack as scfft
from matplotlib import pyplot as plt

fs = 44100  
seconds = 3
myrecording = sd.rec(int(seconds * fs), samplerate=fs, channels=1)
sd.wait()  
write('output.wav', fs, myrecording)   

fs_rate, signal = read("output.wav")
l_audio = len(signal.shape)
N = signal.shape[0]
secs = N / float(fs_rate)
Ts = 1.0/fs_rate 
t = scipy.arange(0, secs, Ts) 
FFT = abs(scipy.fft(signal))
FFT_side = FFT[range(N//2)] 
freqs = scipy.fftpack.fftfreq(signal.size, t[1]-t[0])
fft_freqs = np.array(freqs)
freqs_side = freqs[range(N//2)] 
fft_freqs_side = np.array(freqs_side)

volume=np.array(abs(FFT_side))
audible=np.where(volume>5)

HighestAudibleFrequency=max(freqs_side[audible])
print(HighestAudibleFrequency)

The above code records audio for 3 seconds from the microphone and outputs the highest frequency detected in the 3 seconds. Sorry for the code format, i dont know how to make it look better

$\endgroup$

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