Ableton / link

Ableton Link
Other
1.09k stars 149 forks source link

Second peer syncing to half beats? #61

Closed jamshark70 closed 5 years ago

jamshark70 commented 5 years ago

I'm working on Link integration for SuperCollider.

I find occasionally, for no reason I can determine, that the second peer occasionally locks onto the "and-of" beat -- if the first peer is at beat 20.0, the second peer may be at 15.5.

Why would this be?

fgo-ableton commented 5 years ago

That sounds strange. Are you using the same quantum for both peers? And is it higher that 0.5? Otherwise my guess would be that there is an issue when calculating the host time the events are scheduled for.

jamshark70 commented 5 years ago

I had just spent some time investigating this. I'm still trying to nail down exactly how it happens.

I believe it has to do with system-vs-sample clock drift. SC is divided into client (scheduling, sequencing and note-generation logic) and audio server (audio processing). Sclang sends timestamped OSC messages to scsynth, which scsynth interprets according to system clock time. (There is an alternate, multiprocessor-aware server called supernova that optionally allows timestamps to be measured in samples.)

Sclang's scheduling clocks don't run in any audio callback, so they have no awareness of sample rate inaccuracies. (So, we don't have sample-accuracy either, except in non-realtime rendering or in supernova.) (SC_Ableton_Link.cpp is using the AppSessionState functions.)

I'm pretty sure this only happened when SC had been running for a while, and I activated a LinkClock late in the session. I can definitely not reproduce it if SC and QLinkHut start in quick succession and I create the LinkClock soon after (and then Link's network communication does a great job of keeping them together).

That might be explained if SC and QLinkHut initialize their internal reference times, and then QLinkHut runs for some time according to samples, and then SC tries to join. If SC assumes that times coming from Link have been following the system clock, but they haven't, then they might be off.

But, I just tried to reproduce it and couldn't. So I'll have to keep my eyes open and get back to you.

fgo-ableton commented 5 years ago

Link itself is entirely based on the system clock. So if SC lang and LinkHut run on the same host and same host clock they should stay in sync. On Linux Link uses CLOCK_MONOTONIC as it's default clock. In that case even if network communication got interrupted (for some theoretical reason) they should stay in sync as long as the tempo doesn't change. If SC schedules based on a different clock that would explain where the drift comes from.

jamshark70 commented 5 years ago

I think I can close this.

I found out, only just recently, that the SC language's SystemClock is, in fact, not monotonic (!). SC devs are now discussing what, if anything, to do about that.

I think the effect I was seeing goes like this:

  1. Wake the computer from sleep.
  2. Start sclang pretty shortly after that.
  3. Sometime within 30-40 minutes, network time sync adjusts the OS clock (and sclang follows -- but its time initialization value is based on the old OS clock time).

If I start a LinkClock after that, then sync will not be accurate.

I consider that a bug, or at least gotcha, in SC. At least it's not that common (you have to start SC soon after waking and be on the network).

BTW SC's LinkClock will be in the next v3.11 release.