I am trying to make an equalizer in C++. I must process the audio in blocks of (usually) 256 samples. I use an FFT to obtain the spectrum of the sample block. I process the frequencies and then use an IFFT to obtain the processed audio block in the time-domain. I am using the code provided in the related question: FFT in a single C-file.
For a low-pass filter, setting the lower coefficients to zero should remove the low frequencies. However, in the processed audio, I get a changed spectrum, rather than a low-pass filter (the audio contains a buzzing sound).
I have read the following related articles:
Am I doing something incorrectly? Is the block size too small to obtain a reasonable frequency resolution?
I am familiar with the mathematics of the Fourier transform. However, I do not know the details of the FFT and IFFT transforms. It is possible that the provided code is not implemented correctly. However, when the FFT is done and then an IFFT on the result of the FFT, the original audio block is correctly reconstructed.
I am writing a VST and am doing all the processing in the processReplacing()
method. This is why I am constrained by the block size.
My idea is to keep last n blocks in memory and calculate the FFT on the last n blocks to obtain a higher frequency resolution, then do the processing on these frequencies, and after the IFFT, replace only the last block.
Are there any suggestions on whether this is a correct way of implementing an equalizer?
At least 3 problems:
First, the way to filter out frequencies in NOT to zero out FFT bins. See this answer for more information: https://dsp.stackexchange.com/questions/6220/why-is-it-a-bad-idea-to-filter-by-zeroing-out-fft-bins/6224#6224
Second, after you compute the length of the impulse response of your desired filter response, you have to zero-pad your FFT by at least that additional length, and then use overlap-add or overlap-save (fast convolution algorithms) to combine your IFFT results, instead of just concatenating them.
Third, 256 samples at a 44.1 kHz sample rate isn't enough to fit even 1 full period of any pitch below 170 Hz. So, yes, low frequency resolution will be limited by your chosen block size. Whether or not this is reasonable depends on your requirements for frequency response.
FFT/IFFT fast convolution is one common way to do DSP equalization if you have an equalization curve with a long impulse response, sufficient compute resource/power/cycles, and do not mind some block size related latency.