Pbindef usage with custom TempoClock

A student of mine came across this seemingly counterintuitive situation which I have not encountered before.

In the code below, we expected that the second evaluation of Pbindef(\a, ...etc).play(~bpm) (last line) would play it using that custom TempoClock again, just as it did the first time .play was used a few lines earlier. However, it seems the ~bpm is ignored and the last Pbindef plays using the default TempoClock at 60 BPM. This apparently happens because the Pbindef immediately prior to that was finite (i.e., it ended after 4 notes).

~bpm = TempoClock.new(150/60).permanent_(true);

// start off with an inf pattern
Pbindef(\a, \dur, 1, \degree, Pwhite(0, 10), \amp, 0.4);

Pbindef(\a).play(~bpm);

// a finite pattern now, it ends after 4 notes
Pbindef(\a, \degree, Pwhite(0, 10, 4));

// now if I try something new, it ignores the ~bpm clock
// I would expect it to play using ~bpm as before
Pbindef(\a, \dur, 1, \degree, Pwhite(8, 13)).play(~bpm);

I found that if I run Pbindef(\b).clock_(~bpm); before the last line, then it plays using the ~bpm TempoClock.

I would appreciate if anybody could help me understand what is happening in this example.

Thanks!!

I’m not seeing the described behavior! (Mac) when I run these lines the Pbindef plays using ~bpm as expected…

Also here (Mac) I cannot confirm this behaviour.

Two thoughts:

.) Check with deinstalled quarks.
.) Do Pdef.removeAll before running the example, Pdef might be in an unclear state.

Thank you so much for both of your replies. This is very strange!

I tested this code on a Mac too (Catalina), running SC 3.11.1. Still on the same Mac, I now went ahead and removed all Quarks. I restarted SuperCollider, and the weird behavior is still there.

I also found that if I hit Cmd Period, or evaluate Pbindef(\a).stop before running the last line, then it behaves as expected (ie utilizes the proper ~bpm).

Tomorrow I will try on a different laptop and report back.

I can also reproduce this exactly as you describe, with SC 3.11.2 (9a34118e).

I’m going to guess a bit: In the last line

Pbindef(\a, \dur, 1, \degree, Pwhite(8, 13)).play(~bpm)

the .play(~bpm) call is redundant – the Pbindef is already playing, so it just picks up the new pattern and starts playing on the internal clock of the Pbindef, which happens to be TempoClock.default, because the play method doesn’t set the internal clock. A quick workaround would be (as I now see you noted in your original post):

Pbindef(\a, \dur, 1, \degree, Pwhite(0, 10), \amp, 0.4);
Pbindef(\a).clock = ~bpm;
Pbindef(\a).play;
Pbindef(\a, \degree, Pwhite(0, 10, 4));
Pbindef(\a, \dur, 1, \degree, Pwhite(8, 13)) //should still play on ~bpm

So, if there is a bug, it’s possibly related to if and how the play method should set the internal clock of the Pbindef, if a clock is passed as an argument.

I wonder if this is (vaguely) related to this closed issue, or its fix?

I’m sc 3.10.3 so perhaps a bug had been introduced since then?

Update: I tried the same code on two additional laptops. Under SC 3.10.2 the code runs as I would expect (i.e., the last line does utilize the ~bpm clock). On the other machine though, under SC 3.11.0, the clock is ignored on the last line.
So it does sound like @semiquaver is right? A bug has been introduced?

Current version is 3.11.2.

Also note that the above-referenced bug report was closed in June last year = possible code change around this issue in June last year. I don’t have access to github on my phone anymore so I can’t check the history of release dates, but it seems pretty likely to me that 3.11.0 and 3.11.1 (mentioned in this thread as not working) would not have the code change while 3.11.2 could very well have it (but nobody has mentioned testing it).

Possibility of a code change just prior to the latest release + latest release hasn’t been checked for this issue = next step should be to check the latest release.

Oh, I missed that Brian tested it… so it is still an issue in the current release. Sorry to have overlooked that.

According to sc class library: TaskProxy: play on instances' clock if no argClock by elgiano · Pull Request #4903 · supercollider/supercollider · GitHub - a fix was merged into the development branch but it hasn’t gone into a release yet. So you could update your class library to match the development branch.

hjh

Hi -
I believe I’m running into this problem right now - I’m curious if anyone has a suggested workaround.

~bpm = TempoClock.new(20/60).permanent_(true);
~bpm2 = TempoClock.new(130/60).permanent_(true);


Pbindef(\a,
	\degree, 4,
	\dur, 0.3,
).play(~bpm);


Pbindef(\b,
	\dur, 0.3
).play(~bpm2);

//change the tempos. no action.
~bpm = TempoClock.new(50/60).permanent_(true);
~bpm2 = TempoClock.new(230/60).permanent_(true);


Hi Polina,

you aren’t changing the tempo of the clocks your two Pbindefs are running on. Instead, you are creating two new clocks that have no connection to the running Pbindefs …

Probably you can do something like ~bpm.tempo_(50/60)

(that’s pseudo code, I’m on a phone)

Cheers,
eddi

https://alln4tural.bandcamp.com