Repository navigation
Read the host clock from CLOCK_MONOTONIC_RAW on Linux - #208
Merged
Merged
Conversation
On Linux, `std::chrono::steady_clock` is `CLOCK_MONOTONIC`, which NTP slews. aiosendspin timestamps on `CLOCK_MONOTONIC_RAW`, so while the host's time daemon corrects the system clock, the offset the time filter measures moves at the slew rate. That rate changes faster than the filter's drift model follows, the sync error crosses the hard sync threshold, and playback hard-corrects. `platform_time_us()` now reads `CLOCK_MONOTONIC_RAW` on Linux and keeps `steady_clock` on other hosts. ESP-IDF is unchanged. `SendspinClient::now_us()` exposes the client clock, so consumers stamp `notify_audio_played()` and `write_audio()` times in the library's clock domain. The examples and the integration guide use it.
kahrendt
approved these changes
Oct 17, 2026
kahrendt
left a comment
Contributor
There was a problem hiding this comment.
Thanks! I marked it as a breaking change as anyone who built a linux client that directly used the wrong timestamp needs to migrate to the helper.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On Linux,
std::chrono::steady_clockisCLOCK_MONOTONIC, which NTP slews. aiosendspin timestamps onCLOCK_MONOTONIC_RAW, so while the host's time daemon corrects the system clock, the offset the time filter measures moves at the slew rate. That rate changes faster than the filter's drift model follows, the sync error crosses the hard sync threshold, and playback hard-corrects.platform_time_us()now readsCLOCK_MONOTONIC_RAWon Linux and keepssteady_clockon other hosts. ESP-IDF is unchanged.Notes
SendspinClient::now_us()returns the client clock, so consumers stampnotify_audio_played()andwrite_audio()times in the library's clock domain. The examples and the integration guide use it.steady_clockhelpers; it moves tonow_us()once this is tagged.Testing
-DENABLE_WERROR=ONbuild with the examples and PortAudio; 707/707 under ASan/UBSan, 696/696 without Opus, 707/707 under TSan;script/clang-tidy.shand clang-format 18.1.8 clean.CLOCK_MONOTONIC31 ms againstCLOCK_MONOTONIC_RAWwithin 75 s. With this change the measured offset stayed within 75 µs of zero through it; without it the same event moved the measured offset 51 ms in a minute and the player lost sync repeatedly.-o pulsethe player can still lose sync after such a correction: PulseAudio's own timing runs onCLOCK_MONOTONIC, which this change does not reach.