audio_timing.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. #include <inttypes.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "audio_timing.h"
  5. #include "audio_output.h"
  6. #include "esp_log.h"
  7. #include "esp_timer.h"
  8. #include "ntp_clock.h"
  9. #include "ptp_clock.h"
  10. #define DEFAULT_BUFFER_LATENCY_US 2000 // 2ms startup jitter buffer
  11. // Additional pipeline latency to account for task scheduling, I2S write
  12. // blocking, and resampler processing. Without this, frames pass the
  13. // timing check "on time" but actually exit the speaker several ms later.
  14. #define PIPELINE_LATENCY_US 5000 // ~5ms scheduling + write delay
  15. #define MIN_STARTUP_FRAMES 4
  16. #define DRIFT_ADJUST_THRESHOLD_FRAMES 2
  17. // Early/late threshold: how far a frame may be early (held as pending) or late
  18. // (dropped) before the timing engine acts. Buffered AirPlay 2 streams have a
  19. // deep jitter buffer so a tight threshold keeps sync without drop-outs.
  20. // Unbuffered realtime streams (ALAC/UDP) have almost no buffer to absorb
  21. // scheduling hiccups — e.g. when artwork/metadata arrives on the RTSP
  22. // connection — so they need a much looser threshold to avoid audible
  23. // drop-outs. Both are configurable via Kconfig.
  24. #ifdef CONFIG_AIRPLAY_TIMING_THRESHOLD_MS
  25. #define TIMING_THRESHOLD_US (CONFIG_AIRPLAY_TIMING_THRESHOLD_MS * 1000)
  26. #else
  27. #define TIMING_THRESHOLD_US 10000 // 10ms. early/late threshold (buffered)
  28. #endif
  29. #ifdef CONFIG_AIRPLAY_RT_TIMING_THRESHOLD_MS
  30. #define RT_TIMING_THRESHOLD_US (CONFIG_AIRPLAY_RT_TIMING_THRESHOLD_MS * 1000)
  31. #else
  32. #define RT_TIMING_THRESHOLD_US 50000 // 50ms early/late threshold (realtime)
  33. #endif
  34. // MAX_CONSECUTIVE_EARLY: safety valve — counts how many consecutive calls to
  35. // audio_timing_read returned silence because the pending frame was still too
  36. // early. Each call corresponds to one DMA period (~46 ms on I2S at 44100 Hz).
  37. // 50 calls × 46 ms ≈ 2.3 s: long enough that a legitimate pre-buffer of any
  38. // realistic depth will never hit it, short enough to detect a genuinely stuck
  39. // or invalid anchor in a few seconds.
  40. #define MAX_CONSECUTIVE_EARLY 50
  41. static const char *TAG = "audio_time";
  42. // consecutive_early_frames is now a field in audio_timing_t so it resets
  43. // automatically whenever a new anchor is set.
  44. static uint32_t frame_samples_from_format(const audio_format_t *format) {
  45. if (format->frame_size > 0) {
  46. return (uint32_t)format->frame_size;
  47. }
  48. if (format->max_samples_per_frame > 0) {
  49. return format->max_samples_per_frame;
  50. }
  51. return AAC_FRAMES_PER_PACKET;
  52. }
  53. static void update_timing_targets(audio_timing_t *timing,
  54. const audio_format_t *format) {
  55. timing->nominal_frame_samples = frame_samples_from_format(format);
  56. if (format->sample_rate <= 0 || timing->nominal_frame_samples == 0) {
  57. timing->target_buffer_frames = MIN_STARTUP_FRAMES;
  58. return;
  59. }
  60. uint64_t latency_samples =
  61. ((uint64_t)timing->output_latency_us * (uint64_t)format->sample_rate) /
  62. 1000000ULL;
  63. uint32_t target_frames =
  64. (uint32_t)((latency_samples + timing->nominal_frame_samples - 1) /
  65. timing->nominal_frame_samples);
  66. if (target_frames < MIN_STARTUP_FRAMES) {
  67. target_frames = MIN_STARTUP_FRAMES;
  68. }
  69. timing->target_buffer_frames = target_frames;
  70. }
  71. typedef enum {
  72. SYNC_MODE_NONE, // No clock sync, use local anchor time
  73. SYNC_MODE_PTP, // AirPlay 2 PTP sync
  74. SYNC_MODE_NTP, // AirPlay 1 NTP sync
  75. } sync_mode_t;
  76. // Compute how early (positive) or late (negative) a frame is in microseconds
  77. static bool compute_early_us(const audio_timing_t *timing,
  78. const audio_format_t *format,
  79. uint32_t rtp_timestamp, sync_mode_t sync_mode,
  80. int64_t *early_us) {
  81. if (!timing->anchor_valid || format->sample_rate <= 0) {
  82. return false;
  83. }
  84. int32_t rtp_delta = (int32_t)(rtp_timestamp - timing->anchor_rtp_time);
  85. int64_t frame_offset_ns =
  86. ((int64_t)rtp_delta * 1000000000LL) / format->sample_rate;
  87. int64_t target_ns;
  88. switch (sync_mode) {
  89. case SYNC_MODE_PTP:
  90. // AirPlay 2: use network time with PTP offset for multi-room sync
  91. target_ns = (int64_t)timing->anchor_network_time_ns -
  92. ptp_clock_get_offset_ns() + frame_offset_ns;
  93. break;
  94. case SYNC_MODE_NTP:
  95. // AirPlay 1: use network time with NTP offset for multi-room sync
  96. // offset = remote_time - local_time, so local = remote - offset
  97. target_ns = (int64_t)timing->anchor_network_time_ns -
  98. ntp_clock_get_offset_ns() + frame_offset_ns;
  99. break;
  100. default:
  101. // Fallback: use local anchor time (no multi-room sync)
  102. target_ns = timing->anchor_local_time_ns + frame_offset_ns;
  103. break;
  104. }
  105. // Subtract hardware latency to account for I2S DMA delay
  106. // and pipeline latency for task scheduling and write blocking.
  107. // The hardware latency is computed from the DMA descriptor/frame
  108. // configuration rather than being hard-coded.
  109. target_ns -=
  110. (int64_t)(audio_output_get_hardware_latency_us() + PIPELINE_LATENCY_US) *
  111. 1000LL;
  112. int64_t now_ns = (int64_t)esp_timer_get_time() * 1000LL;
  113. *early_us = (target_ns - now_ns) / 1000LL;
  114. return true;
  115. }
  116. void audio_timing_init(audio_timing_t *timing, size_t pending_capacity) {
  117. if (!timing) {
  118. return;
  119. }
  120. memset(timing, 0, sizeof(*timing));
  121. timing->output_latency_us = DEFAULT_BUFFER_LATENCY_US;
  122. timing->playing = true;
  123. if (pending_capacity > 0) {
  124. timing->pending_frame = (uint8_t *)malloc(pending_capacity);
  125. if (timing->pending_frame) {
  126. timing->pending_frame_capacity = pending_capacity;
  127. }
  128. }
  129. }
  130. void audio_timing_reset(audio_timing_t *timing) {
  131. if (!timing) {
  132. return;
  133. }
  134. timing->playout_started = false;
  135. timing->anchor_valid = false;
  136. timing->pending_valid = false;
  137. timing->pending_frame_len = 0;
  138. timing->ready_time_us = 0;
  139. timing->consecutive_early_frames = 0;
  140. timing->quick_start = false;
  141. timing->deferred_flush_pending = false;
  142. timing->flush_until_ts = 0;
  143. }
  144. void audio_timing_set_format(audio_timing_t *timing,
  145. const audio_format_t *format) {
  146. if (!timing || !format) {
  147. return;
  148. }
  149. update_timing_targets(timing, format);
  150. }
  151. void audio_timing_set_output_latency(audio_timing_t *timing,
  152. const audio_format_t *format,
  153. uint32_t latency_us) {
  154. if (!timing || !format) {
  155. return;
  156. }
  157. timing->output_latency_us = latency_us;
  158. update_timing_targets(timing, format);
  159. }
  160. uint32_t audio_timing_get_output_latency(const audio_timing_t *timing) {
  161. if (!timing) {
  162. return 0;
  163. }
  164. return timing->output_latency_us;
  165. }
  166. uint32_t audio_timing_get_hardware_latency(void) {
  167. return audio_output_get_hardware_latency_us();
  168. }
  169. uint32_t audio_timing_get_advertised_latency(const audio_timing_t *timing) {
  170. // Total end-to-end latency between the phone scheduling a frame and the
  171. // DAC emitting it. Reported to the phone in outputLatencyMicros so it
  172. // schedules sends to land in our sorted buffer at the right time.
  173. //
  174. // output_latency_us — controller target (jitter-buffer depth)
  175. // + audio_output_get_hardware_latency_us() — I2S DMA delay (dynamic)
  176. // + PIPELINE_LATENCY_US — scheduling + write delay constant
  177. uint32_t base =
  178. timing ? timing->output_latency_us : DEFAULT_BUFFER_LATENCY_US;
  179. return base + audio_output_get_hardware_latency_us() + PIPELINE_LATENCY_US;
  180. }
  181. void audio_timing_set_anchor(audio_timing_t *timing,
  182. const audio_format_t *format, uint64_t clock_id,
  183. uint64_t network_time_ns, uint32_t rtp_time) {
  184. if (!timing || !format) {
  185. return;
  186. }
  187. (void)clock_id;
  188. int64_t now_ns = (int64_t)esp_timer_get_time() * 1000LL;
  189. timing->anchor_rtp_time = rtp_time;
  190. timing->anchor_network_time_ns = network_time_ns;
  191. timing->anchor_local_time_ns = now_ns;
  192. timing->ptp_locked = ptp_clock_is_locked();
  193. timing->anchor_valid = true;
  194. // Reset frame counters so pre-buffered audio after a pause/resume or
  195. // track skip does not accumulate into the new anchor's counts.
  196. timing->consecutive_early_frames = 0;
  197. // Compute lead time: how far in the future this anchor's network timestamp
  198. // is relative to now. Negative means the anchor is already in the past
  199. // (normal: the phone pre-buffers and the anchor is 200–800 ms old by the
  200. // time we receive it).
  201. int64_t lead_ms = ((int64_t)network_time_ns -
  202. (int64_t)(ptp_clock_get_offset_ns() + now_ns)) /
  203. 1000000LL;
  204. ESP_LOGI(
  205. TAG,
  206. "Anchor set: rtp=%" PRIu32 " lead=%lld ms ptp_locked=%d quick_start=%d",
  207. rtp_time, (long long)lead_ms, timing->ptp_locked, timing->quick_start);
  208. }
  209. void audio_timing_set_playing(audio_timing_t *timing, bool playing) {
  210. if (!timing) {
  211. return;
  212. }
  213. ESP_LOGI(TAG, "set_playing: %s -> %s", timing->playing ? "playing" : "paused",
  214. playing ? "playing" : "paused");
  215. timing->playing = playing;
  216. if (!playing) {
  217. // Discard any partially-pending frame so resume starts cleanly from
  218. // the oldest frame in the sorted buffer.
  219. timing->pending_valid = false;
  220. timing->pending_frame_len = 0;
  221. }
  222. }
  223. size_t audio_timing_read(audio_timing_t *timing, audio_buffer_t *buffer,
  224. const audio_stream_t *stream, audio_stats_t *stats,
  225. int16_t *out, size_t samples) {
  226. if (!timing || !buffer || !stream || !out || samples == 0) {
  227. return 0;
  228. }
  229. if (!timing->playing) {
  230. return 0;
  231. }
  232. const audio_format_t *format = &stream->format;
  233. int buffered_frames = audio_buffer_get_frame_count(buffer);
  234. // Unbuffered realtime streams (ALAC/UDP) get a looser early/late threshold
  235. // than buffered AirPlay 2 streams, because they have little jitter buffer to
  236. // absorb scheduling hiccups and would otherwise drop frames (audible
  237. // drop-outs) whenever the pipeline stalls — e.g. while artwork/metadata is
  238. // received on the RTSP connection.
  239. const int64_t timing_threshold_us = audio_stream_uses_buffer(stream->type)
  240. ? TIMING_THRESHOLD_US
  241. : RT_TIMING_THRESHOLD_US;
  242. // Wait for enough buffer before starting.
  243. // In quick_start mode (after a seek/skip), start as soon as 1 frame is
  244. // available to minimise the gap between tracks. Anchor-based timing
  245. // still applies — if the frame is early, silence is output until its
  246. // scheduled play time, just like shairport-sync.
  247. // Normal startup waits for target_buffer_frames to build jitter margin.
  248. if (!timing->playout_started && !timing->pending_valid) {
  249. int required = timing->quick_start ? 1 : (int)timing->target_buffer_frames;
  250. if (buffered_frames < required) {
  251. return 0;
  252. }
  253. // Wait for anchor before playing.
  254. // Normal startup: allow a 1-second fallback so a stream with no anchor
  255. // (e.g. AirPlay 1 without NTP) can still start.
  256. if (!timing->anchor_valid) {
  257. int64_t now_us = esp_timer_get_time();
  258. if (timing->ready_time_us == 0) {
  259. timing->ready_time_us = now_us;
  260. }
  261. if (now_us - timing->ready_time_us < 1000000) {
  262. return 0; // Still waiting for anchor
  263. }
  264. // Waited 1 second, no anchor - proceed without sync
  265. }
  266. }
  267. // Determine sync mode: PTP (AirPlay 2), NTP (AirPlay 1), or local fallback
  268. sync_mode_t sync_mode = SYNC_MODE_NONE;
  269. if (ptp_clock_is_locked()) {
  270. sync_mode = SYNC_MODE_PTP;
  271. } else if (ntp_clock_is_locked()) {
  272. sync_mode = SYNC_MODE_NTP;
  273. }
  274. // Drain up to MAX_DRAIN_ATTEMPTS late/invalid frames within a SINGLE
  275. // DMA callback. The previous limit of 8 was the root cause of run-away
  276. // lateness: each call that returned silence (instead of playing a frame)
  277. // forfeited ~23 ms of RTP advancement while wall time kept moving, so
  278. // every late frame we dropped MADE us more late. Draining many frames
  279. // in one pass advances RTP at zero wall-time cost and lets the buffer
  280. // skip past stale data without the DMA ever idling.
  281. enum { MAX_DRAIN_ATTEMPTS = 256 };
  282. for (int attempt = 0; attempt < MAX_DRAIN_ATTEMPTS; attempt++) {
  283. size_t item_size = 0;
  284. void *item = NULL;
  285. bool from_pending = false;
  286. // Get frame from pending or buffer
  287. if (timing->pending_valid) {
  288. item_size = timing->pending_frame_len;
  289. if (item_size < sizeof(audio_frame_header_t)) {
  290. timing->pending_valid = false;
  291. timing->pending_frame_len = 0;
  292. continue;
  293. }
  294. item = timing->pending_frame;
  295. from_pending = true;
  296. } else {
  297. if (!audio_buffer_take(buffer, &item, &item_size, 0)) {
  298. if (stats) {
  299. stats->buffer_underruns++;
  300. }
  301. return 0;
  302. }
  303. buffered_frames = audio_buffer_get_frame_count(buffer);
  304. if (item_size < sizeof(audio_frame_header_t)) {
  305. audio_buffer_return(buffer, item);
  306. continue;
  307. }
  308. }
  309. audio_frame_header_t *hdr = (audio_frame_header_t *)item;
  310. size_t frame_samples = hdr->samples_per_channel;
  311. size_t channels = hdr->channels ? hdr->channels : format->channels;
  312. int16_t *pcm = (int16_t *)(hdr + 1);
  313. // Validate frame
  314. if (frame_samples == 0 || channels == 0) {
  315. if (from_pending) {
  316. timing->pending_valid = false;
  317. timing->pending_frame_len = 0;
  318. } else {
  319. audio_buffer_return(buffer, item);
  320. }
  321. continue;
  322. }
  323. size_t expected_bytes =
  324. sizeof(*hdr) + frame_samples * channels * sizeof(int16_t);
  325. if (item_size < expected_bytes) {
  326. if (from_pending) {
  327. timing->pending_valid = false;
  328. timing->pending_frame_len = 0;
  329. } else {
  330. audio_buffer_return(buffer, item);
  331. }
  332. continue;
  333. }
  334. if (frame_samples > samples) {
  335. frame_samples = samples;
  336. }
  337. // Deferred flush check (AirPlay 2 FLUSHBUFFERED with flushFromSeq):
  338. // keep playing until the frame whose RTP timestamp reaches flush_until_ts,
  339. // then bulk-flush the remainder of the buffer and start fresh.
  340. // Signed 32-bit subtraction handles RTP wraparound correctly.
  341. if (timing->deferred_flush_pending) {
  342. if ((int32_t)(hdr->rtp_timestamp - timing->flush_until_ts) >= 0) {
  343. ESP_LOGI(TAG,
  344. "Deferred flush triggered at ts=%" PRIu32 " (until_ts=%" PRIu32
  345. ")",
  346. hdr->rtp_timestamp, timing->flush_until_ts);
  347. if (from_pending) {
  348. timing->pending_valid = false;
  349. timing->pending_frame_len = 0;
  350. } else {
  351. audio_buffer_return(buffer, item);
  352. }
  353. audio_buffer_flush(buffer);
  354. timing->deferred_flush_pending = false;
  355. timing->playout_started = false;
  356. timing->ready_time_us = 0;
  357. timing->consecutive_early_frames = 0;
  358. // quick_start so the first frame of the next track starts playing
  359. // as soon as 1 frame arrives, with normal anchor timing applied.
  360. timing->quick_start = true;
  361. return 0;
  362. }
  363. }
  364. // Handle early/late frames based on anchor timing.
  365. //
  366. // After a seek/flush, anchor-based timing is applied immediately from the
  367. // first frame — no bypass. With a stable PTP clock the anchor is
  368. // accurate, so early frames are held as pending (silence output) until
  369. // their scheduled play time, and late frames are dropped. This mirrors
  370. // shairport-sync's approach and guarantees the first audible sample is
  371. // correctly synchronised.
  372. if (timing->anchor_valid && format->sample_rate > 0) {
  373. int64_t early_us = 0;
  374. if (compute_early_us(timing, format, hdr->rtp_timestamp, sync_mode,
  375. &early_us)) {
  376. if (early_us > timing_threshold_us) {
  377. // Only advance the stuck-anchor counter for NEW frames taken from
  378. // the buffer — not for pending re-checks of the same early frame.
  379. // A pending frame is re-examined every DMA callback (~8 ms) while
  380. // we wait for wall-clock to reach its scheduled play time. Counting
  381. // those re-checks would fire the stuck-anchor detector in
  382. // (MAX_CONSECUTIVE_EARLY × 8 ms) = 6 s even for a legitimately
  383. // early frame that just needs to wait its pre-buffer depth (~1.5 s).
  384. if (!from_pending) {
  385. timing->consecutive_early_frames++;
  386. // Log the first early frame after each anchor set (shows lead
  387. // time before audio starts) and every 50 new frames after that
  388. // (confirms the counter only counts real buffer reads, not
  389. // pending re-checks).
  390. if (timing->consecutive_early_frames == 1) {
  391. ESP_LOGI(TAG,
  392. "First early frame: rtp=%" PRIu32 " early=%.1f ms"
  393. " quick_start=%d buffered=%d",
  394. hdr->rtp_timestamp, (float)early_us / 1000.0f,
  395. timing->quick_start, buffered_frames);
  396. } else if (timing->consecutive_early_frames % 50 == 0) {
  397. ESP_LOGD(TAG, "Early counter: %d/%d early=%.1f ms rtp=%" PRIu32,
  398. timing->consecutive_early_frames, MAX_CONSECUTIVE_EARLY,
  399. (float)early_us / 1000.0f, hdr->rtp_timestamp);
  400. }
  401. }
  402. // If we have had an implausibly long run of early frames the anchor
  403. // is probably stuck or wrong — give up on it so playback can
  404. // continue. This threshold is high enough (~17 s at 23 ms/frame)
  405. // that it never fires during normal pre-buffered-audio scenarios.
  406. if (timing->consecutive_early_frames > MAX_CONSECUTIVE_EARLY) {
  407. ESP_LOGW(TAG,
  408. "Invalidating stuck anchor: consecutive=%d, early=%lld ms",
  409. timing->consecutive_early_frames, early_us / 1000LL);
  410. timing->anchor_valid = false;
  411. timing->consecutive_early_frames = 0;
  412. // Fall through to play the frame normally
  413. } else {
  414. // Frame is early — store it as pending and output silence.
  415. // The pending frame is re-checked on every subsequent call;
  416. // once wall-clock catches up it will be played on time.
  417. // This is the normal path for pre-buffered audio after a pause.
  418. static int early_count = 0;
  419. early_count++;
  420. if (early_count % 100 == 1) {
  421. ESP_LOGD(TAG,
  422. "Frame too early #%d: %lld ms, buffered=%d, pending=%d",
  423. early_count, early_us / 1000LL, buffered_frames,
  424. timing->pending_valid ? 1 : 0);
  425. }
  426. if (!from_pending && timing->pending_frame &&
  427. item_size <= timing->pending_frame_capacity) {
  428. memcpy(timing->pending_frame, item, item_size);
  429. timing->pending_frame_len = item_size;
  430. timing->pending_valid = true;
  431. audio_buffer_return(buffer, item);
  432. }
  433. memset(out, 0, samples * channels * sizeof(int16_t));
  434. return samples;
  435. }
  436. } else if (early_us < -timing_threshold_us) {
  437. // Reset consecutive early counter on late/normal frames
  438. timing->consecutive_early_frames = 0;
  439. // Late frame — drop it and continue draining within the SAME call.
  440. // The 256-attempt drain loop chews through stale frames at zero
  441. // wall-time cost, skipping past arbitrarily many stale frames in
  442. // one pass without the DMA ever idling.
  443. ESP_LOGW(TAG, "Dropping late frame: %lld ms", -early_us / 1000LL);
  444. if (stats) {
  445. stats->late_frames++;
  446. }
  447. if (from_pending) {
  448. timing->pending_valid = false;
  449. timing->pending_frame_len = 0;
  450. } else {
  451. audio_buffer_return(buffer, item);
  452. }
  453. continue;
  454. }
  455. }
  456. }
  457. // Frame is on time (or anchor-invalid) — reset counter.
  458. timing->consecutive_early_frames = 0;
  459. // Copy PCM data to output
  460. memcpy(out, pcm, frame_samples * channels * sizeof(int16_t));
  461. // Cleanup
  462. if (from_pending) {
  463. timing->pending_valid = false;
  464. timing->pending_frame_len = 0;
  465. } else {
  466. audio_buffer_return(buffer, item);
  467. }
  468. if (!timing->playout_started) {
  469. timing->playout_started = true;
  470. bool was_quick = timing->quick_start;
  471. timing->quick_start = false;
  472. ESP_LOGI(TAG, "Playout started%s: rtp=%" PRIu32,
  473. was_quick ? " (quick_start)" : "", hdr->rtp_timestamp);
  474. }
  475. return frame_samples;
  476. }
  477. return 0;
  478. }