0
$\begingroup$

I am trying to use Fast Fourier Transform (FFT) for decomposing an audio signal into 8 sub-bands according to this link but the problem is the frequency response of the result contains only the first sub-band of the signal. Here is my code in Jupyter Notebook:

%matplotlib notebook

from scipy.io import wavfile      # For reading the wavefile into a numpy array
from scipy import signal as st    # Signal Processing toolbox, used for filter design
import matplotlib.pyplot as plt   # Used for genearating the plots
import numpy as np                # Standard vectorized programming library
import scipy.fftpack              # Calculating the FFT
from IPython.display import Audio # Playing audios

fs, data_ = wavfile.read('Track32.wav')
data_ = data_[:,0] # Select the dara of the first channel
print('Sampling frequency of th read .wav file is: {}.'.format(fs))

# Find the next power of two for zero padding
next_pow2 = int(np.ceil(np.log2(len(data_))))

data = np.zeros(2**next_pow2)
data[(2**next_pow2 - len(data_))//2 : (2**next_pow2 + len(data_))//2] = data_

data_16 = np.reshape(data,(len(data)//16,16))
data_subbands = scipy.fftpack.fft(data_16)
data_f = scipy.fftpack.fft(data_subbands,axis=0)

xf = np.linspace(0,fs/2,data_f.shape[0]//2)
fig,ax = plt.subplots()

bands = ['0 - 2 KHz','2 - 4 KHz','4 - 6 KHz','6 - 8 KHz',
        '8 - 10 KHz','10 - 12 KHz','12 - 14 KHz','14 - 16 KHz']

for pli in range(np.shape(data_f)[1]):
    ax.plot(xf,(2/data_f.shape[0])*abs(data_f[:data_f.shape[0]//2,pli]))

ax.set_title('Frequency Response of the Filtered Signal')
ax.set_ylabel('|Y(f)| [dB]')
ax.set_xlabel('Frequency[Hz]')
ax.legend()
plt.show()

Using the general method for filter banks, I came to this conclusion: Result using general filter bank method(expected)

But after using this code above, I came to this figure: Result using FFT method

Is this the right way to use FFT for implementing a filter bank?

$\endgroup$
  • $\begingroup$ What is your sample rate and what is the frequency and bandwidth for each of the filter banks? What kind of performance do you need for each of the filters in terms of their response? An straight DFT is a filter bank where each bin is a Sinc filter with an equivalent noise bandwidth of one bin; is that sufficient? (In which case you can simply do a sliding DFT with a low number of bins according the the frequency bandwidth desired for each bin, optionally consider an alternate approach using half-band filters, especially if you want a logarithmic progression of filter bandwidth $\endgroup$ – Dan Boschen Jun 28 at 23:22
  • $\begingroup$ @DanBoschen My sampling frequency is 32000 Hz and the bandwidth of each sub-band is 2000 Hz. Each filter must have a high attenuation in its stopband. I am using such a filter bank in order to reconstruct the signal perfectly after down-sampling. As I am trying to reproduce the technique mentioned in this link, I can only use constant bandwidths. $\endgroup$ – reza Jun 29 at 12:29
  • $\begingroup$ You mentioned a link but did not include it.... $\endgroup$ – Dan Boschen Jun 30 at 1:34
  • $\begingroup$ @DanBoschen bit.ly/3iaZexx $\endgroup$ – reza Jun 30 at 5:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.