SuperCollider CLASSES (extension)

PV_PlayBuf
ExtensionExtension

Plays FFT data to a memory buffer

Description

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.
NOTE: PV_RecordBuf stores FFT data to a buffer for use by a number of PV UGens.

Class Methods

*new (buffer, playbuf, rate: 1, offset: 0, loop: 0)

Arguments:

buffer

The FFT buffer to fill data into.

playbuf

The buffer to read frames of FFT data from.

rate

Rate of playback of FFT data. Fractional time frames will use linearly interpolated phase and magnitude values. Can be negative.

offset

An integer number of frames to offset into the playbuf file. Defaults to 0.0.

binStart
(binSkip)
(numBins)
(loop)
(clear)

Inherited class methods

Instance Methods

Inherited instance methods

Examples

// 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 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);
    bufnum = LocalBuf.new(1024, 1); // uses frame size from above
    // 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;
    var in, chain, bufnum;
    bufnum = LocalBuf.new(1024, 1);
    chain = PV_PlayBuf(bufnum, recBuf, MouseX.kr(-1, 1), 50, 1);
    Out.ar(out, IFFT(chain, 1).dup);
    }).add;
);
b = Synth("pvplay", [\out, 0, \recBuf, y]);

// stop the synth
b.free;

// vary the rate... experiment with different FFT sizes and overlaps in the analysis:
(
SynthDef("pvplay", { arg out=0, recBuf=1;
    var in, chain, bufnum;
    bufnum = LocalBuf.new(1024, 1);
    chain = PV_PlayBuf(bufnum, recBuf, LFNoise2.kr(0.2).range(-1, 2), 0, 1);
    Out.ar(out, IFFT(chain, 1).dup);
    }).add;
)
b = Synth("pvplay", [\out, 0, \recBuf, y]);

// stop the synth
b.free;

// free the buffers
[y, z].do({arg me; me.free});