Ok, here you go!
The following concerns only synths that come from the tidal "sound"
function (not global effect synths like # delay
, that are handled differently).
-
In superdirt, the freeing of synths is done by one internal synth that makes the end of the chain of effects. It is the
dirt_gate
synth. Its definition is incore-synths.scd
. I posted it below [1]. It applies a minimal envelope to the whole event (including all the effects you applied to it). ThedoneAction: 14
is called after this envelope is completed. By setting thefadeInTime
andfadeTime
parameters in tidal, you can harden or soften the attack/decay.
This means that you can makeSynthDef
s with synths that do not release themselves, something we normally avoid in supercollider, because you'd pile up synths endlessly. But here, you could simply define a synth like this:
SynthDef(\mess, { |out| Out.ar(out, GrayNoise.ar) }).add
and you could play it in tidal with:sound "mess"
. The synths are freed by thedirt_gate
synth. -
But usually, you want a synth to have a particular amplitude envelope. Then you can define one in your SynthDef, see below [2]. Note that
sustain
means the duration of the whole synth (this is what it is called in SuperCollider in general), which is sent over from tidal (for setting it directly, try# sustain "0.1 0.3 0.5 1"
). Then you can have adoneAction: 2
if you like (this will free the synth after the envelope is done), but you can also leave thisdoneAction
out altogether, because the synth is freed externally anyhow. For example:SynthDef(\mess, { |out, sustain = 0.2| Out.ar(out, GrayNoise.ar * XLine.kr(1, 0.001, sustain)) }).add
But sometimes, you may want to use the synth outside superdirt, and then it is polite that it cleans up after itself. Just make sure that you multiply your envelope with the audible signal, otherwise you'll hear clicks at the end of each synth.
SynthDef(\mess, { |out, sustain = 0.2| Out.ar(out, GrayNoise.ar * XLine.kr(1, 0.001, sustain, doneAction: 2)) }).add
Hope this helps!
[1]
SynthDef("dirt_gate" ++ numChannels, { |out, in, sustain = 1, fadeInTime = 0.001, fadeTime = 0.001, amp = 1|
var signal = In.ar(in, numChannels);
// doneAction: 14: free surrounding group and all nodes
var env = EnvGen.ar(Env([0, 1, 1, 0], [fadeInTime, sustain, fadeTime], \sin), levelScale: amp, doneAction: 14);
signal = signal * env * DirtGateCutGroup.ar(fadeTime, doneAction: 14);
OffsetOut.ar(out, signal);
ReplaceOut.ar(in, Silent.ar(numChannels)) // clears bus signal for subsequent synths
}, [\ir, \ir, \ir, \ir, \ir, \ir]).add;
[2]
(
SynthDef(\imp, { |out, sustain = 1, freq = 440, speed = 1, begin=0, end=1, pan, accelerate, offset|
var env, sound, rate, phase;
env = EnvGen.ar(Env.perc(0.01, 0.99, 1, -1), timeScale:sustain, doneAction:2);
phase = Line.kr(begin, end, sustain);
rate = (begin + 1) * (speed + Sweep.kr(1, accelerate));
sound = Blip.ar(rate.linexp(0, 1, 1, freq) * [1, 1.25, 1.51, 1.42], ExpRand(80, 118) * phase).sum;
OffsetOut.ar(out,
DirtPan.ar(sound, ~dirt.numChannels, pan, env)
)
}).add
);