This is a combined special demand, but afaics everything seems doable. I’m starting with envelopes as this is more straight.
To be honest I couldn’t tell at a glance too but the cleanup mechanism isn’t bound to envelopes, so fxs can take over this job.
(
SynthDef(\source_no_env, { |out = 0, freq = 400,
attackTime = 0.005, amp = 0.1, gate = 1|
var env, sig = Saw.ar(freq, amp);
Out.ar(out, sig ! 2)
}).add;
SynthDef(\wah_env, { |out, in, att = 0.01, rel = 0.5, resLo = 200, resHi = 5000,
cutOffMoveFreq = 0.5, rq = 0.1, amp = 1, mix = 1|
var sig, inSig = In.ar(in, 2), env;
sig = RLPF.ar(
inSig,
LinExp.kr(LFDNoise3.kr(cutOffMoveFreq), -1, 1, resLo, resHi),
rq,
amp
).softclip;
env = EnvGen.ar(Env.perc(att, rel, amp), doneAction: 2);
Out.ar(out, ((1 - mix) * inSig + (sig * mix)) * env);
}).add;
)
// overlapped events with different release times
(
p = PbindFx([
\instrument, \source_no_env,
\dur, 0.25,
\amp, 1,
\midinote, Pwhite(50, 90),
\fxOrder, 1,
\cleanupDelay, 0
],[
\fx, \wah_env,
\mix, Pseq([0.2, 0.5, 0.7], inf),
\cutOffMoveFreq, Pseq([1, 2, 5, 10], inf),
\rel, Pwhite(0.1, 2),
\amp, 0.2,
\cleanupDelay, Pkey(\rel)
]
);
q = p.play;
)
Concerning the second demand, PbindFx is using its own event type based on ‘note’. However you are not the first to ask for different event types and this can be done by routing. In your use case a router synth can read from a bus where the monophonic one is playing to.
Of course there’s a fundamental difference to the first example: no overlapping as source is monophonic. However overlappings caused by fxs (echo, reverb) would be possible also in this case.
// synth for routing
(
SynthDef(\router, { |out = 0, inBus|
Out.ar(out, In.ar(inBus, 2))
}).add;
a = Bus.audio(s, 2);
)
(
// groups to ensure node order
g = Group.new;
h = Group.after(g);
// start silently in group g
x = Synth(\source_no_env, [amp: 0, out: a], g);
)
// play monophonic and PbindFx in parallel
// a random rhythm makes data sharing necessary
(
p = Pbind(
\type, \set,
\ids, x.nodeID,
// data sharing, router should get durs from monophonic
\dur, Prand([1, 1, 2] / 4, inf).collect(~d=_),
\args, #[freq, amp],
\freq, Pwhite(50, 90).midicps,
\amp, 0.1
);
q = PbindFx([
\instrument, \router,
// you have to allow reading from other buses
\otherBusArgs, #[inBus],
\inBus, a,
\dur, Pfunc { ~d },
\fxOrder, 1,
\group, h
],[
\fx, \wah_env,
\mix, Pseq([0.2, 0.5, 0.7], inf),
\cutOffMoveFreq, Pseq([1, 2, 5, 10], inf),
// longer release times would be longer than source
\rel, Pwhite(0.03, Pfunc { ~d }),
\cleanupDelay, Pkey(\rel)
]
);
// time shift because of data sharing
q = Ptpar([0, p, 0.0001, q]).play;
)