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