Passing pattern data into a Pwhile

I have a Pbindef that spits db volume data on variable ~ad1. I’m sending these data into a Pbindef that controls frequency.
What I’d like to do is:
while volume < x then a Prand chooses stuff. When false Pbindef just uses the last acquired frequency OR sends nothing.
I have a couple of different problems:
Pwhile does not like Pfunc and Pkey so I cannot evaluate the volume data inside the test function.
Pif can be a workaround but without an else statement it stops the Pbindef and I cannot think of a way to have the last acquired frequency as the else part of the statement.
I’m attaching the code with the Pwhile and the Pif iteration, none of them work correctly but hopefully you can see what I’m trying to do.
Run the osc thing on the top first and you can monitor the data on the post window.

~targetAddress = NetAddr("127.0.0.1", 57121);
~baseMessage = "/fromSC";
~oscTransmitter =
	Pfunc({|ev|
		var oscArray = [~baseMessage];

		// Construct the osc array from the Pbind's keys
		ev.keysValuesDo{|k,v|
			// Filter out the 'destination' and 'id' keys
			(k != 'destination' and: {k != 'id'}).if{
				oscArray = oscArray ++ k ++ [v];
			}
		}.postln;

		// And send
		ev.destination.sendBundle(~latency, oscArray)
	});


~envelopeAD1 = Pbindef(\envelopeAD1,
	\restprob, Pwhite(0, 1, inf),
			\volume,Pswitch([0, -80],Pkey(\restprob, inf), inf).collect({|event|~ad1 = event;}),
			\dur, 1,
		\destination, ~targetAddress,
		\id, 'envelopeAD1',
		\voice, 0,
		\timingOffset, 0.1,
		\play, ~oscTransmitter
		);


~silentuner1 = Pbindef(\silentuner1,
	\frequency, Pwhile({Pfunc{~ad1}< -60},Prand([1, 2, 3, 4, 5], inf)),
			\dur, 0.3,
		\destination, ~targetAddress,
		\id, 'silentuner1',
		\voice, 0,
		\play, ~oscTransmitter
		);

~silentuner1 = Pbindef(\silentuner1,
	\frequency,  Pif(Pfunc{~ad1} < -60,Prand([1, 2, 3, 4, 5], inf),0),
			\dur, 0.3,
		\destination, ~targetAddress,
		\id, 'silentuner1',
		\voice, 0,
		\play, ~oscTransmitter
		);


~silentuner1.clear;
~silentuner1.play;
~envelopeAD1.play;

Pwhile embeds its subpattern – it’s unfortunately misleading.

Pwhile(
	Pseq([true, true, false], inf).asStream,
	Pseries(0, 1, 3)
).asStream.nextN(10)

-> [ 0, 1, 2, 0, 1, 2, nil, nil, nil, nil ]

… where you might have expected [ 0, 1, nil ... ].

I think it would be necessary to save the frequency somewhere.

~lastFrequency = -inf;

p = Pbind(
	\flag, Prand([true, false], inf),
	\freq, Pif(
		Pkey(\flag),
		Pwhite(100, 200, inf),
		Pfunc { ~lastFrequency }
	).collect { |freq| ~lastFrequency = freq }
);

q = p.asStream;

q.next(())  // run this repeatedly

hjh

1 Like