# FFT and convolution

**URL:** <https://forum.juce.com/t/fft-and-convolution/21220>\
**Category:** General JUCE discussion\
**Created:** [March 4, 2017, 7:27pm UTC](https://forum.juce.com/t/fft-and-convolution/21220 "2017-03-04T19:27:45Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![mUmbler](https://avatars.discourse-cdn.com/v4/letter/m/b19c9b/32.png) [@mUmbler](https://forum.juce.com/u/mUmbler)\
**Post date:** [March 4, 2017, 7:27pm UTC](https://forum.juce.com/t/fft-and-convolution/21220/1 "2017-03-04T19:27:45Z")

</div>

I am attempting to make a plugin that applies an impulse response to an incoming signal. A few questions have arisen.

1. I initialize all of the FFTs outside of the processBlock method. Is the FFT module fast enough to perform a realOnlyForwardTransformation inside of the processBlock method?

2. Once I have obtained the two transformations, can I just loop through them and multiply all the elements? Or do I have to do a conversion to Complex and then work with those?

3. Must I perform an inverse transformation on the result of the multiplication?

Thanks!

---

<div class="post-metadata">

**Author:** ![mayae](https://avatars.discourse-cdn.com/v4/letter/m/9fc29f/32.png) [@mayae](https://forum.juce.com/u/mayae)\
**Post date:** [March 4, 2017, 9:02pm UTC](https://forum.juce.com/t/fft-and-convolution/21220/2 "2017-03-04T21:02:37Z")

</div>

[quote=“mUmbler, post:1, topic:21220”]

1. I initialize all of the FFTs outside of the processBlock method. Is the FFT module fast enough to perform a realOnlyForwardTransformation inside of the processBlock method?  
[/quote]Yes, depending on the length of your impulse, of course.

[quote=“mUmbler, post:1, topic:21220”]  
2) Once I have obtained the two transformations, can I just loop through them and multiply all the elements? Or do I have to do a conversion to Complex and then work with those?  
[/quote]They are complex numbers, you need to perform complex multiplication

[quote=“mUmbler, post:1, topic:21220”]  
3) Must I perform an inverse transformation on the result of the multiplication?  
[/quote]Yes, and remember your transform size will be impulse length + block length. So you need to zero pad your transforms to that size.

---

<div class="post-metadata">

**Author:** ![alatar](https://avatars.discourse-cdn.com/v4/letter/a/34f0e0/32.png) [@alatar](https://forum.juce.com/u/alatar)\
**Post date:** [March 4, 2017, 9:53pm UTC](https://forum.juce.com/t/fft-and-convolution/21220/3 "2017-03-04T21:53:15Z")

</div>

I am currently looking into doing the same.

I can recommend the following PHD thesis, which seems to give quite a good overview of the possible algorithms:

> **[466561.pdf](https://publications.rwth-aachen.de/record/466561/files/466561.pdf?subformat=pdfa)**
>
> 4.75 MB

Also note that forum member “HiFi-LoFi” has made an OpenSource Convolution plugin. See this thread:

> [@KlangFalter: Yet another convolution plugin](https://forum.juce.com/t/klangfalter-yet-another-convolution-plugin/9812):
>
> Hi everybody, I’m quite new to the forum, in fact, this is my first post here. Nevertheless, I already follow the posts already quite some time, and I’ve used the great JUCE framework for some of my hobby projects. One of them is KlangFalter, which is a free (GPL) audio convolution plugin, which I wrote because I couldn’t find any free Audio Unit convolution plugin, and because I was curious about writing any audio plugin: [https://github.com/HiFi-LoFi/KlangFalter](https://github.com/HiFi-LoFi/KlangFalter) It’s not perfect, …

It is GPL though, unfortunately. Therefore I cannot use it.

---

<div class="post-metadata">

**Author:** ![yairadix](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/yairadix/32/1114_2.png) [@yairadix](https://forum.juce.com/u/yairadix)\
**Post date:** [March 5, 2017, 9:06am UTC](https://forum.juce.com/t/fft-and-convolution/21220/4 "2017-03-05T09:06:24Z")

</div>

> [@mUmbler](#):
>
> realOnlyForwardTransformation

Because you’re using the real-transorm, might be worth to mention that JUCE’s implementation is at least two times slower than other FFT libraries’ implementations of it, as [it simply converts the reals to complex numbers](https://github.com/julianstorer/JUCE/blob/master/modules/juce_audio_basics/effects/juce_FFT.cpp#L271) and performs the full complex-fft.

---

<div class="post-metadata">

**Author:** ![alatar](https://avatars.discourse-cdn.com/v4/letter/a/34f0e0/32.png) [@alatar](https://forum.juce.com/u/alatar)\
**Post date:** [March 5, 2017, 10:19am UTC](https://forum.juce.com/t/fft-and-convolution/21220/5 "2017-03-05T10:19:59Z")

</div>

I want to add:

I just fond out there is an open source convolution engine, which is not GPL. In other words, you can use it freely even in commercial plugins. Its part of WDL from Cockos:  
[http://www.cockos.com/wdl/](http://www.cockos.com/wdl/)

Other Jucers seeem to be using it successfully. See also the following thread:

> [@Any free, real-time convolution reverb libraries out there?](https://forum.juce.com/t/any-free-real-time-convolution-reverb-libraries-out-there/18483):
>
> Hello JUCErs, What do you use for convolution reverb in your plugins? In-house built reverb(s) or something open-source? Do you know of any free, real-time convolution reverb libraries out there? Any help is much appreciated! Cheers!

---

<div class="post-metadata">

**Author:** ![mUmbler](https://avatars.discourse-cdn.com/v4/letter/m/b19c9b/32.png) [@mUmbler](https://forum.juce.com/u/mUmbler)\
**Post date:** [March 6, 2017, 11:14pm UTC](https://forum.juce.com/t/fft-and-convolution/21220/6 "2017-03-06T23:14:38Z")

</div>

@mayae  
Thank you very much! I am in the process of applying your suggestions.

@Alatar  
Thank you for the paper. I don’t think Klang will help, this is for my senior project so I wish to figure this out for myself. I might have to check that out if I cannot figure out how to efficiently use the built in FFT module.

@yairadix  
I was thinking of maybe using FFTW, which I may have to resort to using.

---

<div class="post-metadata">

**Author:** ![mUmbler](https://avatars.discourse-cdn.com/v4/letter/m/b19c9b/32.png) [@mUmbler](https://forum.juce.com/u/mUmbler)\
**Post date:** [March 6, 2017, 11:27pm UTC](https://forum.juce.com/t/fft-and-convolution/21220/7 "2017-03-06T23:27:30Z")

</div>

@mayae

Quick question: When you say I must zero pad the transformations, do you mean that I must zero pad the results of the transformations before I do the complex multiplication and inverse transformation, or that I must zero pad the arrays that I pass into the transformations?

---

<div class="post-metadata">

**Author:** ![mayae](https://avatars.discourse-cdn.com/v4/letter/m/9fc29f/32.png) [@mayae](https://forum.juce.com/u/mayae)\
**Post date:** [March 7, 2017, 11:27am UTC](https://forum.juce.com/t/fft-and-convolution/21220/8 "2017-03-07T11:27:29Z")

</div>

Say your impulse response is 1000 samples long (K), and your block size is 1000 (M). The result of the convolution is an array of size N=K+M-1 = 1999 samples, ie. your must zero-pad your input signals to size N, otherwise you will have circular convolution.

In this case, you would probably round N to the next power of two for FFT effeciency (N = 2048).

---

<div class="post-metadata">

**Author:** ![mUmbler](https://avatars.discourse-cdn.com/v4/letter/m/b19c9b/32.png) [@mUmbler](https://forum.juce.com/u/mUmbler)\
**Post date:** [March 9, 2017, 6:18am UTC](https://forum.juce.com/t/fft-and-convolution/21220/9 "2017-03-09T06:18:40Z")

</div>

Would I have to zero pad the impulse response to N as well?

Also, I thought the sample buffer must be double the length for the FFT. So should it be 2\*N?

One final question: should the individual FFTs be initialized to log2(N), or log2 of their respective sizes?

---

<div class="post-metadata">

**Author:** ![mayae](https://avatars.discourse-cdn.com/v4/letter/m/9fc29f/32.png) [@mayae](https://forum.juce.com/u/mayae)\
**Post date:** [March 12, 2017, 4:15pm UTC](https://forum.juce.com/t/fft-and-convolution/21220/10 "2017-03-12T16:15:24Z")

</div>

[quote=“mUmbler, post:9, topic:21220”]  
Would I have to zero pad the impulse response to N as well?  
[/quote]Yes.

[quote=“mUmbler, post:9, topic:21220”]  
Also, I thought the sample buffer must be double the length for the FFT. So should it be 2_N?  
[/quote]The sample buffer should be N complex numbers (which requires 2_N normal floats, but it is really easier to think of in terms of complex entities).

[quote=“mUmbler, post:9, topic:21220”]  
One final question: should the individual FFTs be initialized to log2(N), or log2 of their respective sizes?  
[/quote]All of your operations in the frequency domain require transforms of equal size (N). It doesn’t make sense to perform convolution on differently-sized transforms… The complex sinusoids don’t match up.

---

<div class="post-metadata">

**Author:** ![hifi-lofi](https://avatars.discourse-cdn.com/v4/letter/h/5daacb/32.png) [@hifi-lofi](https://forum.juce.com/u/hifi-lofi)\
**Post date:** [March 31, 2017, 11:01pm UTC](https://forum.juce.com/t/fft-and-convolution/21220/11 "2017-03-31T23:01:01Z")

</div>

Hi,

I just changed the license of FFTConvolver from GPL to MIT, so it should be working now for you as far as licensing is concerned.

> **[HiFi-LoFi/FFTConvolver](https://github.com/HiFi-LoFi/FFTConvolver)**
>
> FFTConvolver - Audio convolution algorithm in C++ for real time audio processing

Regards, Uli
