For a piece of software I've been working on lately I need to implement FFT convolution for performance reasons.
Doing so has been mildly succesfull but there is still a error somewhere causing lots of small spikes to show up on the waveform. Also when looking at the spectrum of the signal, lots of distortion can be seen which is filtered out mostly at 15 KHz.
What I do in the filter is the following with overlap - add:
- Create the filter kernel of 101 points and FFT it
- Create a buffer holding 200 samples of audio
- When there are 200 samples ready, FFT the signal and multiply with the filter kernel FFT.
- IFFT the filtered signal again
- Add last 100 samples from the previous run to the first 100 samples of the current output
- Save the last 100 samples for the next run.
The small spikes and distortion when looking at the spectrum seems to come from a missing sample somewhere, but I can't track down exactly where it happens.
The following code is what I use to do the filtering:
function TFFTAnalyzer.doAnalyzer(Sample: Single) : Single; var I: Integer; Temp : Single; begin Result := X[BufferPos]; X[BufferPos] := Sample; BufferPos := BufferPos + 1; if BufferPos > 200 then BufferPos := 1; if BufferPos = 200 then begin //Add 100 zeros for I := 0 to 512 do begin if I > 200 then X[I] := 0; end; //Calculate the FFT of the sample buffer FFT_transform(1024, X); I := 0; while I <= 1024 do begin Temp := X[I] * FilterX[I] - X[I + 1] * FilterX[I + 1]; X[I + 1] := X[I] * FilterX[I + 1] + X[I + 1] * FilterX[I]; // imaginary part X[I] := Temp; // real part I := I + 2; end; //Inverse FFT the signal FFT_inverse(1024, X); //Overlap the first 100 samples for I := 0 to 100 do begin X[I] := (X[I] + Overlap[I]);// / 2; end; //Save last 100 samples for next overlap for I := 200 to 300 do begin Overlap[I - 200] := X[I]; end; end; end;
This is the picture showing the problem with the spikes and distortion.