{
   "labels" : [
      "beat slicer"
   ],
   "is_private" : null,
   "id" : "1-50R",
   "code" : "/**********************************\r\nYou can download a free drum loop from:\r\nhttps://freesound.org/people/pushtobreak/sounds/5647/\r\n***********************************/\r\n(\r\nSynthDef(\\smplr_m3, {arg startPos = 0, buf, rate = 1, loop = 1,\r\n\tatk = 0.005, rel = 0.005, curve = 0, dur = 0.1,\r\n\tamp = 0.5, out = 0, pan = 0;\r\n\r\n\tvar env, sig;\r\n\tenv= Env([0,1,1,0], [atk, dur-atk-rel, rel], curve).ar(doneAction:2);\r\n\tsig = PlayBuf.ar(numChannels: 1, bufnum: buf, rate: BufRateScale.kr(buf) * rate, startPos: startPos, loop: loop);\r\n\tsig = sig * env * amp;\r\n\tOffsetOut.ar(out, Pan2.ar(sig, pan));\r\n}).add;\r\n)\r\n\r\n(\r\n// Logic for providing slices to the queue\r\n~sliceProducer = {arg count, slices, beats, queue;\r\n\r\n\tvar pos = count % beats;\r\n\tvar delta = (slices/beats).reciprocal;\r\n\tvar slice = (count/delta % slices);\r\n\tvar event = (delta:delta, slice:slice);\r\n\tvar rem = (beats - pos);\r\n\r\n\tif (0.2.coin && (rem <= 1) ) {\r\n\r\n\t\tvar div = delta/2;\r\n\t\tvar event = (delta:div, slice:slice);\r\n\t\t2.do({\r\n\t\t\tqueue.add(event);\r\n\t\t});\r\n\t} {\r\n\t\tif (pos == 0) {\r\n\t\t\tevent[\\slice] = 0;\r\n\t\t\tqueue.add(event);\r\n\t\t} {\r\n\t\t\tevent[\\slice] = (0..slices-1).choose;\r\n\t\t\tqueue.add(event);\r\n\t\t}\r\n\t};\r\n};\r\n\r\n// main interface\r\n~slcr = {arg buf, beats = 8, beatDiv = 2, sliceProducer, amp = 0.1, clock = TempoClock.default;\r\n\r\n\t// buffer info\r\n\tvar numFrames = buf.numFrames;\r\n\tvar sampleRate = buf.sampleRate;\r\n\r\n\t// length in seconds of sample\r\n\tvar len = numFrames/sampleRate;\r\n\r\n\t// beats per second\r\n\tvar bps = beats/len;\r\n\r\n\t// number of slices\r\n\tvar slices = beats * beatDiv;\r\n\r\n\t// frames per slice\r\n\tvar fps = numFrames/slices;\r\n\r\n\t// yields slice data to the pattern\r\n\tvar rtn = Routine({\r\n\r\n\t\tvar queue = LinkedList.new;\r\n\t\tvar count = 0;\r\n\r\n\t\tinf.do({arg i;\r\n\r\n\t\t\tvar event;\r\n\r\n\t\t\tif (queue.isEmpty) {\r\n\t\t\t\tsliceProducer.value(count, slices, beats, queue);\r\n\t\t\t};\r\n\r\n\t\t\tevent = queue.popFirst;\r\n\t\t\tcount = count + event[\\delta];\r\n\t\t\t[event[\\delta], event[\\slice] * fps].yield;\r\n\t\t});\r\n\t});\r\n\r\n\t// return the pattern\r\n\tPbind(\\instrument, \\smplr_m3,\r\n\t\t[\\delta, \\startPos], rtn,\r\n\t\t\\buf, buf,\r\n\t\t\\rate, Pfunc({ clock.tempo }) / bps,\r\n\t\t\\amp, amp,\r\n\t\t\\dur, Pfunc({ clock.beatDur }) * Pkey(\\delta)\r\n\t);\r\n};\r\n)\r\n\r\n(\r\nTempoClock.default.tempo_(2);\r\n~buf = Buffer.read(s, \"/path/to/mono/soundfile\");\r\n)\r\n\r\n(\r\nNdef(\\out).clear;\r\nNdef(\\out).play;\r\nNdef(\\out)[0] = ~slcr.(buf: ~buf, beats: 4, beatDiv: 2, sliceProducer: ~sliceProducer, amp: 0.5);\r\nNdef(\\out)[10] = \\filter -> {arg in; FreeVerb.ar(in, 0.3, 0.5); };\r\n)",
   "author" : "david_morgan",
   "name" : "Simple pattern-based beat slicer",
   "ancestor_list" : [],
   "description" : "Revised: Made some improvements from previous submission. \r\n\r\nI hadn't really come across a simple self-contained example to use with patterns. \r\n\r\nYou can download a free drum loop from:\r\nhttps://freesound.org/people/pushtobreak/sounds/5647/"
}
