My question is related to the explanation here by A. Levy: Analyze audio using Fast Fourier Transform
How can I produce a bandpass filter on these complex numbers...
[-636.00000000 +0.00000000e+00j -47.84161618 -2.80509841e+02j
30.69754505 -1.30624718e+01j -109.94022791 +7.58155488e+00j
-3.18538186 +1.44880882e+01j -120.36687555 +5.45225425e+00j
50.48671763 +1.69504204e+01j 31.56751791 -7.22728042e+01j
-17.96079093 -3.17853727e+01j -19.25527276 +5.08151876e+00j
18.38143611 -2.60879726e+01j -27.15617871 -4.39789289e+01j...
... knowing already that I will then convert my complex array back into the time domain using ifft. My band pass should only allow 18500Hz to 19500Hz through (super-sonic, I know. I'm specifically looking for those tones to arrive from a tone generator across the room). My sampling rate it 44100Hz and the number of points in my FFT is 128.
I will then be using the frequency detection code here (which already works on my non-filterd samples) Python frequency detection in order to give me the pitch of the audio tone when it arrives. If there is no tone played at 19000HZ (for example), then the output of the pitch detection function should return 0.
My current filter code (which is not giving me the correct result):
samp = [-10 -16 -15 -11 -8 -10 -9 -12 -7 -13 -4 -10
-1 -4 -11 -6 -8 -8 -10 -6 -9 -7 -16 -11 5 -14
-9 -3 -9 -7 -7 -6 -3 -11 -13 -9 -10 -4 -6 -7
-11 -15 -15 -3 -5 -15 -11 -8 -13 -9 -12 -10 -8 -16
-13 -5 -4 -12 -14 -8 -14 -6 -7 -7 -4 -6 -9 -4 -4
-4 1 -10 -3 -9 -9 -1 -5 -2 -5 -3 -3 2 -3 2
-5 -4 -6 1 -2 -6 -8 -3 -10 -11 -6 -2 -5 -3
0 3 0 1 1 -1 -3 -3 1 3 -3 -3 3 -3 -1
-3 -1 2 1 0 -8 0 6 -3 -4 -7 -5 -10 -4 -4]
sample_time = 0.000022675 # 1/44100
low_cut = 18500
high_cut = 19500
float_samp = np.float32(samp)
fft_spectrum = np.fft.fft(float_samp)
freqs = np.fft.fftfreq(len(fft_spectrum), d=sample_time)
### wrong approach ###
for i in range(len(freqs)): # (H-red)
if abs(freqs[i]) >= high or abs(freqs[i]) <= low:
fft_spectrum[i] = 0.0
### -------------- ###
time_domain = np.fft.ifft(fft_spectrum)
converted = np.int16(time_domain)
It's currently only returning values between 18500Hz and 19500Hz after pitch detection, whether or not the tone is present. I believe this is the case because I'm knocking out all the information from my fft_spectrum list except those within with my filter values. Even though the tone is not there, the only information left is the within that band, so that's what the pitch detector is reading. This is my assumption.
Please Note: I can not use Scipy as I'm deploying this on Android and that library is not available on that platform. I'm hoping there is a way to do this through Numpy.