SuperCollider CLASSES (extension)

PV_BinPlayBuf
ExtensionExtension

Plays FFT data to a memory buffer

Description

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.

WARNING: Resynth of a FFTs with large window sizes may cause CPU spikes. Unlike PV_BufRd, PV_BinBufRd needs to have an FFT Ugen preceding it in the processing chain.

Class Methods

*new (buffer, playbuf, rate: 1, offset: 0, binStart: 0, binSkip: 1, numBins: 1, loop: 0, clear: 0)

Arguments:

buffer

The FFT buffer to fill data into.

playbuf

The buffer to read frames of FFT data from.

rate
offset
binStart

See below.

binSkip

See below.

numBins

See below.

loop
clear

Inherited class methods

Instance Methods

Inherited instance methods

Examples

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

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).

// anazlyze a soundfile and store its data to a buffer
s.boot;

(
var sf;
// path to a sound file here
p = "Platform.resourceDir +/+ 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 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 recBuf=1, soundBufnum=2;
    var in, chain, bufnum;
    bufnum = LocalBuf.new(1024);
    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
    }).add;
)

a = Synth("pvrec", [\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, recBuf=1, playbuf, clear = 0.0;
    var in, chain, bufnum;
    bufnum = LocalBuf.new(1024);
    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);
    }).add;
);

// mix the resynth and data from the recBuf
b = Synth("pvplay", [\out, 0, \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;

// play your analysis back ... use multiple PV_BinBufRd ugens.
(
SynthDef("pvplay", { arg out=0, recBuf=1, playbuf, clear = 0.0;
    var in, chain, bufnum;
    bufnum = LocalBuf.new(1024);
    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);
    }).add;
);

// mix the resynth and data from the recBuf
b = Synth("pvplay", [\out, 0, \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
[y, z].do({arg me; me.free});