audio_receiver.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. #pragma once
  2. #include "esp_err.h"
  3. #include <stdbool.h>
  4. #include <stddef.h>
  5. #include <stdint.h>
  6. /**
  7. * Audio receiver for AirPlay RTP streams
  8. * Handles UDP packet reception and audio decoding
  9. */
  10. // Audio format info from ANNOUNCE SDP
  11. typedef struct {
  12. char codec[32]; // "AppleLossless", "AAC", etc.
  13. int sample_rate; // 44100, 48000, etc.
  14. int channels; // 1 or 2
  15. int bits_per_sample; // 16, 24
  16. int frame_size; // Samples per frame (ALAC: 352)
  17. // ALAC-specific config (from fmtp line)
  18. uint32_t max_samples_per_frame;
  19. uint8_t sample_size;
  20. uint8_t rice_history_mult;
  21. uint8_t rice_initial_history;
  22. uint8_t rice_limit;
  23. uint8_t num_channels;
  24. uint16_t max_run;
  25. uint32_t max_coded_frame_size;
  26. uint32_t avg_bit_rate;
  27. uint32_t sample_rate_config;
  28. } audio_format_t;
  29. // Audio encryption types
  30. typedef enum {
  31. AUDIO_ENCRYPT_NONE = 0,
  32. AUDIO_ENCRYPT_AES_CBC,
  33. AUDIO_ENCRYPT_CHACHA20_POLY1305
  34. } audio_encrypt_type_t;
  35. // Audio encryption configuration
  36. typedef struct {
  37. audio_encrypt_type_t type;
  38. uint8_t key[32]; // AES-128 uses 16, ChaCha20 uses 32
  39. uint8_t iv[16]; // AES-CBC IV
  40. size_t key_len;
  41. } audio_encrypt_t;
  42. // Audio buffer statistics
  43. typedef struct {
  44. uint32_t packets_received;
  45. uint32_t packets_decoded;
  46. uint32_t packets_dropped;
  47. uint32_t decrypt_errors;
  48. uint32_t buffer_underruns;
  49. uint32_t buffer_overruns;
  50. uint32_t late_frames;
  51. uint16_t last_seq;
  52. uint32_t last_timestamp;
  53. } audio_stats_t;
  54. /**
  55. * Initialize audio receiver
  56. */
  57. esp_err_t audio_receiver_init(void);
  58. /**
  59. * Set audio format from ANNOUNCE SDP
  60. */
  61. void audio_receiver_set_format(const audio_format_t *format);
  62. /**
  63. * Set encryption parameters for RTP decryption
  64. */
  65. void audio_receiver_set_encryption(const audio_encrypt_t *encrypt);
  66. /**
  67. * Start receiving audio on specified port
  68. */
  69. esp_err_t audio_receiver_start(uint16_t data_port, uint16_t control_port);
  70. /**
  71. * Start the active stream type using the provided ports.
  72. */
  73. esp_err_t audio_receiver_start_stream(uint16_t data_port, uint16_t control_port,
  74. uint16_t tcp_port);
  75. /**
  76. * Stop receiving audio
  77. */
  78. void audio_receiver_stop(void);
  79. /**
  80. * Get audio statistics
  81. */
  82. void audio_receiver_get_stats(audio_stats_t *stats);
  83. /**
  84. * Read decoded PCM samples from buffer
  85. * @param buffer Output buffer for PCM samples (interleaved stereo, 16-bit)
  86. * @param samples Maximum number of samples to read (per channel)
  87. * @return Number of samples actually read
  88. */
  89. size_t audio_receiver_read(int16_t *buffer, size_t samples);
  90. /**
  91. * Check if audio data is available
  92. */
  93. bool audio_receiver_has_data(void);
  94. /**
  95. * Flush audio buffer (full stop path — used by TEARDOWN and stop).
  96. */
  97. void audio_receiver_flush(void);
  98. /**
  99. * Flush audio buffer for a mid-stream seek (FLUSH / immediate FLUSHBUFFERED).
  100. * Identical to audio_receiver_flush() but also sets timing.post_flush so
  101. * that audio_timing_read plays frames immediately after the seek instead of
  102. * silencing them during the phone's pre-buffer window (which can be several
  103. * seconds with AirPlay 2 buffered streams). Mirrors shairport-sync's
  104. * first_packet_timestamp==0 behaviour: post-flush frames play unconditionally
  105. * until the anchor reports on-time (early_us < TIMING_THRESHOLD_US).
  106. */
  107. void audio_receiver_seek_flush(void);
  108. /**
  109. * Arm a deferred flush for AirPlay 2 FLUSHBUFFERED with flushFromSeq.
  110. *
  111. * Instead of discarding the buffer immediately, audio_timing_read will
  112. * continue playing normally until it encounters a frame whose rtp_timestamp
  113. * >= flush_until_ts, at which point it bulk-flushes the remainder and sets
  114. * post_flush so the next track starts without delay.
  115. *
  116. * @param flush_until_ts RTP timestamp boundary from flushUntilTS plist key.
  117. */
  118. void audio_receiver_set_deferred_flush(uint32_t flush_until_ts);
  119. /**
  120. * Pause playback while preserving the timing anchor.
  121. * Flushes the audio buffer and resets playback-start state, but does NOT
  122. * call audio_timing_reset() so the anchor remains valid. The pause start
  123. * time is recorded so that audio_receiver_set_playing(true) can compensate
  124. * for the pause duration on resume.
  125. */
  126. void audio_receiver_pause(void);
  127. /**
  128. * Set advertised/target output latency in microseconds.
  129. */
  130. void audio_receiver_set_output_latency_us(uint32_t latency_us);
  131. /**
  132. * Get current output latency in microseconds (buffer latency only).
  133. */
  134. uint32_t audio_receiver_get_output_latency_us(void);
  135. /**
  136. * Get hardware output latency in microseconds (I2S DMA pipeline delay).
  137. */
  138. uint32_t audio_receiver_get_hardware_latency_us(void);
  139. /**
  140. * Get total advertised latency in microseconds. Includes the jitter-buffer
  141. * target depth, hardware DMA delay, and fixed decrypt/decode/network
  142. * pipeline constant. Report this in outputLatencyMicros so the phone
  143. * schedules sends to match our actual end-to-end depth.
  144. */
  145. uint32_t audio_receiver_get_advertised_latency_us(void);
  146. /**
  147. * Provide anchor timing information from SETRATEANCHORTIME.
  148. * @param clock_id PTP clock ID (networkTimeTimelineID)
  149. * @param network_time_ns Anchor time in nanoseconds (PTP timeline)
  150. * @param rtp_time RTP timestamp for the anchor
  151. */
  152. void audio_receiver_set_anchor_time(uint64_t clock_id, uint64_t network_time_ns,
  153. uint32_t rtp_time);
  154. /**
  155. * Enable or pause playout scheduling.
  156. */
  157. void audio_receiver_set_playing(bool playing);
  158. /**
  159. * Check if playback is currently active (not paused).
  160. */
  161. bool audio_receiver_is_playing(void);
  162. /**
  163. * Reset timing anchor (call when PTP clock changes, e.g., SETPEERS)
  164. */
  165. void audio_receiver_reset_timing(void);
  166. /**
  167. * Set the client's control address for NACK retransmission requests.
  168. * @param client_ip Client IP in network byte order
  169. * @param client_control_port Client's control port (host byte order)
  170. */
  171. void audio_receiver_set_client_control(uint32_t client_ip,
  172. uint16_t client_control_port);
  173. /**
  174. * Stream types for AirPlay 2
  175. */
  176. typedef enum {
  177. AUDIO_STREAM_NONE = 0,
  178. AUDIO_STREAM_REALTIME = 96, // UDP, ALAC
  179. AUDIO_STREAM_BUFFERED = 103 // TCP, AAC-ELD
  180. } audio_stream_type_t;
  181. /**
  182. * Start buffered audio receiver (type=103) on TCP port
  183. * @param tcp_port Port to listen on for TCP connections
  184. * @return ESP_OK on success
  185. */
  186. esp_err_t audio_receiver_start_buffered(uint16_t tcp_port);
  187. /**
  188. * Get the active stream port (data or buffered).
  189. */
  190. uint16_t audio_receiver_get_stream_port(void);
  191. /**
  192. * Get the TCP port for buffered audio (after start_buffered)
  193. */
  194. uint16_t audio_receiver_get_buffered_port(void);
  195. /**
  196. * Stop only the buffered receiver but keep playing buffered data
  197. * Used when TEARDOWN with streams array is received (sender done sending)
  198. */
  199. void audio_receiver_stop_buffered_only(void);
  200. /**
  201. * Set the stream type (realtime vs buffered)
  202. */
  203. void audio_receiver_set_stream_type(audio_stream_type_t type);