I’m trying to quickly implement convolution to test a filter design I’ve made. Here’s my excerpt of code that would hypothetically perform a convolution (notes: I’d of course pre-allocate my FFTs in a non testbed setting, and in this test case windowedFilter is already in the frequency domain and guaranteed to match the buffer in doubled size):
The result of this is… nothing. The input buffer is passed out of this method exactly as it came in.
I tried changing the line within the inner for loop to be ‘bufferArray[n] *= 0’ just to see if it’d do anything- but no, the same result (input = output) occurs.
I figure there’s not an override for * in the Complex class that FFT uses. Is there any way that I can go about multiplying two buffers that were processed with FFT’s performRealOnlyForwardTransform, or no? If not, what other libraries out there might work well for my purpose (performing convolution efficiently)?
The problem is that setSize may delete your content. You should be using buffer.setSize (buffer.getNumChannels(), buffer.getNumSamples()/2, true). See the documentation here for more details.
As I said before, nothing seems to happen here, though I did confirm it reaches and runs through the inner-most for loop. setting windowedFilter to all zeros (and thusly windowArray and windowComplexArray) hypothetically should result in silence, but it does nothing (buffer before method=buffer after method).
Instead of using FFT::Complex, replacing the innermost for loop with one that just goes through all of bufferArray and replaces it with zeros also does… nothing.
It gets weirder… if I stick buffer.clear(); as the first line within this processFilter method I do get silence (as expected), but if I stick buffer.clear(); as the last line, after everything, it does nothing. Wtf?
Can you tell me what values does your windowArray has? I’m trying to multiply the values of the FFT (an then do the IFFT) but i am only able to multiply it by a constant. For example, if I want to multiply bin 10 by 0.4 and all the others by 0.3 I get no sound as a result.
Well, that’s because you can’t do filtering this way…
Convolution in spectral domain has the same constraints as in time domain. If you convolve a signal of M samples with another of N samples, you get a result of M + N samples.
When you do an FFT of M samples of you signal and then apply something different than a multiplication, you are actually doing the same as convolving in time domain a signal of N samples with an infinite impulse. But as you do that only on M samples, you end up with aliasing the infinite impulse to N samples.
And then everything does bad.
That’s why we have FIR design functions like Remez, because you can’t design a perfect filter in spectral domain and just multiply your FFT result with it (even in FFT convolution, you use zero-padding).
Yet something else I have to put in my book on audio digital signal processing because this is fundamental in the way you do filter design.