Learn Using the FFT

Getting Started

Welcome to RNBO


RNBO Basics

Key Differences

Why We Made RNBO


Audio IO

Messages to rnbo~

Using Parameters


Messages and Ports

Polyphony and Voice Control

Audio Files in RNBO

Using Buffers

Using the FFT

Export Targets

Export Targets Overview

Max External Target
Raspberry Pi Target
The Web Export Target
The C++ Source Code Target

Code Export

Working with JavaScript
Working with C++

Special Topics

Sample Accurate Patching
Scala and Custom Tuning

RNBO and Max for Live

RNBO Raspberry Pi OSCQuery Runner

Raspberry Pi Debug Interface


Raspberry Pi GPIO

Updating the RNBO Package

Using the FFT

How to use the fft~ and ifft~ objects for spectral processing in RNBO.

This article assumes you have some familiarity with spectral processing in Max, either with pfft~ or with fft~ and ifft~. RNBO’s fft~ and ifft~ objects are almost identical to the equivalent Max objects, so any patches using  fft~ in Max work directly in RNBO. While RNBO does not currently provide pfft~, it’s possible to emulate pfft~ in RNBO, as you’ll see in this article.

For more information on the fft~ and ifft~ objects in Max, see:

Built-in Windowing

Unlike Max’s fft~ and ifft~, RNBO fft~ and ifft~ feature built-in windowing functions like Hann, Hamming, and Blackman. The default in RNBO is to not use any windowing, making it easy to copy over Max patches using fft~ and ifft~ without changing behavior.

With built-in windowing, RNBO FFTs patches can be much simpler than their Max equivalents. Take a look at this Max noise reduction patch. It performs an FFT on the signal, obtaining the amplitude and phase of each frequency component. Then, it mutes any components that fall under an amplitude threshold. Notice how much of the patch deals with applying a windowing function to the input and output of the noise reduction process. 


In the equivalent RNBO patch, all of the windowing happens automatically within the fft~ and ifft~ objects.


You can reduce duplication further by using abstractions. The secret to making this work is using patcher argument syntax to dynamically pass in the window size and phase offset to fft~ and ifft~.


Now if you want to update the processing logic, you only need to change it in one place. If you want to use four overlapping FFTs instead of two, you can easily duplicate the abstraction and update the arguments. 

With this abstraction technique, the resulting patcher looks a lot more like an equivalent pfft~ patch.


Custom Window Functions

If you need to use a windowing function that isn’t built-in to the RNBO fft~, you can provide a reference to a buffer to use as a custom windowing function. The fft~ object will automatically read from the buffer and apply the contents as a windowing function for each spectral frame. In the following phase vocoder example, a buffer containing the square root of the Hann windowing function is used in the FFT and inverse FFT processing.


Example: Spectral Filtering

The classic “Forbidden Planet” example patch implements a graphical EQ using pfft~. The patch peeks into a buffer that contains amplitude values for each FFT bin and scales the spectral data accordingly.



In the following example, we recreate the Forbidden Planet patch using RNBO.



FFTs and codebox

RNBO FFTs are stateful operators which can be used in codebox~. There are two variants of FFT operators available: buffered (fftbuffer) and streaming (fftstream/ifftstream).

  • Buffered FFTs are most useful when you want to do non-realtime processing.

  • Streaming FFTs are best for realtime contexts when you don’t want to handle buffering yourself. (In fact, fftstream/ifftstream use fftbuffer under the hood.)

The following RNBO patch computes the spectral content of a buffer using fftbuffer in codebox. Note the following about using fftbuffer:

  1. The FFT is performed “in-place.” This means the buffer of data you input to fftbuffer gets replaced with the results of the calculations. In this example, we copy over the input data to a workspace buffer to preserve the original buffer.

  2. The fftbuffer operator expects a buffer of interleaved real and complex values. Since we only have real input in this example, the workspace buffer is twice the size of the input and all of the complex values are left as zero.



The following example demonstrates using the streaming FFT operators to create another spectral EQ. 



Resetting FFT processing

Each fft~/ifft~ object in your patch maintains an internal buffer of data and processing index. If you ever want to clear and synchronize all FFTs while patching in RNBO, you can do so by restarting Max’s DSP.

Materials in this article

  • RNBO FFT Patches