Noob: Passing two functions into a Synth

I got those two panning functions for a PanX inside a SynthDef which consists of five summed signals:

~dur = 5;
~panFunc1 = { SinOsc.kr(Env([0.1, 15], ~dur, 4).kr(2)).range(0.0, 1.0).poll(label: "a") };
~panFunc2 = { SinOsc.kr(LFNoise2.kr(5).range(0.1, 0.25), [ 8pi * 1/5, 8pi * 2/5, 8pi * 3/5, 8pi * 4/5, 8pi * 5/5]).range(0.0, 1.0).poll(label: "b") };

How can I pass the first one, then the second one after ~dur into the pos argument of PanX.ar?

Here is the Synth:

(
~dur = 29;
~dur2 = 32;
~env = Env([0, 1, 0], [0.5, 0.5], ['wel', 'wel']);
~grainEnv = Buffer.sendCollection(s, ~env.discretize, 1);

SynthDef(\section1_5, {
	var env, trigger, sig;
	env = Env([0, 1, 1, 0], [0.01, ~dur + ~dur2, 1.0], ['wel']).kr(2);

	trigger = Impulse.ar(
		Env([0.1, 51.91], [~dur], 9).kr(0) * LFNoise2.kr(20).range(Env([0.01, 1], ~dur, 7).kr(0), Env([5.0, 1.0], ~dur, -7).kr(0))
	);

	sig = GrainBuf.ar(
		numChannels: 1,
		trigger: trigger,
		dur: 0.03,
		sndbuf: [~b_1, ~b_2, ~b_3, ~b_4, ~b5],
		rate: 1,
		pos: Env([0.0, 0.1, 1.0], [~dur, ~dur2], ['wel']).ar(0),
		interp: 4,
		pan: 1,
		envbufnum: ~grainEnv,
		maxGrains: 512
	);

	sig = PanX.ar(2, sig * env, pos: 0.5, -6.dbamp).sum;
	Out.ar(0, sig);
}).play;
)

I unsuccessfully tried to recreate the panning functions with demand rates.
I also wrote it as a Routine and Task like this

(
r = Routine({
	~panFunc1.play;
	~dur.wait;
	~panFunc2.play;
});
)
(
t = Task({
	~panFunc1.play;
	~dur.wait;
	~panFunc2.play;
});
)

which I then tried to pass with a 1.do({ r.play; }) or 1.do({ t.play; }) it won’t work either.

Thank you all

here’s one way
make pos an argument of the synth function (that makes a NamedControl you can access later)
then map that Control to a Bus…
use a Routine to play your pan functions on that Bus

a = {
	arg pos = 0.5;
	var sig = Saw.ar(444);
	sig = PanX.ar(2, sig ,pos, -6.dbamp);

}.play;  //a now refers to the synth specified by the preceding function
b = Bus.control.set(0.5);
fork{
	s.sync; // to make sure synth is playing before we map
	a.map(\pos, b); // Bus b now controls the \pos control in Synth a
	~panFunc1.play(s, b); 
	~dur.wait;
	~panFunc2.play(s, b)
}

You’ve probably experienced the bit where a synthdef cannot have a dynamically changing graph of ugens? Everything in a synth must be predetermined. The dynamic change of panning functions cannot be effected by the synthdef pan function swapping out. On the other hand, a synth writing into a bus can be changed.

So no, you cannot pass two functions into a Synth. There are some other instances where it might seem like this is happening, but it isn’t really. One is an Env evaluation trick. The other is a Synth.wrap.

Thanks for your answer!

The first panning function does work but the second one doesn’t…

I changed the second one a bit to make things clearer:

(
~dur = 5;
~panFunc1 = { SinOsc.kr(Env([0.1, 15], ~dur, 4).kr(2)).range(0.0, 1.0) };
~panFunc2 = { [0.0, 0.25, 0.5, 0.75, 1.0] };
~panBus = Bus.control.set(0.5);

a = {
	arg pos = 0.5;
	var sig = Saw.ar([50, 100, 200, 400, 800], 0.1);
	sig = PanX.ar(2, sig, pos, -6.dbamp).sum;
}.play;
)

(
fork {
	s.sync;
	a.map(\pos, ~panBus);
	~panFunc1.play(s, ~panBus); 
	~dur.wait;
	~panFunc2.play(s, ~panBus)
}
)

Maybe one has to pass the array of the second function as a literal?

Hm I see…

I also tried to sequence with demand rate UGens and Envs with hold curves, but I didn’t know of the Synth.wrap. I guess I will give it a look

Another approach is to use a Select inside the synthDef. In this simple example the panning changes from SinOsc.kr(0.2) to LFTri.kr(3). Sweep works like a counter in seconds and the time before changing from one panning behaviour to the next is an argument.

SynthDef(\test, {
	var sig = Saw.ar(\freq.kr(220)) * 0.2;
	var panTrig = Sweep.kr() > \time.kr(2);
	var pos = Select.kr(panTrig.poll, [SinOsc.kr(0.2), LFTri.kr(3)]);
	Out.ar(\out.kr(0), Pan2.ar(sig, pos));
}).add;

Synth(\test, [time:2]); // changes after 2 seconds
Synth(\test, [time:4]) // changes after 4 seconds

Thank you so much!

This works out - also regarding the multichanneling…