b8702e6faa
The Mac dropped the device soon after the first track change: we never
called SpircHandler::notifyAudioReachedPlayback(), so cspot's queue did
not advance and the state sent to Spotify stalled.
- The data callback records a boundary (output write position, track
id) when the track id changes; the session loop (<= 200 ms) calls
notifyAudioReachedPlayback(id) once playback (ring read position)
passes it, and notifyAudioEnded() after DEPLETED once the buffer is
empty. PLAYBACK_START clears boundaries (next data is a new one),
seek/flush drop pending ones.
- audio_ring exposes its write/read frame counters (wrap-safe compare).
- Verified: 10 min on the Mac without a disconnect, every track change
notified ("track audible, Spotify notified"), app shows the playing
track (switches up to ~3-5 s early), 0 underruns.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>