ddf.minim.analysis

## Class FFT

• ```public class FFT
extends FourierTransform```
FFT stands for Fast Fourier Transform. It is an efficient way to calculate the Complex Discrete Fourier Transform. There is not much to say about this class other than the fact that when you want to analyze the spectrum of an audio buffer you will almost always use this class. One restriction of this class is that the audio buffers you want to analyze must have a length that is a power of two. If you try to construct an FFT with a `timeSize` that is not a power of two, an IllegalArgumentException will be thrown.

A Fourier Transform is an algorithm that transforms a signal in the time domain, such as a sample buffer, into a signal in the frequency domain, often called the spectrum. The spectrum does not represent individual frequencies, but actually represents frequency bands centered on particular frequencies. The center frequency of each band is usually expressed as a fraction of the sampling rate of the time domain signal and is equal to the index of the frequency band divided by the total number of bands. The total number of frequency bands is usually equal to the length of the time domain signal, but access is only provided to frequency bands with indices less than half the length, because they correspond to frequencies below the Nyquist frequency. In other words, given a signal of length `N`, there will be `N/2` frequency bands in the spectrum.

As an example, if you construct an FFT with a `timeSize` of 1024 and and a `sampleRate` of 44100 Hz, then the spectrum will contain values for frequencies below 22010 Hz, which is the Nyquist frequency (half the sample rate). If you ask for the value of band number 5, this will correspond to a frequency band centered on `5/1024 * 44100 = 0.0048828125 * 44100 = 215 Hz`. The width of that frequency band is equal to `2/1024`, expressed as a fraction of the total bandwidth of the spectrum. The total bandwith of the spectrum is equal to the Nyquist frequency, which in this case is 22050, so the bandwidth is equal to about 50 Hz. It is not necessary for you to remember all of these relationships, though it is good to be aware of them. The function `getFreq()` allows you to query the spectrum with a frequency in Hz and the function `getBandWidth()` will return the bandwidth in Hz of each frequency band in the spectrum.

Usage

A typical usage of the FFT is to analyze a signal so that the frequency spectrum may be represented in some way, typically with vertical lines. You could do this in Processing with the following code, where `audio` is an AudioSource and `fft` is an FFT.

``` fft.forward(audio.left);
for (int i = 0; i < fft.specSize(); i++)
{
// draw the line for frequency band i, scaling it by 4 so we can see it a bit better
line(i, height, i, height - fft.getBand(i) * 4);
}
```
Windowing

Windowing is the process of shaping the audio samples before transforming them to the frequency domain. The Fourier Transform assumes the sample buffer is is a repetitive signal, if a sample buffer is not truly periodic within the measured interval sharp discontinuities may arise that can introduce spectral leakage. Spectral leakage is the speading of signal energy across multiple FFT bins. This "spreading" can drown out narrow band signals and hinder detection.

A windowing function attempts to reduce spectral leakage by attenuating the measured sample buffer at its end points to eliminate discontinuities. If you call the `window()` function with an appropriate WindowFunction, such as `HammingWindow()`, the sample buffers passed to the object for analysis will be shaped by the current window before being transformed. The result of using a window is to reduce the leakage in the spectrum somewhat.

Averages

FFT also has functions that allow you to request the creation of an average spectrum. An average spectrum is simply a spectrum with fewer bands than the full spectrum where each average band is the average of the amplitudes of some number of contiguous frequency bands in the full spectrum.

`linAverages()` allows you to specify the number of averages that you want and will group frequency bands into groups of equal number. So if you have a spectrum with 512 frequency bands and you ask for 64 averages, each average will span 8 bands of the full spectrum.

`logAverages()` will group frequency bands by octave and allows you to specify the size of the smallest octave to use (in Hz) and also how many bands to split each octave into. So you might ask for the smallest octave to be 60 Hz and to split each octave into two bands. The result is that the bandwidth of each average is different. One frequency is an octave above another when it's frequency is twice that of the lower frequency. So, 120 Hz is an octave above 60 Hz, 240 Hz is an octave above 120 Hz, and so on. When octaves are split, they are split based on Hz, so if you split the octave 60-120 Hz in half, you will get 60-90Hz and 90-120Hz. You can see how these bandwidths increase as your octave sizes grow. For instance, the last octave will always span `sampleRate/4 - sampleRate/2`, which in the case of audio sampled at 44100 Hz is 11025-22010 Hz. These logarithmically spaced averages are usually much more useful than the full spectrum or the linearly spaced averages because they map more directly to how humans perceive sound.

`calcAvg()` allows you to specify the frequency band you want an average calculated for. You might ask for 60-500Hz and this function will group together the bands from the full spectrum that fall into that range and average their amplitudes for you.

If you don't want any averages calculated, then you can call `noAverages()`. This will not impact your ability to use `calcAvg()`, it will merely prevent the object from calculating an average array every time you use `forward()`.

Inverse Transform

FFT also supports taking the inverse transform of a spectrum. This means that a frequency spectrum will be transformed into a time domain signal and placed in a provided sample buffer. The length of the time domain signal will be `timeSize()` long. The `set` and `scale` functions allow you the ability to shape the spectrum already stored in the object before taking the inverse transform. You might use these to filter frequencies in a spectrum or modify it in some other way.

Author:
Damien Di Fede
`FourierTransform`, The Fast Fourier Transform

• ### Fields inherited from class ddf.minim.analysis.FourierTransform

`averages, avgPerOctave, bandWidth, BARTLETT, BARTLETTHANN, BLACKMAN, COSINE, currentWindow, GAUSS, HAMMING, HANN, imag, LANCZOS, LINAVG, LOGAVG, NOAVG, NONE, octaves, real, sampleRate, spectrum, timeSize, TRIANGULAR, TWO_PI, whichAverage`
• ### Constructor Summary

Constructors
Constructor and Description
```FFT(int timeSize, float sampleRate)```
Constructs an FFT that will accept sample buffers that are `timeSize` long and have been recorded with a sample rate of `sampleRate`.
• ### Method Summary

All Methods
Modifier and Type Method and Description
`protected void` `allocateArrays()`
`void` `forward(float[] buffer)`
Performs a forward transform on `buffer`.
`void` ```forward(float[] buffReal, float[] buffImag)```
Performs a forward transform on the passed buffers.
`void` ```forward(float[] buffer, int startAt)```
Performs a forward transform on values in `buffer`.
`void` `inverse(float[] buffer)`
Performs an inverse transform of the frequency spectrum and places the result in `buffer`.
`void` ```scaleBand(int i, float s)```
Scales the amplitude of the `ith` frequency band by `s`.
`void` ```setBand(int i, float a)```
Sets the amplitude of the `ith` frequency band to `a`.
• ### Methods inherited from class ddf.minim.analysis.FourierTransform

`avgSize, calcAvg, doWindow, fillSpectrum, forward, forward, freqToIndex, getAverageBandWidth, getAverageCenterFrequency, getAvg, getBand, getBandWidth, getFreq, getSpectrumImaginary, getSpectrumReal, indexToFreq, inverse, inverse, linAverages, logAverages, noAverages, scaleFreq, setComplex, setFreq, specSize, timeSize, window`
• ### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`
• ### Constructor Detail

• #### FFT

```public FFT(int timeSize,
float sampleRate)```
Constructs an FFT that will accept sample buffers that are `timeSize` long and have been recorded with a sample rate of `sampleRate`. `timeSize` must be a power of two. This will throw an exception if it is not.
Parameters:
`timeSize` - int: the length of the sample buffers you will be analyzing
`sampleRate` - float: the sample rate of the audio you will be analyzing
• ### Method Detail

• #### allocateArrays

`protected void allocateArrays()`
Specified by:
`allocateArrays` in class `FourierTransform`
• #### scaleBand

```public void scaleBand(int i,
float s)```
Description copied from class: `FourierTransform`
Scales the amplitude of the `ith` frequency band by `s`. You can use this to shape the spectrum before using `inverse()`.
Specified by:
`scaleBand` in class `FourierTransform`
Parameters:
`i` - int: the frequency band to modify
`s` - float: the scaling factor
• #### setBand

```public void setBand(int i,
float a)```
Description copied from class: `FourierTransform`
Sets the amplitude of the `ith` frequency band to `a`. You can use this to shape the spectrum before using `inverse()`.
Specified by:
`setBand` in class `FourierTransform`
Parameters:
`i` - int: the frequency band to modify
`a` - float: the new amplitude
• #### forward

`public void forward(float[] buffer)`
Description copied from class: `FourierTransform`
Performs a forward transform on `buffer`.
Specified by:
`forward` in class `FourierTransform`
Parameters:
`buffer` - float[]: the buffer to analyze, must be the same length as timeSize()
• #### forward

```public void forward(float[] buffer,
int startAt)```
Description copied from class: `FourierTransform`
Performs a forward transform on values in `buffer`.
Overrides:
`forward` in class `FourierTransform`
Parameters:
`buffer` - float[]: the buffer to analyze, must be the same length as timeSize()
`startAt` - int: the index to start at in the buffer. there must be at least timeSize() samples between the starting index and the end of the buffer. If there aren't, an error will be issued and the operation will not be performed.
• #### forward

```public void forward(float[] buffReal,
float[] buffImag)```
Performs a forward transform on the passed buffers.
Parameters:
`buffReal` - the real part of the time domain signal to transform
`buffImag` - the imaginary part of the time domain signal to transform
• #### inverse

`public void inverse(float[] buffer)`
Description copied from class: `FourierTransform`
Performs an inverse transform of the frequency spectrum and places the result in `buffer`.
Specified by:
`inverse` in class `FourierTransform`
Parameters:
`buffer` - float[]: the buffer to place the result of the inverse transform in