DSP - Filter Frequency Using DFT

I am trying to implement an 8-band equalizer based on DFT for the sole purpose of training. To prove that my DFT implementation was working, I applied an audio signal, analyzed it and then re-mounted it without any changes in the frequency spectrum. So far so good.

I use the so-called "standard DFT calculation method", which is a correlation. This method calculates the real and imaginary parts as N / 2 + 1 samples in length. To reduce the frequency I'm just doing:

float atnFactor = 0.6; Re[k] *= atnFactor; Im[k] *= atnFactor; 

where "k" is an index in the range from 0 to N / 2, but what I get after resynthesis is a slightly distorted signal, especially at low frequencies.

The sampling rate of the input signal is 44.1 kHz, and since I just want an 8-band equalizer, I feed the DFT 16 samples at a time, so I have 8 frequency bins for playback.

Can someone show me what I'm doing wrong? I tried to find information on this subject on the Internet, but could not find.

Thanks in advance.

+4
source share
1 answer

DFT and FFT are essentially the same for the purposes of this issue.

To reduce the frequency bit (or β€œband”) in the FFT-converted array, you need to multiply both the real and imaginary components by the same coefficient, as well as multiply the real and imaginary components of the corresponding negative frequency buffer, FFT creates a converted pair of arrays where the first half of the values ​​are components with a positive frequency, and the second half are negative frequency components.

Here is a simplified code example for a low-pass filter that explains what I mean:

 // fftsize = size of fft window int halfFFTsize = fftsize / 2; float lowpassFreq1 = 1000.0; float lowpassFreq2 = 2000.0; for (int i = 0; i < halfFFTsize; i++) { int ineg = fftsize - 1 - i; // index of neg. freq. float freq = (float)i * (44100.0F / (float)halfFFTsize); if (freq >= lowpassFreq2) { real[i] = 0; imag[i] = 0; real[ineg] = 0; imag[ineg] = 0; } else if (freq >= lowpassFreq1) { float mult = 1.0 - ((freq - lowpassFreq1) / (lowpassFreq2 - lowpassFreq1)); real[i] *= mult; imag[i] *= mult; real[ineg] *= mult; imag[ineg] *= mult; } } 

Update: after reading your edit, I have to say that your code is working properly. I suggested that you get a heavily distorted, synthesized signal, and not a "slightly distorted signal, especially at low frequencies."

I think the distortion you see is the result of the very small size of the window you are using - this is especially important if you are not using the Hanning window approach to restore the original signal.

Try running your code with a more typical window size (for example, 1024). The 8-band equalizer usually does not use the 8-bit FFT window. Typically, the settings of 8 sliders will be used to calculate the curve of a function connecting 8 points in the frequency domain, and this function will then be used to set the bin amplitudes for a much larger, finer-grained set of frequencies.

Another point: the frequency cells evenly distribute the available range, so no matter how large your window is, more than half of them fill frequencies that are not audible to the human ear. Therefore, bands covered with an equalizer are usually scaled logarithmically (e.g., 100 Hz, 1 kHz and 10 kHz for a typical 3-band equalizer) and therefore do not apply to an equal number of frequency bins.

In the case of a window with 8 cells with a uniform interval, attenuation of 5 out of 8 undoubtedly has no audible effect, except for distortion of the audible frequencies.

+5
source

Source: https://habr.com/ru/post/1310405/


All Articles