Newbie question: stopping a Pbind

Hi everyone, I can’t figure out why I can’t stop this very simple Pbind with the “stop” method… :disappointed_relieved: Any idea?

(
SynthDef(\kick, {
|freqA=500, freqB=20, freqC=10, freqDur1=0.01, freqDur2=0.2, freqC1=1, freqC2=(-1), atk=0.01, rel=1, c1=1, c2=(-12), amp=0.8, out=0, pan=0|
var sig, env, freqSweep;
freqSweep = Env([freqA, freqB, freqC], [freqDur1, freqDur2], [freqC1, freqC2]).ar;
env = Env([0,1,0],[atk,rel],[c1,c2]).kr(2);
sig = SinOsc.ar(freqSweep, pi/2);
sig = sig * env;
sig = Pan2.ar(sig, pan, amp);
Out.ar(out, sig);
}).add;
)

(
~kick1 = Pbind(
\instrument, \kick,
\dur, Pseq ([1/8, 1/16, 1/16, 1/8, 1/8, 1/16, 1/16, 1/16, 1/16, 1/8, 1/8, Rest(11)], inf),
\stretch, 1.875,
\amp, Pseq ([0.9, Pexprand(0.1,0.3,9), 0.9, Rest(11)], inf),
\freqA, Pseq ([500, 300, 300, 300, 500, 300, 300, 300, 300, 300, 500, Rest(11)], inf),
);
)

~kick1.play;
~kick1.stop;

hey, Pbind is the recipe for an Event Stream Player. so you use the play method on the Pbind and the data inside is passed to the Event Stream Player which will use its recipe to produce sound. now you have to stop the Event Stream Player from making sound not the initial recipe, when im not mistaken.
this will work:

(
~kick1 = Pbind(
	\instrument, \kick,
	\dur, 1,
	\amp, 0.25,
	\freqA, 500,
);
)

y = ~kick1.play;
y.stop;

or you wrap it inside a Pdef:

(
Pdef(\kick,
	Pbind(
		\instrument, \kick,
		\dur, Pseq([1/8, 1/16, 1/16, 1/8, 1/8, 1/16, 1/16, 1/16, 1/16, 1/8, 1/8], inf),
		\stretch, 1.875,
		\amp, Pseq([0.9, Pexprand(0.1,0.3,9), 0.9], inf),
		\freqA, Pseq([500, 300, 300, 300, 500, 300, 300, 300, 300, 300, 500], inf),
	)
);
)

Pdef(\kick).play;
Pdef(\kick).stop;
1 Like

Thank you so much! It’s very clear now :hugs:

Another approach is to set the environmental variable ~kick1 equal to the Pbind.play:

(
~kick1 = Pbind(
	\instrument, \kick,
	\dur, 1,
	\amp, 0.25,
	\freqA, 500,
).play;
)

~kick1.stop
~kick1.play

Doing that, as dietcv correctly stated, will provide control over the EventStreamPlayer, but will save you from having to use two variables.

A quick follow up to this stopping a pattern question.
If i take the following Pbinds:

(
d = Pbind(
	\midinote, [50],
	\type, Pseq([\n, \, \, \], inf),
	\dur, 1/8);
e = Pbind(
	\midinote, [64],
	\type, Pseq([\n, \, \, \], inf),
	\dur, 1/8);
);

I can start and stop both independently as follows:

(~lownote = d.play; ~highnote = e.play);
(~lownote.stop; ~highnote.stop);

I can also start both as part of an Array like this:

~composite = [d.play, e.play];

and stop them independently like this:

~composite[0].stop;
~composite[1].stop;

However i can’t stop them like this (only the first Pbind responds to the .stop message):

~composite[0,1].stop;

Similarly, if i start them like this:

~composite = [d, e];
~composite[0].play;
~composite[1].play;

Then i can no longer stop them with the above method.

~composite[0].stop;
~composite[1].stop;

Further, (and similar to the above stop questions) why when using the following method does only the first Pbind play and not the second?

~composite[0,1].play;

This seems a inconsistent but I’m clearly missing something in terms of how Arrays are implemented within the Pattern context.

~composite[0,1] is the same as ~composite.at(0, 1) and the at method ignores all arguments except the first one.

This is already discussed earlier in the thread.

~composite = [d, e];
-> [a Pbind, a Pbind]

~composite[0].play;
-> an EventStreamPlayer  // i.e. NOT A PBIND! This is important!

Pbind does not stop, because Pbind never plays. It makes another object that plays. You have to keep the playing object in the array in order to stop it.

hjh

1 Like