1TITLE:: PV_BinPlayBuf 2summary:: Plays FFT data to a memory buffer 3categories:: Libraries>JoshUGens, UGens>FFT 4related:: Classes/PV_RecordBuf, Classes/PV_PlayBuf, Classes/PV_BufRd 5 6DESCRIPTION:: 7PV_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. 8WARNING:: 9Resynth of a FFTs with large window sizes may cause CPU spikes. 10Unlike PV_BufRd, PV_BinBufRd needs to have an FFT Ugen preceding it in the processing chain. 11:: 12 13CLASSMETHODS:: 14 15METHOD:: new 16 17ARGUMENT:: buffer 18The FFT buffer to fill data into. 19 20ARGUMENT:: playbuf 21The buffer to read frames of FFT data from. 22 23ARGUMENT:: rate 24 25ARGUMENT:: offset 26 27ARGUMENT:: binStart 28See below. 29 30ARGUMENT:: binSkip 31See below. 32 33ARGUMENT:: numBins 34See below. 35 36ARGUMENT:: loop 37 38ARGUMENT:: clear 39 40INSTANCEMETHODS:: 41 42 43EXAMPLES:: 44note:: 45With binStart, binSkip and numBins, you have some control over which bins to synthesize. e.g. 46list:: 47 ## binStart = 0 48 ## binSkip = 2 49 ## numBins = 10 50 ## bins to synthesize = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]. 51:: 52All 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). 53:: 54 55 56code:: 57// anazlyze a soundfile and store its data to a buffer 58s.boot; 59 60( 61var sf; 62// path to a sound file here 63p = "Platform.resourceDir +/+ sounds/a11wlk01.wav"; 64// the frame size for the analysis - experiment with other sizes (powers of 2) 65f = 1024; 66// the hop size 67h = 0.25; 68// get some info about the file 69sf = SoundFile.new( p ); 70sf.openRead; 71sf.close; 72// allocate memory to store FFT data to... SimpleNumber.calcPVRecSize(frameSize, hop) will return 73// the appropriate number of samples needed for the buffer 74y = Buffer.alloc(s, sf.duration.calcPVRecSize(f, h)); 75// allocate the soundfile you want to analyze 76z = Buffer.read(s, p); 77) 78 79// this does the analysis and saves it to buffer 1... frees itself when done 80( 81SynthDef("pvrec", { arg recBuf=1, soundBufnum=2; 82 var in, chain, bufnum; 83 bufnum = LocalBuf.new(1024); 84 Line.kr(1, 1, BufDur.kr(soundBufnum), doneAction: 2); 85 in = PlayBuf.ar(1, soundBufnum, BufRateScale.kr(soundBufnum), loop: 0); 86 // note the window type and overlaps... this is important for resynth parameters 87 chain = FFT(bufnum, in, 0.25, 1); 88 chain = PV_RecordBuf(chain, recBuf, 0, 1, 0, 0.25, 1); 89 // no ouput ... simply save the analysis to recBuf 90 }).add; 91) 92 93a = Synth("pvrec", [\recBuf, y, \soundBufnum, z]); 94 95// you can save your 'analysis' file to disk! I suggest using float32 for the format 96// These can be read back in using Buffer.read 97 98y.write(p++".scpv", "wav", "float32"); 99 100// play your analysis back ... see the playback UGens listed above for more examples. 101( 102SynthDef("pvplay", { arg out=0, recBuf=1, playbuf, clear = 0.0; 103 var in, chain, bufnum; 104 bufnum = LocalBuf.new(1024); 105 chain = FFT(bufnum, PlayBuf.ar(1, playbuf, BufRateScale.kr(playbuf), loop: 1)); 106 // MouseX points into file. start at bin 10, skip 3, resynth 50 107 chain = PV_BinBufRd(chain, recBuf, MouseX.kr(0, 1), 10, 3, 5, clear); 108 Out.ar(out, IFFT(chain, 1).dup); 109 }).add; 110); 111 112// mix the resynth and data from the recBuf 113b = Synth("pvplay", [\out, 0, \recBuf, y, \playbuf, z, \clear, 0.0]); 114 115b.free; 116 117// zero out the data in the FFT buf that ins't read in from recBuf 118b = Synth("pvplay", [\out, 0, \bufnum, x, \recBuf, y, \playbuf, z, \clear, 1.0]); 119 120// stop the synth 121b.free; 122 123// play your analysis back ... use multiple PV_BinBufRd ugens. 124( 125SynthDef("pvplay", { arg out=0, recBuf=1, playbuf, clear = 0.0; 126 var in, chain, bufnum; 127 bufnum = LocalBuf.new(1024); 128 chain = FFT(bufnum, PlayBuf.ar(1, playbuf, BufRateScale.kr(playbuf), loop: 1)); 129 // MouseX points into file. start at bin 10, skip 3, resynth 50 130 chain = PV_BinBufRd(chain, recBuf, MouseX.kr(0, 1), 10, 3, 50, clear); 131 chain = PV_BinBufRd(chain, recBuf, MouseX.kr(0.1, 0.9), 10, 3, 50, 0.0); 132 Out.ar(out, IFFT(chain, 1).dup); 133 }).add; 134); 135 136// mix the resynth and data from the recBuf 137b = Synth("pvplay", [\out, 0, \recBuf, y, \playbuf, z, \clear, 0.0]); 138 139b.free; 140 141// zero out the data in the FFT buf that ins't read in from recBuf 142b = Synth("pvplay", [\out, 0, \bufnum, x, \recBuf, y, \playbuf, z, \clear, 1.0]); 143 144// stop the synth 145b.free; 146// free the buffers 147[y, z].do({arg me; me.free}); 148:: 149