(
SynthDef(\saw, {
var sig, env;
env = Env.adsr().kr(gate:\gate.kr(1), doneAction:2);
sig = LPF.ar(Saw.ar(\freq.kr, env), (1 + \filt.kr) * 2000);
Out.ar(\out.kr, sig);
}).add;
SynthDef(\pulse, {
var sig, env;
env = Env.adsr().kr(gate:\gate.kr(1), doneAction:2);
sig = LPF.ar(Pulse.ar(\freq.kr, env, env), (1 + \filt.kr) * 600);
Out.ar(\out.kr, sig);
}).add;
Pdef(\rotate, Pbind(\filt, Penv([-0.5, 1.4, -0.5] + 0.5, [30, 30], \sin).repeat));
Pdef(\pattern, Pdef(\polyInst) <> Pbind(
\instrument, Pseq([ \saw, [\pulse, \saw], \pulse], inf),
\noteBase, Pstutter(16, Pseq([0, -2, -1.5, 4.05, 7], inf)),
\noteOffset, Pseq([2, 4, 9], inf),
\note, Ptuple([Pkey(\noteBase), Pkey(\noteBase) + Pkey(\noteOffset)]),
\dur, 0.25,
\legato, 2
) <> Pdef(\rotate)).play;
)
The question is, what is Pdef(\polyInst)
? In other words, can you have a mix-in Pbind that enables polyphonic instrument parameters “naturally” without using Ppar
or creating a new event type from scratch (with the requisite code duplication, potential for changed behavior, etc)…
Considering the amount of time I’ve spent trying to crack this one, I’m pretty happy that this thread rattled loose whatever final neuron was required.
the answer below.....
Pdef(\polyInst, Pbind(
\getMsgFunc, {
|instrument|
var funcs;
if (instrument.isKindOf(Array)) {
funcs = instrument.collect({
|i|
Event.parentEvents[\default][\getMsgFunc].value(i)
});
~instrument = instrument;
{
funcs.collect({
|f|
f.valueEnvir
}).flop
}
} {
Event.parentEvents[\default][\getMsgFunc].value(instrument)
};
},
\synthDefName, {
if (~instrument.isArray) {
var collectedInstruments, instrument = ~instrument;
collectedInstruments = instrument.collect({
|i|
~instrument = i;
Event.parentEvents[\default][\synthDefName].valueEnvir;
});
~instrument = instrument;
collectedInstruments;
} {
Event.parentEvents[\default][\synthDefName].valueEnvir
}
}
));