2
votes

I’m trying to implement a 32 point FFT - Equalizer - iFFT

On a step by step basis. I input a Time domain signal to a FFT block and then used iFFT to obtain the original data back.

Naturally after FFT, I get 32 points of symmetrical real and imaginary data.

I tried,

Step 1:

   fft_sig = fft(data_processing_block);                 %FFT of the signal

  ifft_sig = ifft(fft_sig);                            %iFFT of the signal

The output matches the input. Works like a charm.

Step 2:

  fft_sig = fft(data_processing_block);                 %FFT of the signal

  after_eq_re = real(fft_sig);
  after_eq_im = imag(fft_sig);

  after_eq = after_eq_re + (i*after_eq_im);

  ifft_sig = ifft(after_eq);                            %iFFT of the signal

This also works just fine.

Step 3:

  fft_sig = fft(data_processing_block);                 %FFT of the signal

  after_eq_re = real(fft_sig).*1.0;                     % Multiply Real data with a constant       
  after_eq_im = imag(fft_sig).*1.0;                     % Multiply Imag data with a constant 

  after_eq = after_eq_re + (i*after_eq_im);

  ifft_sig = ifft(after_eq);                            %iFFT of the signal

This also works fine.

Step 4:

I replaced the constant (1.0) with an Equalizer table. Of size 32.

Eq_data_32 =[0.0;0.1347;0.2117;0.2956;0.4146;0.5300;0.5615;0.5195;0.4391;0.3621;0.2816;0.1977;0.1837;0.1172;0.0857;0.0577;0.0;0.0577;0.0857;0.1172;0.1837;0.1977;0.2816;0.3621;0.4391;0.5195;0.5615;0.5300;0.4146;0.2956;0.2117;0.1347];

Eq_data_32(1) and Eq_data_32(17) are zeros. Eq_data_32(2:16) is symmetrical to Eq_data_32(18:32).

 re_Eq_data_32 = Eq_data_32;  % Equalizer data for real values
 im_Eq_data_32 = -(re_Eq_data_32);  % Equalizer data for imaginary values

  fft_sig = fft(data_processing_block);                 %FFT of the signal

  after_eq_re = real(fft_sig).*re_Eq_data_32';
  after_eq_im = imag(fft_sig).*im_Eq_data_32';

  after_eq = after_eq_re + (i*after_eq_im);     
  ifft_sig = ifft(after_eq);                             %iFFT of the signal

Now the output is distorted and does not sound good. I think this is due to symmetry of the Equalizer table. I can’t figure how to arrange the Equalizer table to preserve the symmetry. As far as I can tell, my real and imaginary Equalizer table are symmetric. So why can’t I get a clear output ?

Complete code:

Fs = 16000;                       % sampling frequency
no_samples = 640;                  % no of samples
Freq1 = 1000;                      % Frequency 1 of the signal
Freq2 = 2500;                      % Frequency 2 of the signal
Freq3 = 3500;                      % Frequency 3 of the signal
Amp = 0.1;
t = 1/Fs*((1:no_samples)-1);      % time duration, t = 1/Fs
Input_sig_16k = Amp*sin(2*pi*Freq1*t)+Amp*sin(2*pi*Freq2*t)+Amp*sin(2*pi*Freq3*t);  % Multitone Input Signal 

% Equlizer data
Eq_data_32 =[0.0;0.1347;0.2117;0.2956;0.4146;0.5300;0.5615;0.5195;0.4391;0.3621;0.2816;0.1977;0.1837;0.1172;0.0857;0.0577;0.0;0.0577;0.0857;0.1172;0.1837;0.1977;0.2816;0.3621;0.4391;0.5195;0.5615;0.5300;0.4146;0.2956;0.2117;0.1347];

re_Eq_data_32 = Eq_data_32;  % Equalizer data for real values
im_Eq_data_32 = -(re_Eq_data_32);

window_size = 32;

 for ii = 1:(length(Input_sig_16k)/window_size)-1

  data_range = (((ii-1)*window_size)+1:((ii-1)*window_size)+32);
  data_block = Input_sig_16k(data_range);

  fft_sig = fft(data_block);                 %FFT of the signal

  after_eq_re = real(fft_sig).*re_Eq_data_32';   % Multiply real portion of FFT with Equalizer
  after_eq_im = imag(fft_sig).*im_Eq_data_32';   % Mutliply imaginary portion with Equalizer

  after_eq = after_eq_re + (i*after_eq_im);

  ifft_sig = ifft(fft_sig);                  %iFFT of the signal

 data_full(data_range) = ifft_sig;            % Output signal

 end

plot(Input_sig_16k,'-og'), grid on;   % plot and compare both the signals
hold on;
plot(data_full,'-xr')
hold off;
1
was the original fft 32 of length?Ander Biguri
@AnderBiguri Yes. It was. The fact that the program works fine without the Equalizer or a constant value for an Equalizer points to the fact that the FFT-iFFT is not the problem, but the symmetry of the Equalizer. So I'm trying to get my head around the arrangement of the Equalizer data. Thats where the problem is. I think my Equalizer data is symmetrical, but it still doesn't work. hence my confusion and search for answers.Big Head
I think this needs a minimal reproducible exampleAnder Biguri
@AnderBiguri I added a complete code to the original post. If you alternate the following line ifft_sig = ifft(fft_sig); between the above and the following ifft_sig = ifft(after_eq); you get the effects of without and with Equalizer.Big Head
is it possible you need to fftshift the Eq_data_32?Shai

1 Answers

2
votes

Multiplication in the frequency domain is circular convolution in the time domain. Circular convolution means that the end of your multiplication filtering process wraps around and corrupts the beginning of each FFT/IFFT buffer.

Instead, zero-pad each FFT by at least the length of the impulse response of your equalization filter. Then use either overlap-add or overlap-save (fast convolution methods/algorithms) to re-combine your IFFT results.

Also, if you want a strictly real result (no non-zero imaginary numbers), make sure that the input to your IFFT is conjugate symmetric.