Sharing data with different patterns

Dear community,

I’m looking for different ways to sync and control multiple parameters of different patterns (sometimes controlling the same synth, sometimes controlling different synths). In the following example, the problem appears when I use Pfunc to read a pattern. I can no longer find the best way to solve this problem. Thank you very much for your help.

(
~speed = 0.7;
Pbind(\octave, 5, \dur, Pfunc({~speed})).play
)

~speed = 0.1;

~speed = Pwhite(0.1, 1, inf).asStream;
1 Like

Have you tried Pdefn? It might do want you are after.

Maybe use a PatternProxy?

(
~speed = PatternProxy(0.7);
Pbind(\octave, 5, \dur, ~speed).play;
)

~speed.source_(Pwhite(0.1, 1, inf))

Thank you very much Jordan. Yes, but then the problem arises when I want to synchronize Pdefns in different Pbinds, for example: Pdefn (\dur_synt1, ~speed, \dur_synt2, ~speed)… making sure that they receive the same values even using a random generator like Pwhite.

Ah I misunderstood, sorry!

Thank you nufets! This works, but there is still a problem with this example. Pwhite is evaluated differently for each Pbind:


(
SynthDef(\saw, {
	var sig, env;
	env = Env.adsr().kr(gate:\gate.kr(1), doneAction:2);
	sig = Saw.ar(\freq.kr, env);
	Out.ar(\out.kr, sig*0.1);
}).add;

~speed = PatternProxy(0.7);

Pbind(\degree, 3, \dur, ~speed).play;
Pbind(\instrument, \saw, \degree, 6s, \dur, ~speed).play
)

~speed.source_(0.3);

~speed.source_(Pwhite(0.1, 1, inf));

You can use Pdup to duplicate the control pattern to many receiving patterns. A random value fetched in the control pattern will be the same for all receiving patterns, then you can use Pchain to have all patterns read from from the control pattern(s). You can also always have a pattern which sets a global variable which is read with Pfuncs, so maybe instead of Pwhite, Pfunc{ ~speed = rrand(0.1, 1) } and then read the ~spead where you need it, or if you wanted to keep the original structure you could do, Pbind(\val, Pwhite(0.1, 1), \read, Pfunc{|ev|~speed = ev.val } )

You can sort of do this with Pget, Plet, and Plambda, it is a little awkward though…

(
a = Pbind(
	\dur, 0.125,
	\degree, Plet(\shared, pattern: Pdefn(\x) )
);
b = Pbind(
	\dur, 0.5,
	\degree, Pget(\shared, default: 1, repeats: inf).trace
);
c = Pbind (
	\dur, 0.5,
	\degree, Pget(\shared, default: 1, repeats: inf).trace
);

// Play the patterns in parallel
Plambda(
	Ppar([a, b, c], inf)
).play;
)

Pdefn(\x, 0.2)

Pdefn(\x, Pwhite()) // does produce repeated results

You can put the Pwhite in a Pseed, i.e. make sure different randoms get the same seed:

~speed.source_(Pseed(1234, Pwhite(0.1, 1, inf)));

As always, the generosity of the participants in this forum is amazing!

Thank you all for your answers, they help me a lot.

Glad that I could help!

However, when sequentially changing from the “seeded” version of your Pwhite to a non-seeded one and back to a seeded one will make the pattern loose its alignment. Just mentioning this as I for myself have no answer to the question on how to “realign” two patterns that were started in sync, then at some point “un-synced” and then “re-synced” again. Here’s some code illustrating what I mean (using your example):

(
// I thought giving the PatternProxy a default quant might
// re-sync the pattern while playing. It doesn't, only makes sure
// patterns are scheduled when started calling 'play'
// any further scheduling is determined by the deltas ('dur') defined in the patterns
~speed = PatternProxy(0.7).quant_(1);

Pbind(
	\degree, 3, 
	\dur, ~speed, 
	// just for debugging purposes
	\beat, Pfunc { thisThread.clock.beats }
).trace(prefix: \p1).play;

Pbind(
	\instrument, \saw, 
	\degree, 6s, 
	\dur, ~speed, 
	\beat, Pfunc { thisThread.clock.beats }
).trace(prefix: \p2).play;
)

// p1 and p2 playing aligned
// 'beat' returns identical values in p1 an p2
~speed.source_(Pseed(1234, Pwhite(0.1, 1, inf)));
// 2 different random values for ~speed in p1 and p2
~speed.source_(Pwhite(0.1, 1, inf));
// alignment of p1 and p2 is lost
// 'dur' is identical in p1 and p2, 'beat' is not
~speed.source_(Pseed(1234, Pwhite(0.1, 1, inf)));

Yes, I noticed that. It concerns another question posted here: Synchronizing patterns (again)

ah, yes, I’ve already seen that thread … :wink: