This can probably be made a bit spiffier (I’d appreciate suggestions), but the basic idea:
(SynthDef(\beep, {
var out = \out.ir(0), amp = \amp.kr(0.5), freq = \freq.kr(440);
ReplaceOut.ar(out, amp * SinOsc.ar(freq).dup);
}).add;)
c = Bus.control(s, 1);
(SynthDef(\menv, {
var bus = \bus.ir(c), atk = \atk.kr(0.15), rls = \rls.kr(0.5), gate = \gate.kr(1);
var insig = In.kr(bus), env = EnvGen.kr(Env.asr(atk, 1, rls, 0), gate, doneAction:2);
var eSlopesDown = (HPZ1.kr(env) < 0), outsig = eSlopesDown.if(env, max(insig, env));
ReplaceOut.kr(bus, outsig);
}).add;)
x = Synth(\beep); // perma running
x.map(\amp, c);
p = Pbind(\instrument, \menv, \addAction, 1, \dur, Pseq([1], 5), \legato, Pseq([0.5, 0.7, 0.9, 1, 1])).play;
The slopes are constant, as I desired. The “gap” between the \legato = 1 events is exactly the length of an “attack”, i.e. atk, although it’s part-release and part attack (due to taking the max between them).
To make Pmono style “full” legato with this code/approach, I need to set \sustain > \dur + atk, e.g.
p = Pbind(\instrument, \menv, \addAction, 1, \dur, Pseq([1], 4), \sustain, Pseq([1.10, 1.15, 1.2, 1])).play;

