{
   "ancestor_list" : [],
   "description" : "Explore options to freeze playback of a sound file\r\n(a) by playhead movement\r\n(b) by FFT freeze",
   "name" : "freeze playback",
   "author" : "LFSaw",
   "id" : "1-5hh",
   "is_private" : null,
   "code" : "q = q ? ();\r\n\r\n// load buffers\r\n// e.g. mono sound (see below)\r\nq.audioBuffer = Buffer.read(s, Platform.resourceDir +/+ \"sounds/a11wlk01.wav\");\r\n\r\n(\r\nNdef(\\freezePlayer).addSpec(\r\n\t\\lpFreq, \\freq,\r\n\t\\hpFreq, \\freq,\r\n\t\\shift, [0.125, 4, \\exp],\r\n\t\\freezeRate, [10, 100, \\exp], // how fast to go back and forth\r\n\t\\rateDir, [-1, 1, \\lin], // direction of movement in the buffer, if 1 or -1, use normal playback\r\n\t\\rate, [0.125, 16, \\exp], // how fast the buffer should play back/forth in normal mode\r\n\t\\modSource, [0, 2, \\lin, 0], // [SinOsc, LFPulse, LFTri]\r\n);\r\n\r\n// make sure to check number of channels of the buffer(s) to be used\r\nNdef(\\freezePlayer, {|bufnum = 0|\r\n\tvar numChannels = 1;\r\n\tvar chain, efx;\r\n\tvar rateDir = \\rateDir.kr(0);\r\n\t// var wet = \\wet.kr(0) > 0;\r\n\tvar wet = rateDir.abs < 1;\r\n\tvar rateScale = BufRateScale.kr(bufnum);\r\n\r\n\t// possible modulation sources are e.g. LFPulse, LFTri, SinOsc..\r\n\t// for the system to work properly, the integrated signal should be 0, (i.e. going equal parts backwards and forwards).\r\n\tvar modSource = LinSelectX.kr(\\modSource.kr(0), [\r\n\t\tSinOsc.kr(\\freezeRate.kr(20), phase: 0).range(-1, 1),\r\n\t\tLFPulse.kr(\\freezeRate.kr(20), iphase: 0).range(-1, 1),\r\n\t\tLFTri.kr(\\freezeRate.kr(20), iphase: 0).range(-1, 1)\r\n\t]);\r\n\r\n\r\n\tvar rateFX = (\r\n\t\t((1-wet) * rateDir.sign) // normal playback\r\n\t\t+ (wet * (modSource + rateDir)) // \"freeze\"\r\n\t) * \\rate.kr(1) * rateScale;\r\n\r\n\tvar snd = PlayBuf.ar(\r\n\t\tnumChannels: numChannels,\r\n\t\tbufnum: bufnum,\r\n\t\trate: rateFX,\r\n\t\ttrigger: \\trig.tr(1),\r\n\t\tloop: 1\r\n\t);\r\n\r\n\tsnd = LPF.ar(HPF.ar(snd, \\hpFreq.kr(10)), \\lpFreq.kr(10000));\r\n});\r\n);\r\n\r\nNdef(\\freezePlayer).set(\\bufnum, q.audioBuffer.bufnum);\r\nNdef(\\freezePlayer).edit;\r\n\r\n\r\n// q.audioBuffer.play\r\n\r\n//////////////// frequency-domain\r\n\r\n(\r\nNdef(\\freezePlayerFFT).addSpec(\r\n\t\\lpFreq, \\freq,\r\n\t\\hpFreq, \\freq,\r\n\t\\wet, [0, 1, \\lin, 1],\r\n\t\\frShift, [0.25, 4, \\exp],\r\n\t\\frDiff, [0, 1, \\lin, 1]\r\n);\r\nNdef(\\freezePlayerFFT, {|bufnum = 0|\r\n\tvar numChannels = 1;\r\n\tvar chain, efx;\r\n\tvar wet = \\wet.kr(0) > 0;\r\n\tvar buffer = q.audioBuffer;\r\n\tvar snd = PlayBuf.ar(\r\n\t\tnumChannels: numChannels,\r\n\t\tbufnum: bufnum,\r\n\t\trate: \\rate.kr(1) * BufRateScale.kr(bufnum) * (1-wet),\r\n\t\ttrigger: \\trig.tr(1),\r\n\t\tloop: 1\r\n\t);\r\n\r\n\t// FFT processing\r\n    chain = FFT(LocalBuf(4096), snd); // encode to frequency domain\r\n\tchain = PV_Diffuser(chain, \\frDiff.kr(0) * wet);\r\n\tchain = PV_Freeze(chain, wet);\r\n\tchain = PV_BinShift(chain, \\frShift.kr(1));\r\n\r\n\tefx = IFFT(chain); // decode to time domain\r\n\r\n\tsnd = Select.ar(wet, [snd, efx]);\r\n\t// snd = efx;\r\n\r\n\tsnd = LPF.ar(HPF.ar(snd, \\hpFreq.kr(10)), \\lpFreq.kr(10000));\r\n});\r\n)\r\n\r\nNdef(\\freezePlayerFFT).set(\\bufnum, q.audioBuffer.bufnum);\r\n\r\n\r\nNdef(\\freezePlayerFFT).play\r\nNdef(\\freezePlayerFFT).edit",
   "labels" : [
      "playback",
      "jit",
      "freeze",
      "efx"
   ]
}
