Trigger an Ndef within a pattern

I’m trying to understand how to use Ndefs in combination with patterns and events to control a SynthDef. I’m new to the Ndef paradigm so this might be an obvious one or just my summer-brain being slow, but i couldn’t find it in the docs.

I really like that you can combine pattern control and plug in Ndef’s as LFO’s directly into the pattern, but i fail to understand why the Ndef(\env) in this example doesn’t re-trigger on each event:

SynthDef(\syn, {|out, freq, amp, gate = 1, filterFreq = 2700, pan = 0|
	var env, sig;
	env = EnvGen.kr(Env.adsr(0, 0.1, 0.6, 0.6), gate, doneAction: 2);
	sig = RLPF.ar(Saw.ar(freq, amp * env), filterFreq.clip(20, 20000), 0.2);
	sig = Pan2.ar(sig, pan);
	Out.ar(out, sig);
}).add;

(
Ndef(\x).play(vol: 1.0);
Ndef(\lfo, {|lfoFreq = 1.5| SinOsc.kr(lfoFreq).exprange(900, 1800)});
Ndef(\env, {|gate = 1, offset = 900| EnvGen.kr(Env.perc(0.01, 0.5, 3600 + offset), gate, 2.0, -0.5, doneAction: 2) + offset});

Pdef(\ptn, 
	Pbind(
		\instrument, \syn,
		\degree, Pseq([[0, 2, 5], [-2, 0, 2], [-5, -2, 2]], inf),
		\strum, Pwhite(0.02, 0.05),
		\mtranspose, Pdup(5, Pseq([0, -2, -5, 2, 0, -2, 5, 2, 3, -3], inf)),
		\filterFreq, Pfunc{|ev| Ndef(\lfo).set(\lfoFreq, ev.degree[rrand(0, 2)])},
		//\filterFreq, Pfunc{Ndef(\env)}, // how to trigger it?
		\dur, Pwhite(0.45, 0.54),
		\amp, Pwhite(0.08, 0.15),
		\out, Pfunc{Ndef(\x).bus.index},
		\group, Pfunc({Ndef(\x).group})
	)
).play;
)
Pdef(\ptn).stop;

Another cool thing you can do is pop a pattern into an Ndef and use that to control it using nodeproxy roles

https://doc.sccode.org/Reference/NodeProxy_roles.html

a = NodeProxy(s);
a[0] = { |freq = 440, dt=0.1, rate=2| Ringz.ar(Impulse.ar(rate * [1, 1.2]), freq, dt)*0.1 };
a.play;

(
a[1] = \pset -> Pbind(
    \dur, Prand([1, 0.5], inf),
    \freq, Pwhite(200.0, 1000, inf).round(30),
    \rate, Pdup(4, Prand([1, 3, 6, 10], inf)),
    \dt, Pwhite(0.01, 0.1, inf) + 1
)
);

a.nodeMap.postln; // the values are set in the node map.
3 Likes

Very cool indeed! Thanks! I also watched your great Ndef-tutorial this morning.
Maybe my approach is a bit backwards within the NodeProxy paradigm, but i’m working on a larger instrument (basically trying to convince myself that i don’t need a 3rd Wave or a Prophet VS synth, because i can build it in SuperCollider, hehe…). It’s basically a class that returns a SynthDef and i want to keep the interface open for different styles of live coding as well as attaching midi controllers and such.

But still, if anyone can explain why the envelope Ndef fails to retrig on each event in the example above i would be grateful.

I’m not sure if this would work for you (and perhaps there’s a more NodeProxy-idiomatic way of doing this), but a way around it would be to not free the Ndef with doneAction: 2, but instead let it play and control the envelope by setting a trigger-rate control in each event:

(
Ndef(\x).play(vol: 1.0);
Ndef(\lfo, {|lfoFreq = 1.5| SinOsc.kr(lfoFreq).exprange(900, 1800)});
Ndef(\env, {|offset = 900| var gate = \trig.tr(0); EnvGen.kr(Env.perc(0.01, 0.5, 3600 + offset), gate, 2.0, -0.5) + offset});

Pdef(\ptn, 
	Pbind(
		\instrument, \syn,
		\degree, Pseq([[0, 2, 5], [-2, 0, 2], [-5, -2, 2]], inf),
		\strum, Pwhite(0.02, 0.05),
		\mtranspose, Pdup(5, Pseq([0, -2, -5, 2, 0, -2, 5, 2, 3, -3], inf)),
		\filterFreq, Pfunc{Ndef(\env).set(\trig, 1)},
		\dur, Pwhite(0.45, 0.54),
		\amp, Pwhite(0.08, 0.15),
		\out, Pfunc{Ndef(\x).bus.index},
		\group, Pfunc({Ndef(\x).group})
	)
).play;
)

Thanks! This solves this example at least. But it seems to imply that we can’t have gated Ndefs in patterns? Because if there’s a \gate.kr without a doneAction: 2 in the Ndef it complains:

WARNING: The gate control should be able to free the synth!

gate is reserved for Ndef’s control over the synth node. You shouldn’t use it for retriggering.

I’ve sometimes used gt for this purpose (although the default event prototype won’t generate gate-off automatically in that case).

Perhaps JITLib should have used a name other than gate for its internal use, but changing it would break compatibility.

hjh