FFTComplexDev - Measure complex deviation of signal

FFTComplexDev.kr(chain, rectify=0, powthresh=0.1)

Calculates the complex deviation of the signal, which is a measure of the total rate of change of the complex spectral components, across all the FFT bins. A stationary signal (such as a steady sine wave) should exhibit zero deviation, because its magnitude remains constant and its phase changes linearly, whereas a non-stationary signal (such as a sine wave of modulating frequency, or more complex changing sound) should exhibit a positive complex deviation.

This measure can be used as a component in onset detection - see [OnsetsDS] - but may also have other applications.

The comparison is frame-by-frame, so its behaviour will depend to some extent upon your frame size. Also note that this measure only makes sense when used with a continuous stream of FFT frames - so it should be used with the normal [FFT] UGen, not with [FFTTriggered].

The optional second argument rectify specifies (at creation time - cannot be modulated) whether all bins whose power is decreasing should be ignored. Set it greater than zero to activate the rectification feature (it's either on or off; no shades of gray).

The other optional argument powthresh tells the UGen to ignore FFT bins where the power is lower than a threshold. (This option can be modulated at control rate.)

For more details about both algorithms (rectified and non-rectified) see

Dixon, S. (2006) Onset Detection Revisited. In Proceedings of the 9th International Conference on Digital Audio Effects (DAFx-06), Montreal, Canada. pp. 133-137.

Examples

These examples use the standard unrectified measure, with a fixed powthresh value. Feel free to dabble with the parameters.

s.boot;

b = Buffer.alloc(s, 512, 1);

// Move the mouse to vary the frequency, and the amount of noise added.

// Watch the scope/post window to see the change in complex deviation.

(

x = {

var in, chain, flux;

in = SinOsc.ar(MouseX.kr(50, 500, 1), 0, 0.1) + WhiteNoise.ar(MouseY.kr(0, 0.1));

chain = FFT(b.bufnum, in);

flux = FFTComplexDev.kr(chain);

flux.poll(10, "Complex deviation");

Out.ar(0, in.dup);

Out.kr(0, flux);

}.play(s);

)

x.free;b.free;

// Load an audio file and plot the complex deviation as a function of time

b = Buffer.alloc(s, 512, 1);

c = Buffer.read(s, "sounds/a11wlk01.wav");

(

x = {

var in, chain, cxdev;

in = PlayBuf.ar(1, c.bufnum, BufRateScale.kr(c.bufnum));

chain = FFT(b.bufnum, in);

cxdev = FFTComplexDev.kr(chain, 0, 10) * 0.1;

cxdev.poll(10, "Complex deviation");

Out.ar(0, in.dup * 0.1);

K2A.ar(cxdev)

}.plot(c.numFrames/c.sampleRate, s);

)

x.free; b.free; c.free;