Looping rhythms and samples with the lplay
SynthDef
A part of rhythmic electronic music that SuperCollider isn't so great at dealing with are loops. In the Pattern library there isn't a defaulting to 'loop'-based musical structures as is the default in DAW environments such as Ableton live.
This is of course extremely powerful, but sometimes for more complex rhythmic forms, loops are a reasonable practical substitute.
I use loops particularly when there are some rhythms that I find hard to articulate by specifying duration values - an example being the classic Amen Break when I'm trying to make some fast Drum-and-bass style music.
For this, I wrote lplay
, a variation on the bplay
Synthdef that is ubiquitous in my Live Coding setup.
(
SynthDef(\lplay,
{arg out = 0, buf = 0, amp = 0.5, pan = 0 rel=15, dur = 8;
var sig,env ;
sig = Mix.ar(PlayBuf.ar(2,buf,BufRateScale.ir(buf) * ((BufFrames.ir(buf)/s.sampleRate)*p.clock.tempo/dur),1,0,doneAction:2));
env = EnvGen.ar(Env.linen(0.0,rel,0),doneAction:2);
sig = sig * env;
sig = sig * amp;
Out.ar(out,Pan2.ar(sig,pan));
}).add;
)
lplay
takes a dur
value and plays a buffer exactly over the time period speficied by the dur
value. For example, if you have a 8 beat drum loop, and you created this Pbind
:
p.clock.tempo = 175/60
~loop = Pbind(\instrument,\lplay,\buf,d["breaks175"][0],\dur,16)
The loop would play over 8 cycles of the ProxySpace
TempoClock
(p.clock.tempo). This is achieved by using this equation for the rate
control:
((BufFrames.ir(buf)/s.sampleRate)*p.clock.tempo/dur)
Note that the looping is tied to the rate of playback, so the faster the tempo, the faster the sample will be played. If you try and play a 120bpm sample at 175bpm, it will sound very high-pitched! - Be aware of this when using it during performance.
An important note is that you will have to reload the synthdef when the tempo is changed if you want looping to work with the updated tempo