PatternProxy doesn't change Pbind values instantaneously

Hi all,

I’m trying to change some values inside a Pbind “on the fly”, without having to wait the next event to hear the change. I’ve started to use PatternProxy inside the Pbind but it does apply the change on value only when the next event occurs.
Have I done something wrong with the code or is it just conceptually wrong ?

~freqBlip = PatternProxy.new;
~freqBlip.source = Prand([10,20,30],inf);

(
Pbind(
	\instrument, \noise2,
	\freqBlip, ~freqBlip,
         \dur, 120,
).play
)

~freqBlip.quant = 3;
~freqBlip.source = Prand([1,2,3],inf);  

Thank you very much for your help.

Giulia

The pattern produces events.

Then it turns the events, one by one, over to an EventStreamPlayer to be played. At this point, the pattern has no more control over the event.

Playing the event really just starts something else (usually a Synth node) that produces the actual sound. The Synth node runs under its own power – the specific event that played it doesn’t have direct influence over its behavior (apart from a scheduled note release). It was given parameters at the beginning, and the default event prototype doesn’t overwrite those.

Also, there’s not a good way using pattern proxies to “re-awaken” a pattern earlier than its next scheduled time.

TL;DR Based on the desired behavior you described, you’re going to have an extremely hard time getting pattern proxies to do that. “… without having to wait the next event to hear the change” – the current pattern design simply doesn’t support that easily.

It will probably require building a new structure to track and modify playing events.

hjh

1 Like

In normal cases, the values in a Pbind are only used to set the initial values of the Synth that is played. Your Pbind plays one synth every 120 seconds, and the values are sent only then - then the EventStreamPlayer sleeps until it’s time to play the next event.

There are a few ways to get what you’re going for. Probably the most straightforward way is to use Pmono, which is specifically intended to play a synth once and then set the values of that Synth for future events. An equivalent of your example code with Pmono:

~freqBlip = PatternProxy.new;
~freqBlip.source = Prand([10,20,30],inf);

(
Pmono(
	\noise2,
	\freqBlip, ~freqBlip,
	\dur, 1,  // <--- parameter updates are sent every 1 beat
).play
)

~freqBlip.quant = 3;
~freqBlip.source = Prand([1,2,3],inf);  

You can also use PmonoArtic if you want to restart your synth once in a while AND send updates to the running synth.

If you want your changes to be send as soon as you hit return on the code, this might be more difficult. This would work if you e.g. used a \set event to set the values of a running synth, and then actually restarted playback of that Pbind when ever you make a change.

Hi jamshark70,

thank you very much for the detailed explanation. Yes, I thought that using pattern proxies would have helped to overcome the patterns’ characteristic, letting me manipulate events inside them but I understand now that I was just wrong with the all system conceptually. The reason why I wanted to develop such a system it is because my events needs to be really long (120 sec for example) for compositional purposes, but I also need a real time approach on them… I’ll probably go for Ndefs then.

Thank you again

Hi scztt, thanks for your help.

As I wrote above in the reply, my events need to be really long and continuous (like 120 sec for example), and subjected to fluid changes while they are running. That’s why restarting the synth for each change doesn’t really work in this case. I thought to overcome this problems using pattern proxies but I didn’t know that they don’t actually provide what I wanted because of the logic of the system itself.
I think I’ll go for \set on the synthdef itself as you suggested or eventually I’ll switch to Ndefs.

Thank you for your explanation!

Setting values is probably the most flexible in the long term.

One thing just for clarity - Pmono doesn’t restart the synth, it’s effectively like a single synth event followed by a stream of \set events.

There’s one more version of this that is probably my preference - if only because I think it splits the code up in a way that’s very clean… The event type \phrase will play another Pdef as if it were a single event. That Pdef is played as long as the outer pattern, and inherits all it’s values from the outer pattern, but can define it’s own structure.

For your case, you can have an outer pattern that plays your long 120 second notes… Then you can specify a phrase that’s a Pmono with a bunch of parameter sets, specifying the fluid changes happening to the running synth. An example:

(
Pdef(\longNote, Pmono(
	\default,
	\degree, Pkey(\degree) + Pseq([0, 2, 5, 9, 5], inf), // <--- values, including the degree, are inherited from the outer but can be overridden or modified
	\dur, 1/9
).trace);

Pdef(\pattern, Pbind(
	\type, \phrase,  // <--- refers to the Pdef above
	\instrument, \longNote,
	\octave, 3,
	\legato, 1,
	\degree, Pseq([0, -5, -3], inf),
	\dur, 60,
)).play;
)

This plays one new synth every 60 seconds, and modulates it’s freq parameter 9 times a second for as long as that note runs.

2 Likes