Really nice !
For example, instead of sending your Synths to the bus 0, you could send them to a separated “Mixer” Synth with a nice release time that you could release while playing your pattern.
E.g.
// An audio bus that will receive the Synths output
~channel=Bus.audio(s,2);
// A mixer that will push the Synths output to a physical output
// With a 3 second release time.
SynthDef(\mixall,{ |in=0, out=0|
var sig=In.ar(in,2);
var env=EnvGen.kr(Env.asr(0,1,3,\lin),\gate.kr(1), doneAction:2);
sig=sig*env;
ReplaceOut.ar(out,sig);
}).add;
// A pattern, which output is the audio bus and that must be placed **before**the mixer
p=Pbind(\dur, 0.5, \degree, Prand(Scale.lydianMinor.degrees,16), \before,~mixer, \out,~channel);
(
~mixer=Synth(\mixall,[\in,~channel,\out,0]);
Pseq([p,
// at the last occurrence, trigger in parallel, while playing, a "\off" message on the mixer to release it
Ppar([
// debug
Pbind(\type, \rest, \dur, Pfuncn({"Releasing...".postln; 1},1)),
// release the mixer ...
Pbind(\type, \off, \id, ~mixer.nodeID, \dur, Pn(1,1) ),
// ... while playing
p
])
]).play;
)
If you don’t want to modify all your patterns by adding \before
and \out
, you can write it like this:
p=Pbind(\dur, 0.5, \degree, Prand(Scale.lydianMinor.degrees,16));
m=Pseq([p,
Ppar([
// debug
Pbind(\type, \rest, \dur, Pfuncn({"Releasing...".postln; 1},1)),
// release the mixer ...
Pbind(\type, \off, \id, ~mixer.nodeID, \dur, Pn(1,1) ),
// ... while playing
p
])
]);
// adding \before and \out to the pattern beford playing it
Pfset({~before=topEnvironment[\mixer] ; ~out=topEnvironment[\channel]},m).play;