public abstract class FourierTransform
extends java.lang.Object
N
, there will be
N/2
frequency bands in the spectrum.
As an example, if you construct a FourierTransform 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 a FourierTransform 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 (one
of the derived classes of FourierTransform).
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
FourierTransform 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 60120 Hz in half, you will get 6090Hz and 90120Hz. 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 1102522010 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 60500Hz 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
FourierTransform 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.
Modifier and Type  Field and Description 

protected float[] 
averages 
protected int 
avgPerOctave 
protected float 
bandWidth 
static WindowFunction 
BARTLETT
A constant indicating a Bartlett window should be used on sample buffers.

static WindowFunction 
BARTLETTHANN
A constant indicating a BartlettHann window should be used on sample buffers.

static WindowFunction 
BLACKMAN
A constant indicating a Blackman window with a default value should be used on sample buffers.

static WindowFunction 
COSINE
A constant indicating a Cosine window should be used on sample buffers.

protected WindowFunction 
currentWindow 
static WindowFunction 
GAUSS
A constant indicating a Gauss with a default value should be used on sample buffers.

static WindowFunction 
HAMMING
A constant indicating a Hamming window should be used on sample buffers.

static WindowFunction 
HANN
A constant indicating a Hann window should be used on sample buffers.

protected float[] 
imag 
static WindowFunction 
LANCZOS
A constant indicating a Lanczos window should be used on sample buffers.

protected static int 
LINAVG 
protected static int 
LOGAVG 
protected static int 
NOAVG 
static WindowFunction 
NONE
A constant indicating no window should be used on sample buffers.

protected int 
octaves 
protected float[] 
real 
protected int 
sampleRate 
protected float[] 
spectrum 
protected int 
timeSize 
static WindowFunction 
TRIANGULAR
A constant indicating a Triangular window should be used on sample buffers.

protected static float 
TWO_PI 
protected int 
whichAverage 
Modifier and Type  Method and Description 

protected abstract void 
allocateArrays() 
int 
avgSize()
Returns the number of averages currently being calculated.

float 
calcAvg(float lowFreq,
float hiFreq)
Calculate the average amplitude of the frequency band bounded by
lowFreq and hiFreq , inclusive. 
protected void 
doWindow(float[] samples) 
protected void 
fillSpectrum() 
void 
forward(AudioBuffer buffer)
Performs a forward transform on
buffer . 
void 
forward(AudioBuffer buffer,
int startAt)
Performs a forward transform on
buffer . 
abstract void 
forward(float[] buffer)
Performs a forward transform on
buffer . 
void 
forward(float[] buffer,
int startAt)
Performs a forward transform on values in
buffer . 
int 
freqToIndex(float freq)
Returns the index of the frequency band that contains the requested
frequency.

float 
getAverageBandWidth(int averageIndex)
Returns the bandwidth of the requested average band.

float 
getAverageCenterFrequency(int i)
Returns the center frequency of the i^{th} average band.

float 
getAvg(int i)
Gets the value of the
i^{th} average. 
float 
getBand(int i)
Returns the amplitude of the requested frequency band.

float 
getBandWidth()
Returns the width of each frequency band in the spectrum (in Hz).

float 
getFreq(float freq)
Gets the amplitude of the requested frequency in the spectrum.

float[] 
getSpectrumImaginary()
Get the Imaginary part of the Complex representation of the spectrum.

float[] 
getSpectrumReal()
Get the Real part of the Complex representation of the spectrum.

float 
indexToFreq(int i)
Returns the middle frequency of the i^{th} band.

void 
inverse(AudioBuffer buffer)
Performs an inverse transform of the frequency spectrum and places the
result in
buffer . 
abstract void 
inverse(float[] buffer)
Performs an inverse transform of the frequency spectrum and places the
result in
buffer . 
void 
inverse(float[] freqReal,
float[] freqImag,
float[] buffer)
Performs an inverse transform of the frequency spectrum represented by
freqReal and freqImag and places the result in buffer.

void 
linAverages(int numAvg)
Sets the number of averages used when computing the spectrum and spaces the
averages in a linear manner.

void 
logAverages(int minBandwidth,
int bandsPerOctave)
Sets the number of averages used when computing the spectrum based on the
minimum bandwidth for an octave and the number of bands per octave.

void 
noAverages()
Sets the object to not compute averages.

abstract void 
scaleBand(int i,
float s)
Scales the amplitude of the
i^{th} frequency band
by s . 
void 
scaleFreq(float freq,
float s)
Scales the amplitude of the requested frequency by
a . 
abstract void 
setBand(int i,
float a)
Sets the amplitude of the
i^{th} frequency band to
a . 
protected void 
setComplex(float[] r,
float[] i) 
void 
setFreq(float freq,
float a)
Sets the amplitude of the requested frequency in the spectrum to
a . 
int 
specSize()
Returns the size of the spectrum created by this transform.

int 
timeSize()
Returns the length of the time domain signal expected by this transform.

void 
window(WindowFunction windowFunction)
Sets the window to use on the samples before taking the forward transform.

public static final WindowFunction NONE
public static final WindowFunction HAMMING
public static final WindowFunction HANN
public static final WindowFunction COSINE
public static final WindowFunction TRIANGULAR
public static final WindowFunction BARTLETT
public static final WindowFunction BARTLETTHANN
public static final WindowFunction LANCZOS
public static final WindowFunction BLACKMAN
public static final WindowFunction GAUSS
protected static final int LINAVG
protected static final int LOGAVG
protected static final int NOAVG
protected static final float TWO_PI
protected int timeSize
protected int sampleRate
protected float bandWidth
protected WindowFunction currentWindow
protected float[] real
protected float[] imag
protected float[] spectrum
protected float[] averages
protected int whichAverage
protected int octaves
protected int avgPerOctave
protected abstract void allocateArrays()
protected void setComplex(float[] r, float[] i)
protected void fillSpectrum()
public void noAverages()
public void linAverages(int numAvg)
specSize() / numAvg
bands wide.numAvg
 int: how many averages to computepublic void logAverages(int minBandwidth, int bandsPerOctave)
logAverages(11, 1)
will result in 12 averages, each
corresponding to an octave, the first spanning 0 to 11 Hz. To ensure that
each octave band is a full octave, the number of octaves is computed by
dividing the Nyquist frequency by two, and then the result of that by two,
and so on. This means that the actual bandwidth of the lowest octave may
not be exactly the value specified.minBandwidth
 int: the minimum bandwidth used for an octave, in Hertz.bandsPerOctave
 int: how many bands to split each octave intopublic void window(WindowFunction windowFunction)
windowFunction
 the new WindowFunction to use, typically one of the statically defined
windows like HAMMING or BLACKMANprotected void doWindow(float[] samples)
public int timeSize()
public int specSize()
timeSize()/2 + 1
, see above for an explanation.public float getBand(int i)
i
 int: the index of a frequency bandpublic float getBandWidth()
public float getAverageBandWidth(int averageIndex)
averageIndex
 int: the index of the average you want the bandwidth ofgetAverageCenterFrequency(int)
public abstract void setBand(int i, float a)
i^{th}
frequency band to
a
. You can use this to shape the spectrum before using
inverse()
.i
 int: the frequency band to modifya
 float: the new amplitudepublic abstract void scaleBand(int i, float s)
i^{th}
frequency band
by s
. You can use this to shape the spectrum before using
inverse()
.i
 int: the frequency band to modifys
 float: the scaling factorpublic int freqToIndex(float freq)
freq
 float: the frequency you want the index for (in Hz)public float indexToFreq(int i)
i
 int: the index of the band you want to middle frequency ofpublic float getAverageCenterFrequency(int i)
i
 int: which average band you want the center frequency of.public float getFreq(float freq)
freq
 float: the frequency in Hzpublic void setFreq(float freq, float a)
a
.freq
 float: the frequency in Hza
 float: the new amplitudepublic void scaleFreq(float freq, float s)
a
.freq
 float: the frequency in Hzs
 float: the scaling factorpublic int avgSize()
public float getAvg(int i)
i^{th}
average.i
 int: the average you want the value ofpublic float calcAvg(float lowFreq, float hiFreq)
lowFreq
and hiFreq
, inclusive.lowFreq
 float: the lower bound of the band, in HertzhiFreq
 float: the upper bound of the band, in Hertzpublic float[] getSpectrumReal()
public float[] getSpectrumImaginary()
public abstract void forward(float[] buffer)
buffer
.buffer
 float[]: the buffer to analyze, must be the same length as timeSize()public void forward(float[] buffer, int startAt)
buffer
.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.public void forward(AudioBuffer buffer)
buffer
.buffer
 AudioBuffer: the buffer to analyzepublic void forward(AudioBuffer buffer, int startAt)
buffer
.buffer
 AudioBuffer: the buffer to analyzestartAt
 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.public abstract void inverse(float[] buffer)
buffer
.buffer
 float[]: the buffer to place the result of the inverse transform inpublic void inverse(AudioBuffer buffer)
buffer
.buffer
 AudioBuffer: the buffer to place the result of the inverse transform inpublic void inverse(float[] freqReal, float[] freqImag, float[] buffer)
freqReal
 float[]: the real part of the frequency spectrumfreqImag
 float[]: the imaginary part the frequency spectrumbuffer
 float[]: the buffer to place the inverse transform in