«freeze playback» by LFSaw
on 03 Jul'23 10:31 inExplore options to freeze playback of a sound file (a) by playhead movement (b) by FFT freeze
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
q = q ? (); // load buffers // e.g. mono sound (see below) q.audioBuffer = Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav"); ( Ndef(\freezePlayer).addSpec( \lpFreq, \freq, \hpFreq, \freq, \shift, [0.125, 4, \exp], \freezeRate, [10, 100, \exp], // how fast to go back and forth \rateDir, [-1, 1, \lin], // direction of movement in the buffer, if 1 or -1, use normal playback \rate, [0.125, 16, \exp], // how fast the buffer should play back/forth in normal mode \modSource, [0, 2, \lin, 0], // [SinOsc, LFPulse, LFTri] ); // make sure to check number of channels of the buffer(s) to be used Ndef(\freezePlayer, {|bufnum = 0| var numChannels = 1; var chain, efx; var rateDir = \rateDir.kr(0); // var wet = \wet.kr(0) > 0; var wet = rateDir.abs < 1; var rateScale = BufRateScale.kr(bufnum); // possible modulation sources are e.g. LFPulse, LFTri, SinOsc.. // for the system to work properly, the integrated signal should be 0, (i.e. going equal parts backwards and forwards). var modSource = LinSelectX.kr(\modSource.kr(0), [ SinOsc.kr(\freezeRate.kr(20), phase: 0).range(-1, 1), LFPulse.kr(\freezeRate.kr(20), iphase: 0).range(-1, 1), LFTri.kr(\freezeRate.kr(20), iphase: 0).range(-1, 1) ]); var rateFX = ( ((1-wet) * rateDir.sign) // normal playback + (wet * (modSource + rateDir)) // "freeze" ) * \rate.kr(1) * rateScale; var snd = PlayBuf.ar( numChannels: numChannels, bufnum: bufnum, rate: rateFX, trigger: \trig.tr(1), loop: 1 ); snd = LPF.ar(HPF.ar(snd, \hpFreq.kr(10)), \lpFreq.kr(10000)); }); ); Ndef(\freezePlayer).set(\bufnum, q.audioBuffer.bufnum); Ndef(\freezePlayer).edit; // q.audioBuffer.play //////////////// frequency-domain ( Ndef(\freezePlayerFFT).addSpec( \lpFreq, \freq, \hpFreq, \freq, \wet, [0, 1, \lin, 1], \frShift, [0.25, 4, \exp], \frDiff, [0, 1, \lin, 1] ); Ndef(\freezePlayerFFT, {|bufnum = 0| var numChannels = 1; var chain, efx; var wet = \wet.kr(0) > 0; var buffer = q.audioBuffer; var snd = PlayBuf.ar( numChannels: numChannels, bufnum: bufnum, rate: \rate.kr(1) * BufRateScale.kr(bufnum) * (1-wet), trigger: \trig.tr(1), loop: 1 ); // FFT processing chain = FFT(LocalBuf(4096), snd); // encode to frequency domain chain = PV_Diffuser(chain, \frDiff.kr(0) * wet); chain = PV_Freeze(chain, wet); chain = PV_BinShift(chain, \frShift.kr(1)); efx = IFFT(chain); // decode to time domain snd = Select.ar(wet, [snd, efx]); // snd = efx; snd = LPF.ar(HPF.ar(snd, \hpFreq.kr(10)), \lpFreq.kr(10000)); }); ) Ndef(\freezePlayerFFT).set(\bufnum, q.audioBuffer.bufnum); Ndef(\freezePlayerFFT).play Ndef(\freezePlayerFFT).edit
reception
comments