{
   "labels" : [
      "glitch",
      "tutorial",
      "stutter"
   ],
   "is_private" : null,
   "id" : "1-50T",
   "code" : "// Source audio: simple sweep\r\n{ Pulse.ar(XLine.kr(100, 1000, 5)) * 0.1!2 }.play;\r\n\r\n// All you need is a varying delay.\r\n// In this example, an 0.2s delay is switched on every other 0.2s. So every 0.2s of audio is repeated once.\r\n(\r\n{\r\n    var snd = Pulse.ar(XLine.kr(100, 1000, 5));\r\n    snd = DelayC.ar(snd, 0.2, LFPulse.ar((0.2 * 2).reciprocal) * 0.2);\r\n    snd * 0.1!2;\r\n}.play;\r\n)\r\n\r\n// More general version using Stepper instead of LFPulse. You can control the length of the repeat and the number of repeats.\r\n(\r\n{ |fragmentlength = 0.2, numrepeats = 3|\r\n    var trig, reset, del, snd;\r\n    snd = Pulse.ar(XLine.kr(100, 1000, 5));\r\n    trig = Impulse.ar(fragmentlength.reciprocal);\r\n    reset = Impulse.ar(0); // if we don't do this the stepper will start at 1...\r\n    del = Stepper.ar(trig, reset, 0, numrepeats - 1) * fragmentlength;\r\n    snd = DelayC.ar(snd, 10, del);\r\n    snd * 0.1!2;\r\n}.play(args: [\\fragmentlength, 0.1, \\numrepeats, 4]);\r\n)\r\n\r\n// With some enhancements, we can allow the reset counter to be out of sync.\r\n(\r\n{ |holdlength = 0.5, fragmentlength = 0.2|\r\n    var reset, phase, fragment, del, snd;\r\n    snd = Pulse.ar(XLine.kr(100, 1000, 5));\r\n\r\n    reset = Impulse.ar(holdlength.reciprocal);\r\n    phase = Sweep.ar(reset);\r\n    // this is the easiest way to make an Impulse resettable? seriously?\r\n    fragment = { |ph| (ph - Delay1.ar(ph)) < 0 + Impulse.ar(0) }.value(phase / fragmentlength % 1);\r\n    del = Latch.ar(phase, fragment);\r\n    snd = DelayC.ar(snd, 10, del);\r\n    snd * 0.1!2;\r\n}.play;\r\n)\r\n\r\n// Many stutter plugins let you play back the audio at a different rate.\r\n// This is a little trickier. Speeding up 2x not as easy as adding a Sweep.ar(fragment) because otherwise you get negative delays.\r\n// So you have to add in an extra delay equal to fragmentlength.\r\n(\r\n{ |holdlength = 0.5, fragmentlength = 0.2, rate = 1.5|\r\n    var reset, phase, fragment, del, snd;\r\n    snd = Pulse.ar(XLine.kr(100, 1000, 5));\r\n    reset = Impulse.ar(holdlength.reciprocal);\r\n    phase = Sweep.ar(reset);\r\n    fragment = { |ph| (ph - Delay1.ar(ph)) < 0 + Impulse.ar(0) }.value(phase / fragmentlength % 1);\r\n    del = Latch.ar(phase, fragment) + ((fragmentlength - Sweep.ar(fragment)) * (rate - 1));\r\n    snd = DelayC.ar(snd, 10, del);\r\n    snd * 0.1!2;\r\n}.play;\r\n)\r\n\r\n(\r\n~stutter = { |snd, reset, fragmentlength, rate = 1.0, maxdelay = 10|\r\n    var phase, fragment, del;\r\n    phase = Sweep.ar(reset);\r\n    fragment = { |ph| (ph - Delay1.ar(ph)) < 0 + Impulse.ar(0) }.value(phase / fragmentlength % 1);\r\n    del = Latch.ar(phase, fragment) + ((fragmentlength - Sweep.ar(fragment)) * (rate - 1));\r\n    DelayC.ar(snd, maxdelay, del);\r\n};\r\n)\r\n\r\n/*\r\n// put this into your extensions dir to install as a pseudo-ugen\r\nStutter {\r\n    *ar { |in, reset, length, rate = 1.0, maxdelay = 10|\r\n        var phase, fragment, del;\r\n        phase = Sweep.ar(reset);\r\n        fragment = { |ph| (ph - Delay1.ar(ph)) < 0 + Impulse.ar(0) }.value(phase / length % 1);\r\n        del = Latch.ar(phase, fragment) + ((length - Sweep.ar(fragment)) * (rate - 1));\r\n        ^DelayC.ar(in, maxdelay, del);\r\n    }\r\n}\r\n*/\r\n\r\n\r\n\r\n\r\n// Next examples use this buffer\r\nb = Buffer.read(s, Platform.resourceDir +/+ \"sounds/a11wlk01.wav\");\r\n\r\n\r\n// audio-rate stutter inspired by DestroyFX\r\n(\r\n{\r\n    var snd, holdperiod, multiplier;\r\n    snd = PlayBuf.ar(1, b, BufRateScale.kr(b), loop: 1);\r\n    holdperiod = MouseY.kr(0.01, 1.0, 1);\r\n    multiplier = MouseX.kr(1, 20);\r\n    snd = ~stutter.(snd, Impulse.ar(holdperiod.reciprocal), holdperiod / multiplier);\r\n    snd * 0.3!2;\r\n}.play;\r\n)\r\n\r\n// feedback loop inspired by Glitchmachines\r\n(\r\n{\r\n    var in, loop, out;\r\n    in = PlayBuf.ar(1, b, BufRateScale.kr(b), loop: 1);\r\n\tout = (in!2*0.6) + DelayC.ar(LocalIn.ar(2), 0.3, [0.11, 0.13], 0.95);\r\n    loop = out;\r\n    loop = ~stutter.(loop, Impulse.kr([3.4, 5.5]), [0.1, 0.03], [0.8, 1.3]);\r\n    loop = LPF.ar(loop, 5000);\r\n\tLocalOut.ar(loop.reverse);\r\n    out * 0.3;\r\n}.play;\r\n)\r\n)\r\n\r\n// sequencing with Pmono\r\n(\r\nSynthDef(\\stuttertest, {\r\n    |out = 0, buf, t_reset = 0, fragmentlength = 0.1, amp = 0.1|\r\n    var snd;\r\n    snd = PlayBuf.ar(1, buf, BufRateScale.kr(buf), loop: 1);\r\n    snd = ~stutter.(snd, t_reset, fragmentlength);\r\n    Out.ar(out, snd * amp!2);\r\n}).add;\r\n)\r\n(\r\nPmono(\\stuttertest,\r\n    \\buf, b,\r\n    \\amp, 0.3,\r\n    \\reset, 1,\r\n    \\dur, 0.1,\r\n    \\fragmentlength, Pseq([0.01, 0.03, 0.07, 0.05, 0.06], inf)\r\n).play;\r\n)\r\n\r\n// grab audio on onsets\r\n// live performers like this because they can control the effect easily\r\n(\r\n{\r\n    var snd, reset;\r\n    snd = PlayBuf.ar(1, b, BufRateScale.kr(b), loop: 1);\r\n    reset = Onsets.kr(FFT(LocalBuf(512), snd), 0.5);\r\n    snd = ~stutter.(snd, reset, 0.05);\r\n    snd = DelayC.ar(snd, 0.2, 0.2);\r\n    snd!2 * 0.3;\r\n}.play;\r\n)\r\n\r\n// \"scrambler\" -- randomly samples from recent audio\r\n// even simpler than stutter, a favorite effect of mine\r\n(\r\n{\r\n    var snd;\r\n    snd = PlayBuf.ar(1, b, BufRateScale.kr(b), loop: 1);\r\n    snd = DelayC.ar(snd, 1.0, LFNoise0.ar(13).range(0.0, 1.0));\r\n    snd!2 * 0.3;\r\n}.play;\r\n)\r\n\r\n/*\r\nSome other options to try out:\r\nBreakcore ugen in sc3-plugins\r\nBBCut quark (see CutStream* classes for real-time stutter)\r\n*/",
   "name" : "Stutter tutorial",
   "author" : "snappizz",
   "ancestor_list" : [],
   "description" : "Stutter effects grab a small segment of live audio and play it back. It is a popular effect in electronic music, independently invented and developed in various ways by audio plugin developers. Here's how to do it in SuperCollider."
}
