{
   "description" : "PlayBuf, granular sampling, Pbind, fork, TGrains",
   "ancestor_list" : [],
   "author" : "Bruno Ruviaro",
   "name" : "Granular Sampling demo [no GUI]",
   "id" : "1-5aX",
   "is_private" : null,
   "code" : "//////////////////////\r\n// GRANULAR SAMPLING\r\n// Code examples\r\n//////////////////////\r\n\r\n// Replace path (a string of characters) with a path to a wav or aiff file on your computer \r\nb = Buffer.readChannel(server: s, path: \"/home/sclork/Downloads/wheels-mono.wav\", channels: [0]);\r\n\r\n// Load synthdef\r\n(\r\nSynthDef(\"grain-asr\", {arg buffer, rate = 1, startPos = 0, gate = 1, att = 0.01, rel = 0.1, amp = 1, pan = 0;\r\n\tvar env, snd;\r\n\tenv = Env.asr(att, amp, rel).kr(gate: gate);\r\n\tsnd = PlayBuf.ar(\r\n\t\tnumChannels:  1,\r\n\t\tbufnum:  buffer,\r\n\t\trate: rate,\r\n\t\tstartPos: startPos * BufSamples.kr(buffer)\r\n\t);\r\n\tsnd = snd * env;\r\n\tOut.ar(0, Pan2.ar(snd, pan));\r\n\tDetectSilence.ar(snd, doneAction: 2);\r\n}).add;\r\n)\r\n\r\n// ===================\r\n// Pattern examples\r\n// Note that in these examples grain duration is controlled indirectly through \\dur, \\legato, and \\release\r\n// Also because we are using Pbinds there is a limit on how many grains you can play per second\r\n\r\n(\r\n~stubborn = Pbind(\r\n\t\\instrument, \"grain-asr\",\r\n\t\\buffer, b,\r\n\t\\startPos, Pseq([Pn(0.1, 10), Pn(0.3, 10), Pn(0.8, 5)], inf), // 0.0=beginning of sample, 0.5=half way into sample, 1.0=end of sample\r\n\t\\dur, 0.1,\r\n\t\\att, 0.001,\r\n\t\\rel, 0,\r\n\t\\rate, 1, //Pwhite(1, 1.5), // 1=original speed, 0.5=half speed, 2=twice speed, etc.\r\n\t// a negative number for \\rate makes sound goes backward\r\n\t\\amp, 0.5,\r\n\t\\pan, Pwhite(-1.0, 1.0),\r\n\t\\legato, 1\r\n).play.stop;\r\n\r\n~stubborn.play;\r\n)\r\n\r\n\r\n(\r\n~go = Pbind(\r\n\t\\instrument, \"grain-asr\",\r\n\t\\buffer, b,\r\n\t\\startPos, 0.1, // 0.0=beginning of sample, 0.5=half way into sample, 1.0=end of sample\r\n\t\\dur, 2,\r\n\t\\att, 0.001,\r\n\t\\rel, 1,\r\n\t\\rate, Pwhite(1, 1.5), // 1=original speed, 0.5=half speed, 2=twice speed, etc.\r\n\t// a negative number for \\rate makes sound goes backward\r\n\t\\amp, 0.75,\r\n\t\\pan, Pwhite(-1.0, 1.0),\r\n\t\\legato, 1\r\n).play.stop;\r\n\r\n~go.play;\r\n)\r\n\r\n(\r\n~rhythm = Pbind(\r\n\t\\instrument, \"grain-asr\",\r\n\t\\buffer, b,\r\n\t\\startPos, Pseq([0.04, 0.12, 0.215, 0.78], inf),\r\n\t\\dur, 1/4,\r\n\t\\att, 0.001,\r\n\t\\rel, 0.01,\r\n\t\\rate, -1, // normal speed, but reverse\r\n\t\\amp, 0.75,\r\n\t\\pan, Pwhite(-1.0, 1.0),\r\n\t\\legato, 0.7\r\n).play.stop;\r\n\r\n~rhythm.play;\r\n)\r\n\r\n(\r\n~allOver = Pbind(\r\n\t\\instrument, \"grain-asr\",\r\n\t\\buffer, b,\r\n\t\\startPos, Pseq([0.4, 0.32, 0.6215, 0.8], inf) + Pwhite(0.0, 0.05),\r\n\t\\dur, 1/4,\r\n\t\\att, 0.001,\r\n\t\\rel, 1,\r\n\t\\rate, Prand([Pn(-2, 4), 1, -4], inf),\r\n\t\\amp, Pwhite(0.5, 0.75),\r\n\t\\pan, Pwhite(-0.3, 0.3),\r\n\t\\legato, 0.1\r\n).play.stop;\r\n\r\n~allOver.play;\r\n)\r\n\r\n(\r\n~upAndAway = Pbind(\r\n\t\\instrument, \"grain-asr\",\r\n\t\\buffer, b,\r\n\t\\startPos, Prand([0.44, 0.32, 0.6215, 0.8], inf),\r\n\t\\dur, Pwhite(1/16, 1/17),\r\n\t\\att, 0.001,\r\n\t\\rel, 0.01,\r\n\t\\rate, Pn(Pgeom(1, 1.1, 20)),\r\n\t\\amp, Pwhite(0.2, 0.75),\r\n\t\\pan, Pwhite(-1.0, 1.0),\r\n\t\\legato, 1\r\n).play.stop;\r\n\r\n~upAndAway.play;\r\n)\r\n\r\n(\r\n~shorty = Pbind(\r\n\t\\instrument, \"grain-asr\",\r\n\t\\buffer, b,\r\n\t\\startPos, Pwhite(0.0, 0.1),\r\n\t\\dur, 1/20,\r\n\t\\att, 0.001,\r\n\t\\rel, 0.1,\r\n\t\\rate, Pseq([1, 5, 3, 3.3], inf),\r\n\t\\amp, Pwhite(0.5, 0.95),\r\n\t\\pan, Pwhite(-1.0, 1.0),\r\n\t\\legato, Pn(Pgeom(0.01, 1.05, 40))\r\n).play.stop;\r\n\r\n~shorty.play;\r\n)\r\n\r\n(\r\n~kik = Pbind(\r\n\t\\instrument, \"grain-asr\",\r\n\t\\buffer, b,\r\n\t\\startPos, 0.1,\r\n\t\\dur, 1/8,\r\n\t\\att, 0.001,\r\n\t\\rel, 0.1,\r\n\t\\rate, 0.2,\r\n\t\\amp, Pseq([\r\n\t\t1, 0, 0, 0, 1, 0, 0, 0\r\n\t], inf),\r\n\t\\pan, 0,\r\n\t\\legato, 0.1\r\n).play.stop;\r\n\r\n~kik.play;\r\n)\r\n\r\n(\r\n~snair = Pbind(\r\n\t\\instrument, \"grain-asr\",\r\n\t\\buffer, b,\r\n\t\\startPos, 0.49,\r\n\t\\dur, 1/8,\r\n\t\\att, 0.001,\r\n\t\\rel, 0.13,\r\n\t\\rate, 1,\r\n\t\\amp, Prand([\r\n\t\tPseq([0, 0, 1, 0, 0, 0, 1, 0], 2),\r\n\t\tPseq([0, 0, 1, 0, 0, 1, 1, 0], 1),\r\n\t\tPseq([0, 0, 1, 0, 0, 0, 1, 1], 1)\t\r\n\t], inf),\r\n\t\\pan, 0,\r\n\t\\legato, 0.2\r\n).play.stop;\r\n\r\n~snair.play;\r\n)\r\n\r\n(\r\n~helloHat = Pbind(\r\n\t\\instrument, \"grain-asr\",\r\n\t\\buffer, b,\r\n\t\\startPos, 0.78,\r\n\t\\dur, 1/16,\r\n\t\\att, 0.001,\r\n\t\\rel, Pwhite(0.1, 0.2),\r\n\t\\rate, Pwhite(4, 4.1),\r\n\t\\amp, Prand([\r\n\t\tPseq([0, 1, 0, 1, 0, 1, 0, 1], 2),\r\n\t\tPseq([0, 1, 1, 1, 0, 1, 1, 1], 1),\r\n\t\tPseq([0, 1, 1, 1, 0, 1, 1, 1], 1)\t\r\n\t], inf) * Pwhite(0.25, 0.5),\r\n\t\\pan, 0,\r\n\t\\legato, 0.2\r\n).play.stop;\r\n\r\n~helloHat.play;\r\n)\r\n\r\n\r\n// quick .fork example\r\n(\r\n~bpm = TempoClock.new(60/60).permanent_(true);\r\n{\r\n\t~snair.reset.play(~bpm);\r\n\t~kik.reset.play(~bpm);\r\n\t~helloHat.reset.play(~bpm);\r\n\t8.wait;\r\n\t~shorty.reset.play(~bpm);\r\n\t4.wait;\r\n\t~shorty.stop;\r\n\t~stubborn.reset.play(~bpm);\r\n\t4.wait;\r\n\t~stubborn.stop;\r\n\t4.wait;\r\n\t~upAndAway.reset.play(~bpm);\r\n\t4.wait;\r\n\t~rhythm.reset.play(~bpm);\r\n\t4.wait;\r\n\t~snair.stop;\r\n\t~kik.stop;\r\n\t~helloHat.stop;\r\n\t4.wait;\r\n\t~upAndAway.stop;\r\n\t~rhythm.stop;\r\n\t~go.reset.play(~bpm);\r\n\t8.wait;\r\n\t~go.stop;\r\n}.fork(~bpm);\r\n)\r\n\r\n\r\n\r\n// ===============================\r\n// Another approach: TGrains\r\n// (using Ndef for live coding)\r\n// ===============================\r\n\r\n(\r\nNdef(\\tgrains, { \r\n\t\r\n\tvar trigRate, rate, snd, centerPos;\r\n\t\r\n\t// mouse movement X and Y:\r\n\ttrigRate = MouseY.kr(2, 200, 1);\r\n\tcenterPos = MouseX.kr(0, BufDur.kr(b));\r\n\t\r\n\t// try out various 'rate' lines \r\n\t// (bottom most line to be uncommented will be the one running)\r\n\t//\r\n\t// rate = Dseq([10, 1, 1, 0.5, 0.5, 0.2, 0.1], inf);\r\n\t// rate = Dseq([1, 1, 1, 1, 2, 4, 8], inf);\r\n\trate = Drand([0.5, 1, 1, 2, 4, 8], inf);\r\n\t// rate = SinOsc.ar(1/3).range(0.5, 1);\r\n\t// rate = LFNoise0.ar(5).range(0.5, 2);\r\n\t// rate = LFSaw.ar(1).range(1/5, 1);\r\n\t\r\n\tsnd = TGrains.ar(\r\n\t\tnumChannels: 2,\r\n\t\ttrigger: Impulse.ar(trigRate),\r\n\t\tbufnum: b,\r\n\t\trate: rate,\r\n\t\tcenterPos: centerPos,\r\n\t\tdur: 4 / trigRate,\r\n\t\tpan: Dseq([-1, 1], inf),\r\n\t\tamp: 0.2,\r\n\t\tinterp: 2\r\n\t);\r\n\t\r\n\tsnd = FreeVerb.ar(\r\n\t\tin: snd, \r\n\t\tmix: 0.14, \r\n\t\troom: 0.5, \r\n\t\tdamp: 0.5\r\n\t);\r\n\t\r\n}).play;\r\n)",
   "labels" : [
      "granular sampling"
   ]
}
