«Simple pattern-based beat slicer» by david_morgan
on 24 Jan'16 22:00 inRevised: 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/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
/********************************** 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); }; )
reception
comments