PV_BinPlayBuf plays FFT data to a memory buffer

PV_PlayBuf will play back FFT data stored to a buffer with PV_RecordBuf.

WARNING: Resynth of a FFTs with large window sizes may cause CPU spikes.

WARNING: Unlike PV_BufRd, PV_BinBufRd needs to have an FFT Ugen preceding it in the

processing chain.

PV_RecordBuf stores FFT data to a buffer for use by a number of PV UGens. See also PV_RecordBuf, PV_PlayBuf, PV_BinPlayBuf and PV_BufRd.

PV_BinBufRd(buffer, playbuf, point, binStart, binSkip, numBins, hop, wintype)

buffer - the FFT buffer to fill data into

playbuf - the buffer to read frames of FFT data fram.

point - a value between 0.0 and 1.0. 0.0 is the beginning of the file, 1.0 the end. Values greater then 1.0

or less then 0.0 are wrapped into this range.

binStart, binSkip and numBins - see below.

With binStart, binSkip and numBins, you have some control over which bins to synthesize.

e.g. binStart = 0

binSkip = 2

numBins = 10

bins to synthesize = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

All values for these parameters are truncated to integers when used by the UGens (you can't start an bin 1.5 or skip 2.3).

Examples:

// anazlyze a soundfile and store its data to a buffer

s.boot;

(

var sf;

// path to a sound file here

p = "sounds/a11wlk01.wav";

// the frame size for the analysis - experiment with other sizes (powers of 2)

f = 1024;

// the hop size

h = 0.25;

// get some info about the file

sf = SoundFile.new( p );

sf.openRead;

sf.close;

// allocate the FFT buffer

x = Buffer.alloc(s, f);

// allocate memory to store FFT data to... SimpleNumber.calcPVRecSize(frameSize, hop) will return

// the appropriate number of samples needed for the buffer

y = Buffer.alloc(s, sf.duration.calcPVRecSize(f, h));

// allocate the soundfile you want to analyze

z = Buffer.read(s, p);

)

// this does the analysis and saves it to buffer 1... frees itself when done

(

SynthDef("pvrec", { arg bufnum=0, recBuf=1, soundBufnum=2;

var in, chain;

Line.kr(1, 1, BufDur.kr(soundBufnum), doneAction: 2);

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

// note the window type and overlaps... this is important for resynth parameters

chain = FFT(bufnum, in, 0.25, 1);

chain = PV_RecordBuf(chain, recBuf, 0, 1, 0, 0.25, 1);

// no ouput ... simply save the analysis to recBuf

}).send(s);

)

a = Synth("pvrec", [\bufnum, x, \recBuf, y, \soundBufnum, z]);

// you can save your 'analysis' file to disk! I suggest using float32 for the format

// These can be read back in using Buffer.read

y.write(p++".scpv", "wav", "float32");

// play your analysis back ... see the playback UGens listed above for more examples.

(

SynthDef("pvplay", { arg out=0, bufnum=0, recBuf=1, playbuf, clear = 0.0;

var in, chain;

chain = FFT(bufnum, PlayBuf.ar(1, playbuf, BufRateScale.kr(playbuf), loop: 1));

// MouseX points into file. start at bin 10, skip 3, resynth 50

chain = PV_BinBufRd(chain, recBuf, MouseX.kr(0, 1), 10, 3, 5, clear);

Out.ar(out, IFFT(chain, 1).dup);

}).send(s);

);

// mix the resynth and data from the recBuf

b = Synth("pvplay", [\out, 0, \bufnum, x, \recBuf, y, \playbuf, z, \clear, 1.0]);

b.free;

// zero out the data in the FFT buf that ins't read in from recBuf

b = Synth("pvplay", [\out, 0, \bufnum, x, \recBuf, y, \playbuf, z, \clear, 1.0]);

// stop the synth

b.free;

// play your analysis back ... use multiple PV_BinBufRd ugens.

(

SynthDef("pvplay", { arg out=0, bufnum=0, recBuf=1, playbuf, clear = 0.0;

var in, chain;

chain = FFT(bufnum, PlayBuf.ar(1, playbuf, BufRateScale.kr(playbuf), loop: 1));

// MouseX points into file. start at bin 10, skip 3, resynth 50

chain = PV_BinBufRd(chain, recBuf, MouseX.kr(0, 1), 10, 3, 50, clear);

chain = PV_BinBufRd(chain, recBuf, MouseX.kr(0.1, 0.9), 10, 3, 50, 0.0);

Out.ar(out, IFFT(chain, 1).dup);

}).send(s);

);

// mix the resynth and data from the recBuf

b = Synth("pvplay", [\out, 0, \bufnum, x, \recBuf, y, \playbuf, z, \clear, 0.0]);

b.free;

// zero out the data in the FFT buf that ins't read in from recBuf

b = Synth("pvplay", [\out, 0, \bufnum, x, \recBuf, y, \playbuf, z, \clear, 1.0]);

// stop the synth

b.free;

// free the buffers

[x, y, z].do({arg me; me.free});