Two routes to one convolution, in a race. Watch the solid FFT curve pass the dashed direct one as the length grows.
When the FFT route wins
Two signals, each N samples long. Real multiplies for their convolution.
Two 4-sample signals: 16 multiplies by hand, 176 by FFT. Short signals: go direct.
Describe this picture
Real multiplies for the convolution of two signals, each samples long, on log axes: the dashed curve is the direct route, , and the solid one the FFT route. The readouts are , which route is cheaper, and the multiplies by each route. The clip sweeps from 4 to 4096. At the start the caption says “Two 4-sample signals: 16 multiplies by hand, 176 by FFT. Short signals: go direct.” At it says “From N = 173 on, the FFT route is always cheaper. (It already wins from 116 to 128, then loses again when the FFT size jumps to 512.)”, and the readouts show 65 536 multiplies directly and 29 696 by FFT. At the end it says “N = 4096: 16.8 million multiplies directly, 671 744 by FFT, 25 times fewer.” After the sweep, dragging along the plot or the arrow keys choose : the arrows step by 1, Page Up and Page Down double or halve it, and Home and End jump to the ends. At 128 the caption says “N = 128: the FFT route wins, 13 312 against 16 384.” At 129 it says “N = 129: 2N − 1 = 257 needs an FFT of 512, and direct wins again.”
Convolution through the FFT
On the page Circular vs linear convolution (13.4) you saw that multiplying two DFTs convolves the two sequences circularly, and that padding both with zeros turns the circle into a line. This page asks a practical question: when is that route faster than flip and slide, and how do you use it on a signal that never ends?
Here is the recipe. Let have samples and have . The linear convolution has samples (see Discrete convolution, 5.2). Choose the FFT size : the smallest power of two that is at least . Then do five things.
- Zero-pad and to samples.
- Take the FFT of each.
- Multiply the two spectra, bin by bin.
- Take the inverse FFT of the product.
- Keep the first samples.
I call this FFT convolution. In symbols, with both inputs already padded:
Nothing about it is approximate. It gives the same samples as flip and slide, up to rounding in the arithmetic.
When the FFT route wins
To compare the two routes I count real multiplies, because an FFT works on complex numbers and a complex multiply costs 4 real ones, as on the page Complex numbers for signals (3.3). I use no tricks for real inputs. The two-for-one trick of More FFT algorithms (14.2) would roughly halve the FFT part, and I leave it out so the count stays simple.
Take two signals of the same length . Flip and slide multiplies every sample of one by every sample of the other: real multiplies. The FFT route needs three FFTs (two forward, one inverse) of size , and complex products. From The FFT (14.1), one FFT costs complex multiplies. So
The FFT route is like a motorway: slower to get onto, faster for a long trip. For short signals the fixed cost of three FFTs is more than the you were trying to avoid. For long signals grows much faster than .
The race at the top of this page runs the formula. At its start, two 4-sample signals, the FFT size is 8, and multiplies against 16 by hand. At it is 65 536 multiplies directly and 29 696 by FFT. At it is 16.8 million against 671 744, 25 times fewer.
The FFT curve is a staircase, not a smooth line. The size has to be a power of two, so it jumps each time passes one. The jump is why the crossover is not a single point. Here are the numbers around it.
| direct | FFT route | cheaper | ||
|---|---|---|---|---|
| 64 | 4096 | 5888 | 128 | direct |
| 116 | 13 456 | 13 312 | 256 | FFT route |
| 128 | 16 384 | 13 312 | 256 | FFT route |
| 129 | 16 641 | 29 696 | 512 | direct |
| 172 | 29 584 | 29 696 | 512 | direct |
| 173 | 29 929 | 29 696 | 512 | FFT route |
| 1024 | 1 048 576 | 143 360 | 2048 | FFT route, 7.3 times fewer |
From to the FFT route wins, because is already enough. At the length needs 512, the cost more than doubles (13 312 to 29 696), and direct wins again until . From 173 onward the FFT route is cheaper at every length up to 4096.
After the sweep you can choose yourself in that picture. Try 128, then 129, and watch the cheaper trace swap twice.
Overlap-add: a signal that never stops
A microphone never stops, so you cannot wait for the whole signal before you start. Instead, cut into blocks of samples each. Convolution is linear, so by the superposition of The impulse response (5.1) the output is the sum of what each block produces alone.
Each block’s output is samples long. That is more than the block, so the end of each output, its tail, spills into the time of the next block. The fix is to place each block’s output at the block’s own start and to add wherever tails overlap. This is overlap-add. Think of tiling a floor with tiles that overlap at the edges: the overlapped strips get painted twice, and you add the two coats.
Watch the two hatched zones, where one block’s tail lands on the start of the next: only there do two outputs add.
Overlap-add, three blocks
x has 24 samples, h = 1, 1, 1. Blocks of 8, each convolved with an FFT of 16.
A long input, cut into blocks of 8 samples.
Describe this picture
Overlap-add with three blocks: has 24 samples, , and blocks of 8 are each convolved with an FFT of 16. The input panel shades block 1, block 2 and block 3. The output panel draws each block’s output as open circles, labelled “block 1 output” and so on; the two overlap zones are hatched and labelled “tails add”, and the final sum is drawn as filled dots labelled “sum = x * h”. The readouts are the block and the samples finished; there is no control. Each caption appears once the picture it describes is complete and stays until the next. The first says “A long input, cut into blocks of 8 samples.” Once block 1 is drawn: “Block 1 convolved with h gives 10 samples, n = 0 to 9. The last 2 spill into block 2’s time.” Then: “Block 2’s output starts at n = 8, on top of block 1’s tail: at n = 8 and 9 the two add, 2 + 0 = 2 and 1 + 2 = 3.” At the end: “Added up: 26 samples, exactly the direct convolution x * h. Each block needed only a 16-point FFT, however long x is.”
The input has three blocks of 8: 2, 1, 3, 0, −1, 2, 1, 1; then 0, 2, −2, 1, 3, 1, 0, −1; then 1, 1, 2, 0, −1, 0, 2, 1. The filter is . Each block of 8 convolved with gives samples, so a 16-point FFT is enough.
The block outputs, each computed with a 16-point FFT, are:
- block 1, at to 9: ;
- block 2, at to 17: ;
- block 3, at to 25: .
Block 2 starts at , on top of block 1’s tail: at and 9 the two add, and . At and the tails of block 2 meet the start of block 3: and . Only those four samples are sums; every other sample belongs to one block alone.
Added up, the 26 samples of are 2, 3, 6, 4, 2, 1, 2, 4, 2, 3, 0, 1, 2, 5, 4, 0, 0, 1, 4, 3, 1, −1, 1, 3, 3, 1, and they equal the output of flip and slide sample for sample. Each block needed only a 16-point FFT, however long is.
Overlap-save: keep what did not wrap
There is a second way to cut a signal, and it works the other way round. Let the FFT wrap, then throw away what wrapped. This is overlap-save.
Take overlapping segments of input samples. Each segment starts samples after the last one, so it repeats the end of the one before. Convolve each segment with circularly, as on page 13.4. The circular convolution wraps the tail of the segment back onto its first outputs, so those are wrong. The remaining outputs have nothing wrapped onto them and are correct. Keep those and drop the rest.
The figure uses the same and as before. The segment holds two zeros of history, then to . Of the eight circular outputs, the first two () are wrapped. The other six equal to . Each segment yields good samples, so the next one starts 6 samples later. The two methods differ in where the repeated work sits: overlap-add overlaps the outputs and adds, overlap-save overlaps the inputs and discards.
Bigger blocks: cheaper, but later
Overlap-add leaves one choice: the block length . To see what it costs, take a real job, a reverb. The echo of a room is its impulse response, as on page 5.1. Record it once, and any dry sound can be placed in that room by convolution with it.
A hall with a 1-second echo, sampled at Hz, has taps. Directly, that is 16 000 multiplies for every output sample. With overlap-add each block costs two FFTs (the FFT of is done once and kept) and products, where is the first power of two at least . Spread over the outputs of the block, the cost per output sample is
There is a price. The first output of a block can only appear after the whole block has arrived, so every output is late by about . This waiting time is the latency. It is like a bus that waits to fill: cheaper per passenger, later to leave.
Watch the cost fall as the blocks double, while the delay doubles with them, until past 16 384 the cost climbs again.
Bigger blocks: cheaper, but later
A 1-second room, 16 000 taps at 16 kHz, run by overlap-add.
Blocks of 64: only 4 ms of delay, but 15 360 multiplies per output, about as many as direct.
Describe this picture
A 1-second room, 16 000 taps at 16 kHz, run by overlap-add. The axes are the block length in samples and the real multiplies per output sample. A dashed line at 16 000 is labelled “direct”, and dots joined by a thin line are labelled “overlap-add”. The readouts are the block , the delay, the multiplies per output and how many times fewer than direct. The clip doubles the block length from 64 to 65 536. At the start the caption says “Blocks of 64: only 4 ms of delay, but 15 360 multiplies per output, about as many as direct.” (readouts 64, 4.0 ms, 15 360, 1.0×). At 512: “Blocks of 512: the FFT size jumps to 32 768, so the cost goes up a little, to 4096.” At 16 384: “Blocks of 16 384: 128 multiplies per output, 125 times fewer than direct. But each block waits 1024 ms to fill.” (readouts 16 384, 1024.0 ms, 128.0, 125.0×). At the end: “Past 16 384 the FFT grows faster than the block, and the cost climbs again (144 at 65 536). The choice is delay against cost.” (readouts 65 536, 4096.0 ms, 144.0, 111.1×). After the sweep, dragging along the plot or the arrow keys choose the block length, one doubling per press, and Home and End jump to the ends. A “Hear the room” button plays the sound described below.
Blocks of 64 give only 4 ms of delay, but 15 360 multiplies per output, about as many as direct. At 512 the cost rises a little, from 3840 to 4096, because the FFT jumps to 32 768.
Blocks of 16 384 cost 128 multiplies per output, 125 times fewer than direct, but each block waits 1024 ms to fill. This is the cheapest block length of the sweep.
Past that point the FFT grows faster than the block, and the cost climbs again: 144 at 65 536. The choice is delay against cost. The whole table, from the same formula:
| delay | multiplies per output | times fewer | ||
|---|---|---|---|---|
| 64 | 16 384 | 4.0 ms | 15 360 | 1.0 |
| 256 | 16 384 | 16.0 ms | 3840 | 4.2 |
| 512 | 32 768 | 32.0 ms | 4096 | 3.9 |
| 1024 | 32 768 | 64.0 ms | 2048 | 7.8 |
| 4096 | 32 768 | 256.0 ms | 512 | 31.3 |
| 16 384 | 32 768 | 1024.0 ms | 128 | 125.0 |
| 32 768 | 65 536 | 2048.0 ms | 136 | 117.6 |
| 65 536 | 131 072 | 4096.0 ms | 144 | 111.1 |
Press “Hear the room” in the picture. It plays a 0.3 s dry pluck, a 440 Hz tone with a 60 ms decay, and then the same pluck convolved with a synthetic 1 s room. The room is seeded white noise times , which has decayed to dB at 0.8 s. The output is the same for every block length. It sounds the same; only the wait changes.
Real-time reverbs split into pieces too. This is partitioned convolution: small blocks for the start of give low delay, and big blocks for its tail give low cost.
The maths behind it · circulant matrices
Convolution with is multiplication by a Toeplitz matrix. Padded to a circle it becomes circulant, and the DFT diagonalises every circulant matrix, as on The DFT as a matrix (13.5). Fast convolution is “change basis, scale each coordinate, change back”.
The maths behind it · cross-correlation
The same trick computes a correlation, which is convolution with one signal reversed. That is the basis of fast cross-correlation for time-delay estimation (25.x).
Worked example
Use the reverb above with . The first power of two at least is . The cost per output is real multiplies, against 16 000 directly: 7.8 times fewer. The delay is s, which is 64 ms.
Is that a good choice? If 64 ms of delay is acceptable, 7.8 times fewer multiplies is a good return. If you need under 10 ms, blocks of 64 give 4.0 ms but save nothing. That tension is why real systems partition .
Where you’ll meet this
Long FIR filters are applied by FFT in this way, as on the pages of Chapter 19. The short-time Fourier transform of Chapter 15 also cuts a signal into overlapping frames (15.5 and 15.6). Multirate filter banks use the same blocking (Chapter 22).
Reference card
| Quantity | Formula | Notes |
|---|---|---|
| FFT convolution | both zero-padded to | |
| FFT size | next power of two | |
| Cost, equal lengths | direct ; FFT real | FFT wins for 116 to 128, then for good from |
| Overlap-add | blocks of ; outputs long; add the overlap | tails add |
| Overlap-save | segments of , step ; drop the first outputs | wrapped part dropped |
| Cost per output, overlap-add | ‘s FFT done once | |
| Delay | bigger blocks, cheaper, later |