Adjusting Pbindef based on current value

Hi -
I had a small question. -
The following snippet iterates through all currently playing Pbindefs and sets their duration to 0.2. I am curious if there is a way to call their current value and modify it within this statement. (If I wanted to make each duration 2x its current, for example.)

Thanks for any and all help!

Pbindef.all.keys.do{|item, i|
	Pbindef(item,
		\dur, 0.2)
};

The data structure inside Pbindef makes this a bit harder than you’d think.

Pbindef has a .source pattern (a PbindProxy).

Inside the PbindProxy, there’s an array of .pairs.

To access an item by name in this array, first, find the indexOf a name, and if it exists, the item is at index + 1. (I don’t see it built in method to do this, but maybe I’m overlooking something.)

Then this gets you a PatternProxy, whose .source is the value you want.

AFAICS this doesn’t exist as a method, but could be wrapped up in a function.

Pbindef(\x, \a, 1, \b, 2);

(
~pbindefAt = { |key, name|
	var index;
	var proxy = Pbindef.all[key];
	// Pbindef and Pdef use the same global collection
	// Pbindef guarantees this top-level data structure
	// but Pdef can be anything e.g. Pfindur(4.0, Pbind(...))
	// too complex to find pairs in that case, so, reject requests for Pdefs
	if(proxy.isKindOf(Pbindef)) {
		index = proxy.source.pairs.indexOf(name);
		if(index.notNil) {
			proxy.source.pairs[index + 1].source
		} { nil }
	} { nil }
};
)

~pbindefAt.(\x, \a)  // 1

Pbindef(\x, \a, ~pbindefAt.(\x, \a) * 2);

Adding this as a method of PbindProxy and Pbindef would probably be a good enhancement.

(Note that if the original value is a pattern, then ~pbindefAt.(\x, \a) * 2 would be a Pbinop representing the * 2 operation. If you do this many times, then you would get nested Pbinops… which would evaluate OK, but could be tricky to unwind if needed.)

hjh

1 Like

This is so helpful, thank you!