Files
aes67-ESP32-P4/main/audio_ring.h
T
bsncubed b8702e6faa Spotify: tell cspot when a new track becomes audible
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>
2026-09-25 20:47:28 +10:00

19 lines
876 B
C

// Single-producer / single-consumer ring of interleaved int32 frames in PSRAM.
// The producer is a source task, the consumer the AES67 TX pull callback (must never block).
#pragma once
#include <stddef.h>
#include <stdint.h>
#include "esp_err.h"
esp_err_t audio_ring_init(size_t capacity_frames, int channels);
size_t audio_ring_level(void); // frames available to read
size_t audio_ring_space(void); // frames that can be written
size_t audio_ring_write(const int32_t *frames, size_t n); // producer; returns frames written
size_t audio_ring_read(int32_t *frames, size_t n); // consumer; returns frames read
void audio_ring_flush(void); // consumer side: drop everything buffered
// Monotonic frame counters (wrap at 2^32): frames written so far / read (played) so far.
uint32_t audio_ring_written(void);
uint32_t audio_ring_read_pos(void);