hey, thanks a lot for the detailed information. i will have a look at the wslib quark.
I actually thought that one could do a hybrid solution with Pmono, where you have a \dur
pattern and modulate the triggers like this. which is not working.
var trig = \trig.tr(0);
trig = Trig.ar(trig, SampleDur.ir) * (1 + (LFNoise2.kr(20) * 0.5));
ive already tried to use the auto-map approach see this thread ctrlEnv merge Event \type. But i use PbindFx for sequencing fx and a function for data sharing between source and fx and PbindFx doesnt like the busses created automatically. every external input has to be passed via \otherBusArgs
. so i skipped this solution. see this thread DXEnvFan Bus in PbindFx - #3 by dietcv
But ive combined some things and sending LFOs to a control Bus and using In.ar
for sending a modulation signal:
(
~makeBusses = {
~bus = Dictionary.new;
~bus.add(\fx -> Array.fill(3, { Bus.audio(s, 2) }));
~bus.add(\ctrl -> Array.fill(3, { Bus.control(s, 1) }));
};
~makeNodes = {
s.bind({
if(~mainGrp.isNil) {
~mainGrp = Group.basicNew(s, -1);
};
if(~ctrlGrp.isNil) {
~ctrlGrp = Group.basicNew(s, -1);
};
if(~fxGrp.isNil) {
~fxGrp = Group.basicNew(s, -1);
};
~mainGrp.nodeID = s.nodeAllocator.alloc;
~ctrlGrp.nodeID = s.nodeAllocator.alloc;
~fxGrp.nodeID = s.nodeAllocator.alloc;
s.sendBundle(nil, ~mainGrp.newMsg(nil,\addToHead));
s.sendBundle(nil, ~ctrlGrp.newMsg(~mainGrp,\addAfter));
s.sendBundle(nil, ~fxGrp.newMsg(~ctrlGrp,\addAfter));
});
};
)
(
SynthDef(\pluck, {
var trig = \trig.tr(0);
var lfo = \lfo.kr(0);
var sig;
trig = Trig.ar(trig, SampleDur.ir);// * (1 + (LFNoise2.kr(20) * 0.5));
sig = SinOsc.ar(lfo.linexp(-1, 1, 100, 8000)) + SinOsc.ar(lfo.linexp(-1, 1, 1000, 4000));
sig = Pluck.ar(sig, trig, 0.1, \freq.kr(50).reciprocal, \dec.kr(0.1), \coef.kr(0.5));
sig = sig * \amp.kr(0.25);
sig = sig * (1 + In.ar(\modIn.kr(0)));
//sig = SafetyLimiter.ar(sig);
Out.ar(\out.kr(0), sig);
}).add;
SynthDef(\lfo, {
arg gate=1, rate=0.3, mul=1;
var sig;
FreeSelf.kr(gate <= 0);
sig = LFSaw.ar(rate * (1 + (LFNoise2.kr(rate) * 0.5)), mul: mul);
Out.kr(\out.kr(0), sig)
}).add;
SynthDef(\ampMod, {
var lfoGain = EnvGen.ar(Env([0, 1], [0.02], \sin));
var sig = SinOsc.ar(\freq.kr(150)).range(1 - lfoGain, 1);
Out.ar(\out.kr(0), sig)
}).add;
)
(
Pdefn(\durs, Pbind(\dur, 1/12));
Pdefn(\notes, Pbind(\freq, [125, 130]));
Pdefn(\coefs, Pbind(\coef, [0.5, 0.5]));
Pdefn(\decs, Pbind(\dec, [0.2, 0.3]));
Pdefn(\amps, Pbind(\amp, [0.25, 0.25]));
Pdef(\poly,
Ppar({|i|
Pmono(\pluck,
\dur, Pkey(\dur),
\freq, Pkey(\freq).collect(_[i]),
\dec, Pkey(\dec).collect(_[i]),
\coef, Pkey(\coef).collect(_[i]),
\lfo, ~bus[\ctrl][i].asMap,
\modIn, ~bus[\fx][i],
\otherBusArgs, [\modIn],
\group, ~mainGrp,
\amp, Pkey(\amp).collect(_[i]),
\out, i,
\cleanupDelay, Pkey(\dur) * Pkey(\legato),
\fxOrder, [1]
) } !2) <> Pdefn(\notes) <> Pdefn(\coefs) <> Pdefn(\decs) <> Pdefn(\durs) <> Pdefn(\amps);
);
Pdefn(\rates, Pbind(\rate, [0.3, 0.2]));
Pdefn(\muls, Pbind(\mul, [1, 1]));
Pdef(\lfo,
Ppar({|i|
Pbind(
\instrument, \lfo,
\dur, inf,
\rate, Pkey(\rate).collect(_[i]),
\mul, Pkey(\mul).collect(_[i]),
\out, ~bus[\ctrl][i],
\group, ~ctrlGrp,
) } !2) <> Pdefn(\rates) <> Pdefn(\muls);
);
Pdef(\poly_ctrl,
Ptpar([0, Pdef(\poly), 0.0001, Pdef(\lfo)])
);
)
Pdef(\poly_ctrl).play;
Pdef(\poly_ctrl).stop
(
x = Synth(\ampMod, [\freq, 300, \out, ~bus[\fx][0]], target: ~mainGrp, addAction: \addBefore);
y = Synth(\ampMod, [\freq, 400, \out, ~bus[\fx][1]], target: ~mainGrp, addAction: \addBefore);
)
(
x.free;
y.free;
)
and searching a good way for composing the Pdefn values:
(
r = Routine({
Pdef(\poly_ctrl).play;
10.wait;
loop {
Pdefn(\notes, Pbind(\freq, Env([[125,130], [145,165]], 10)));
10.wait;
Pdefn(\notes, Pbind(\freq, Env([[145,165], [125,130]], 10)));
10.wait;
}
}).play(AppClock, quant:1)
)
(
Pdef(\poly_ctrl).stop;
r.stop;
)
but the initial SynthDef(\demand_clicks)
vs. SynthDef(\pmono_clicks)
is still unsolved.