FFT Convolution Filter: How to do it correctly?

Hey JUCE forum! I was wondering if anyone has run into this issue with FFTs: I wanted to multiply a pointer array of floats with an FFT of my buffer (e.g. samples, also pointer array), so I thought I could multiply in the picture below and then inverse transform it back like this:

However, this is producing strange artifacts at the beginning and end of the buffer, shown here:

In this particular example, it’s a 440hz wave at 48kHz (buffer size of 512 samples), being convolved with a bandpass filter with 0 dB peak at 12kHz, shown here:

I’ve been dealing with this for a bit too long and would appreciate anybody chiming in, thank you!

I guess you might have a misconception of how FFT works.

Here is a good book which explains all the basic stuff:

http://www.dspguide.com/pdfbook.htm

Chapters 10/16/18 might be the crucial points to your question.

Ah, thank you for the help! You’re right, I did misunderstand two things:

  1. The real and imaginary parts are interleaved with each other (I forgot because I was working with complex data types earlier).
  2. According to Chapter 18 Figure 18.2, I have to filter the imaginary part as well for the IFFT to work.

I may have gotten some other parts wrong, so please correct me before I go down the wrong path!
It’ll also help if I give a bit more context:

I want to make a freeform filter graph, where the user can draw in their filter kernel like this:
fft 4
(I’m making a vocal synthesizer, so I want custom, complex formant shapes)

This graph I put in a vector* of floats which I wanted to filter the input signal with. I originally thought I could just multiply the FFT of the input signal with the filter kernel, then IFFT out, but the real and imaginary parts now imply I can’t just do that.

Because I’m already in the frequency domain with the filter kernel, I can’t just do FFT on it to get the corresponding imaginary part. I’m not sure if I can even calculate the imaginary filter kernel either, but here’s what I think the solution may be:

  1. Convert the rectangular coordinates of the filter kernel to polar coordinates, so r (amplitude) = sqrt(x^2 + y^2), and θ (angle) = atan(y/x)?
  2. Multiply the real part of the FFT input signal with r (amplitude), and multiply the imaginary part of the FFT input signal with θ (angle)?
  3. IFFT the input signal back into the time domain.

However, doing this in code results in the same pop in the beginning and back of the buffer, so while I think this is more correct, I’m not sure what these extremities are the result of:
fft 5

Would you happen to know of any JUCE tutorials that apply filter graphs to input signals? Thank you again for taking the time to point me to some resources!