Skip to content

fix(desktop): hold a playback anchor so lyric lines land on the beat - #10

Merged
aodjo merged 1 commit into
developfrom
fix/lyric-sync-anchor
Sep 25, 2026
Merged

aodjo merged 1 commit into
developfrom
fix/lyric-sync-anchor

Conversation

@aodjo

@aodjo aodjo commented Sep 25, 2026

Copy link
Copy Markdown
Owner

Lyric lines arrived early on one verse and late on the next.

Players are not obliged to keep the position they publish up to date. MPRIS
has clients assume playback advances linearly and watch for a discontinuity
instead, and several players round the value or leave it standing between
updates. Reprise was adopting every sample as the new truth, which handed
the player's rounding straight to the lyric sheet twice a second.

Now the position advances on the clock from an anchor, and a sample only
replaces it when playback has genuinely moved: a new track, a change of
state, or a jump beyond the drift tolerance. A seek is still picked up on
the very next poll.

Simulated against a player reporting whole-second positions, polled every
500ms, over a 40-line sheet:

worst error spread line jumped backwards
adopting every sample 700ms 700ms 8 times
holding the anchor 200ms 200ms never

The remaining 200ms is the panel's own 250ms tick, which macOS shares. For a
player that reports precise positions the two are identical, so the change
costs nothing where it was not needed.

Also here:

  • Each player is now dated by its own read rather than by the sweep, taking
    the midpoint of the round trip. A shared timestamp taken before the reads
    ran the estimate ahead by however long they took, and an anchor holds that
    error for the length of a track.
  • PlaybackPosition.Project splits the unclamped projection out of
    Estimate, because asking whether playback has jumped is not a question
    about the track's length: a length that has not arrived yet clamped the
    comparison to zero and re-anchored on every poll.
  • The active-session tie-break no longer ranks on how recently a session was
    observed. Every candidate comes from one sweep, so that key now only
    favoured whichever player answered last, taking the choice away from the
    player id that keeps the panel from flickering.
  • Players are polled every 500ms rather than every second, matching macOS.

https://claude.ai/code/session_0164R7Zuagx737iKYbuuSjnA

Copilot AI lite review requested due to automatic review settings September 25, 2026 19:52
@aodjo
aodjo merged commit dfe5682 into develop Sep 25, 2026
8 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants