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.
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.
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.
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?
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.
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)