Does SystemClock have a notion on physical time?

I’m confused why only TempoClock has elapsedBeats to return the physical time. I see that SystemClock has no such method and SystemClock.seconds actually tail-calls (via Clock) to the thread’s .seconds… which isn’t a physical time (seconds is also settable in Thread).

So how can I get a an elapsedBeats that doesn’t depend on when the (current) thread clock has started, e.g to have a shared physical time measure between several threads without having to stick them on the same TempoClock?

I see that I can probably call Main/Process's elapsedTime or monotonicClockTime none of which are actually documented… (Main just inherits these methods from Process). The C++ implementations of these two do

double elapsedTime() { return DurToFloat(std::chrono::high_resolution_clock::now() - hrTimeOfInitialization); }

double monotonicClockTime() { return DurToFloat(monotonic_clock::now().time_since_epoch()); }

I also see that monotonicClockTime, although it seems to work, is never used in the class library, whereas Main.elapsedTime is used a bunch of times. Perhaps most notably, it is the source of timestamps used when sending bundles to the server.

Oh, forgot this one.

Situations where you want physical time are rare. In almost all cases, logical time is more useful.

For logical time, .seconds will give you a consistent time reference.

[SystemClock.beats, SystemClock.seconds, TempoClock.beats, TempoClock.seconds]

-> [ 813.775656904, 813.775656904, 812.276238924, 813.775656904 ]

… showing that the default TempoClock was instantiated slightly later than SystemClock, but its seconds value is the same as SystemClock. (I did note, though, that TempoClock’s documentation for seconds is incorrect – it claims to be elapsed time, but it’s really logical time.)

(
{
	var start = TempoClock.seconds;
	10000000.do { 1.0.rand };
	[start, TempoClock.seconds, Main.elapsedTime].postln
}.fork(TempoClock);
)

[ 1022.648851983, 1022.648851983, 1023.382883839 ]

Main.elapsedTime advanced, while logical time did not.

If you want physical time in consistent units across all clocks, Main.elapsedTime is it.

Perhaps most notably, it is the source of timestamps used when sending bundles to the server.

I don’t think so. OSC bundle timestamps are based on &g->thread->seconds == SystemClock.seconds (OSCData.cpp, line 439).

hjh

1 Like

I was thinking of schedBundle in schedBundle.sc

bundle.prSend(server, delta,Main.elapsedTime);

Event uses schedBundle extensively. Ultimately that seems to call into _NetAddr_SendBundle, which I haven’t looked at yet.

bundle here is expected to be an OSCBundle or MixedBundle object (because some of those methods call doPrepare on it, and that method name is implemented for OSCBundle etc but not for other classes).

JITLib uses OSCBundles but very few other places in the class library. (And schedBundle.sc shows no commit activity except formatting cleanups in some 10 years. I also spotted a reference to Tempo which I’m fairly sure is from the crucial library quark. That’s a bad sign: main library methods that require an extension should not be in the main library!)

I’m appalled that this is using elapsedTime, but it isn’t core functionality (probably should be moved back into crucial).

No, it doesn’t. Event.sc contains no references to either of those classes.

schedBundle in Event.sc is a function, not a method (so that the user can choose to override if needed).

hjh

1 Like