pvcollect Process each bin of an FFT chain, separately

chain = chain.pvcollect(numframes, func, frombin, tobin, zeroothers)

pvcollect applies function func to each bin of an FFT chain. func should be a function that takes magnitude, phase, index as inputs and returns a resulting [magnitude, phase].

The "index" is the integer bin number, starting at 0 for DC. You can optionally ignore the phase and only return a single (magnitude) value, in which case the phase is assumed to be left unchanged.

frombin, tobin, and zeroothers are optional arguments which limit the processing to a specified integer range of FFT bins. If zeroothers is set to 1 then bins outside of the range being processed are silenced.

Note that this procedure can be relatively CPU-heavy, depending on how you use it. See "efficiency considerations" below. 

See also: pvcalc, pvcalc2, UnpackFFT.




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




x = {

var in, chain, v;

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

chain = FFT(LocalBuf(1024), in);

v = LFPar.kr(0.5).range(0.1, 1);

chain = chain.pvcollect(1024, {|mag, phase, index|

//////// Try uncommenting each of these lines in turn and re-running the synth:


//[mag, phase];

//[mag, phase] / 3;

//[mag, phase].sqrt;

//[mag, 3.14.rand];

//[mag, LFNoise0.kr.range(0, 3.14)];

//[mag * Dseq([1, 0, 0, 1, 1, 0, 1, 0].stutter(8), 999999999999)]; // Can even use Demand ugens! One val demanded each frame

//[mag.sqrt, 3.14.rand];

//if(index % 7 == 0, mag, 0); // Comb filter

//if(LFNoise0.kr(10) > 0.5, mag, 0);

//mag + DelayN.kr(mag, 1, v); // Spectral delay

if((index-LFPar.kr(0.1).range(2, 1024/20)).abs < 10, mag, 0); // Swept bandpass

}, frombin: 0, tobin: 250, zeroothers: 0);

Out.ar(0, 0.5 * IFFT(chain).dup);




Efficiency considerations

Using pvcollect (or its components, UnpackFFT & PackFFT) is usually less efficient than using a single "PV_" unit generator to process an FFT chain, because it involves the creation of quite a large graph of demand-rate unit generators.

If you wish to reduce the CPU impact of using this approach, try the following: