What you intend is possible, it just works a bit different from how you described it. Env is a language thing, the server can only deal with array args. So all boils down to a topic that comes up in a variety of ways: building a synthdef that can deal with arrays up to a predefined max size.
This is Ex. 4 of miSCellaneous_lib’s tutorial “Event patterns and array args”, sequencing Envs of different length.
(
// NamedControl is recommended in that case as a literal Array of special format would be impractical.
// Define a SynthDef with maximum envelope size you expect to pass
SynthDef(\envArray_1, { |out = 0, freq = 440, amp = 0.1, timeScale = 1, gate = 1|
var sig, env, envArray, envSig;
envArray = Env([0, 1, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0]).asArray; // works also without '.asArray'
env = \env.kr(envArray); // shortcut for NamedControl.kr(\env, envArray)
envSig = EnvGen.kr(env, gate, timeScale: timeScale, doneAction: 2);
sig = Saw.ar([freq, freq * 2.01], amp);
Out.ar(out, sig * envSig)
}).add
)
// Pbind uses event type \on to avoid setting gate to 0 and receiving messages "node not found",
// synths are ended by envelopes anyway.
(
p = Pbind(
\type, Pshuf([\on, \on, \rest], inf),
\instrument, \envArray_1,
\dur, Pn(Pshuf([1, 1/2, 1/2]), 30),
\midinote, Pn(Pshuf((40..80))) + Pn(Pshuf([[0.5, 11.5], [0, 4], [0, -7], [-0.5, -9.5]])),
// envData contains env types, determined by levels and times.
// Times are only relations, within the synthdef they are scaled by the timeScale arg.
\envData, Pn(Pshuf([
[[0, 1, 0], [1, 1]],
[[0, 1, 1/4, 1, 0], [1, 1, 1, 1]],
[[0, 1, 1/4, 1, 1/4, 1, 0], [1, 1, 1, 1, 1, 1]]
])),
// *x splits the envData array into levels and times, Env is converted in to an Array automatically
\env, Pkey(\envData).collect { |x| Env(*x) },
// when wanting to pass the Array explicitely it would require
// wrapping into an additional Array which is necessary for passing:
// \env, Pkey(\envData).collect { |x| [Env(*x).asArray] },
\timeScale, Pfunc { |e| e.dur / e.envData[1].sum }
).trace.play;
)
p.stop;
For inverting an envelope, I’m not aware of an existing tool, you could write a little helper function using the reverse method for arrays.