Hello!
I have multiple patterns sharing arguments which are stored in a dictionary. and to minimize code and for usability reasons, i used to give those arguments simple in the “Pairs” argument of the Patterns. However now I realized, that i want to change those arguments and keep those patterns adapt to this. Typically, I would use Pfunc{} for keeping track of argument changes, but it doesn’t work for Pairs. Is there a way to make it work or is there another workaround for this?
I provide some example code to clarify what i mean:
~a = Dictionary.with(\amp->0.3);
//this works for changing the amp in ~a, that the pattern picks it up
(
p = Pbind(
\amp, Pfunc{~a[\amp]}
).play
)
~a[\amp] = 0.1;
~a[\amp] = 0.3;
p.stop;
//this doesnt work to track the amp of ~a when not in a Pfunc
(
p = Pbind(
*~a.asPairs
).play
)
~a[\amp] = 0.1;
~a[\amp] = 0.3;
p.stop;
there are numerous ways to manipulate the contents of a Pattern. A Pbind by itself isn’t really laid out to be manipulated but e.g. Pbindf or PatternProxy might be useful? You possibly would have to adapt your strategy a bit but I think that could make a flexible framework for your purposes.
thanks for the response.
Not entirely sure how exaclty, u mean like this? Pbindf(Pbind(),*~a.asPairs).play
I mean im still not able to set ~a as a function or somehow.
Not true. Try it. It won’t work for pairs but it’s fine for events. (Though, the Pfunc solution that I proposed [99% sure it will work] does use a pattern to preset the event values, so the objection doesn’t apply to that.)
Oh, I just found out, I was not quite right about Pbindf - rather than just replace key/value pairs in the Pbind it creates a new EventStreamPlayer. My bad. Anyway, I don’t really understand what you mean by “I mean im still not able to set ~a as a function” - ~a is some kind of Dictionary. It wouldn’t make sense to redfine it as function. I think using a Pfunc like you did isn’t a bad idea. However, the Dictionary should not just hold numbers as values but Pfuncs:
~a = 0.3;
~pairs[\amp] = Pfunc { ~a };
(
~pbind = Pbind(
*(~pairs.asPairs)
)
// 'playing' a Pbind returns an EventStreamPlayer, not the Pbind
p = ~pbind.play;
// should update amplitude
~a = 0.7
I’ve been doing this for years. Now I can see what you mean that Dictionary isn’t interchangeable with Event here. But it definitely works with events, and has done for a long time.
A quick example, without the function. IMO reduced ugliness:
~a = (amp: 0.3);
(
p = Pchain(
Pbind(
\degree, Pwhite(0, 7, inf),
\dur, 0.25
),
Pfunc { ~a }
).trace.play;
)
// prints this: amp = 0.3 is there
( 'degree': 1, 'dur': 0.25, 'amp': 0.3 )
p.stop;
But, to be really formally correct, it should be:
~a = (amp: 0.3); // or Dictionary[\amp -> 0.3] or Dictionary.with(...)
(
p = Pchain(
Pbind(
\degree, Pwhite(0, 7, inf),
\dur, 0.25
),
Pfunc { |ev| ev.putAll(~a) }
).trace.play;
)
… because Pfunc in this context replaces any previous work with the ~a event. (This is why the result was Dictionary, causing the error, before.) putAll merges the incoming event ev and ~a.
If it’s written that way, then it also works with ~a being a Dictionary.