Offt
INSTRUMENT design -- Fast Fourier Transform (FFT) object
Offt is a utility object that encapsulates several
Fast Fourier Transform (FFT) operations for use by RTcmix instruments.
These include the allocation of a buffer for the transformation
of samples as well as functions to perform a forward- (real-to-complex)
or backward- (complex-to-real; inverse) transform on the data in
the buffer.
Using the Offt object requires a little basic knowledge
of how the Fast Fourier Transform operates. Julius O. Smith has
a
good math tutorial
about the FFT, and the
FFTW page
is probably the best source of FFT information currently on the web.
The specific FFT code used by the Offt object depends
upon how RTcmix was compiled. The default compilation uses
older code written by Laurent de Soras (available at
musicdsp.org
and other places). If RTcmix was compiled using the "--with-fftw"
flag during configuration, then the
FFTW v. 3
library is used. [note: the FFTW library needs to be compiled with the
"--enable-float" flag to work in this object.]
Constructors
Access Methods
float* Offt::getbuf()
-
returns a pointer to the buffer used by Offt for the transform.
This buffer is used both as a holder for sound samples going
"in" to the FFT and coming "out" of the FFT. It is also used
to hold spectral information once the FFT has been performed on
incoming sound samples.
void Offt::r2c()
-
takes a buffer filled with fftsize (set in the
constructor) real-valued
samples (i.e. time-domain sound samples) and transforms it into
fftsize/2 complex numbers, expressed as pairs
of consecutive floats representing the real and imaginary
parts of the frequencies that are integer multiples of the
fundamental analysis frequency. These values
in the range [0, Nyquist) -- that
is, up to, but not including Nyquist. The real parts have even
indices into the buffer; the imaginary parts have odd indices. The one
wrinkle is that what would be the imaginary portion of 0 Hz -- in
other words buf[1] -- is replaced by the real value of Nyquist.
So the imaginary parts of DC and Nyquist are missing. (This is
the same format used in earlier cmix FFT routines.)
r2c() is also referred to as the "forward" FFT.
The values in the buffer may be accessed using the getbuf()
method described above.
void Offt::c2r()
-
takes a buffer filled with fftsize/2 complex numbers
representing the spectrum of a signal and transforms it
into a buffer filled with fftsize real-valued sound
samples. This is the inverse of the r2c() operation
described above, and is in fact often called the "inverse"
FFT. The values in the buffer may be accessed using the getbuf()
method described above.
Examples
#include <Ougens.h>
Offt *theFFT;
int fftsize;
float *fftbuf;
int MYINSTRUMENT::init(float p[], int n_args)
{
...
fftsize = 1024;
theFFT = new Offt(fftsize);
fftbuf = theFFT->getbuf();
...
}
int MYINSTRUMENT::run()
{
float out[2];
int i;
...
// let's assume RTBUFSAMPS is equal to fftsize for this example
// the best way to deal with fftbuf vs RTBUFSAMPS diffs is to
// use the Obucket object
for (i = 0; i < framesToRun(); i++) // read 'em in
{
fftbuf[i] = someSampleGeneratingProcess();
}
theFFT->r2c();
// now do weird stuff to the buffer...
...
theFFT->c2r();
for (i = 0; i < framesToRun(); i++) // write 'em out
{
out[0] = fftbuf[i];
rtaddout(out);
increment);
}
...
}
See Also