{ thisThread.clock.secs2beats(10).postln }.fork
returns -9138.438647381
thisThread.clock.secs2beats(10).postln
returns 10
I’m not using it wrong am I? that should return something reasonable right?
{ thisThread.clock.secs2beats(10).postln }.fork
returns -9138.438647381
thisThread.clock.secs2beats(10).postln
returns 10
I’m not using it wrong am I? that should return something reasonable right?
yes I am also seeing negative numbers here
also for TempoClock.secs2beats(10) in the main thread
I didn’t see them until restarting
This discrepancy is because of:
fork { [thisThread, thisThread.clock].postln };
-> [ a Routine, a TempoClock ]
[thisThread, thisThread.clock];
-> [ a Thread, class SystemClock ]
The confusion with the negative numbers is because beats2secs and secs2beats are operating on absolute time points, not durations.
(
var t = TempoClock.new;
SystemClock.sched(1, { t.stop });
{
"TempoClock beats now = %
SystemClock seconds now = %
t.beats2secs(beats now) = %
t.secs2beats(SystemClock seconds now) = %
t.secs2beats(10) = %
".postf(
t.beats,
SystemClock.seconds,
t.beats2secs(t.beats),
t.secs2beats(SystemClock.seconds),
t.secs2beats(10)
);
}.fork(t);
)
TempoClock beats now = 0.0
SystemClock seconds now = 428.036806685
t.beats2secs(beats now) = 428.036806685
t.secs2beats(SystemClock seconds now) = 0.0
t.secs2beats(10) = -418.036806685
The timing model in SC goes like this:
SystemClock is the time reference. Everything goes back to SystemClock’s seconds
. “0 seconds” is set when the sclang process boots up, and SystemClock advances according to std::chrono::high_resolution_clock
(or std::chrono::steady_clock
).
When you start a TempoClock, it’s a line beats = tempo * secs + b
where b is such that 0 = tempo * secs + b (so b = -secondsAtTempoClockOnset * tempo). I think it doesn’t look exactly like that in the source code, but conceptually, that’s what it is.
The above example schedules a routine at 0 beats on t
. To wake up on time, “beat 0” as an absolute time point must correspond to an absolute point on the “seconds” timeline. This is t.beats2secs(0)
. In fact t.beats2secs(t.beats) == SystemClock.seconds
, always, by definition.
t.secs2beats
then is taking an absolute point on the “seconds” timeline and converting it into the timepoint in beats on this TempoClock. t.beats2secs(10)
… chances are, “10 seconds after sclang bootup” was a long time ago. If it was earlier than the moment of creating a tempo clock, then the beats value must be less than 0.
hjh
Thanks!
I’ll add that to the docs later today.
Should probably be called beat2sec
though — 4 beats (duration) verses the fourth beat (time point).