audio_output.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. #include "audio_output.h"
  2. #include "rtsp_server.h"
  3. #include "audio_resample.h"
  4. #include "dac.h"
  5. #include "led.h"
  6. #include "driver/i2s_std.h"
  7. #include "driver/gpio.h"
  8. #include "esp_check.h"
  9. #include "freertos/FreeRTOS.h"
  10. #include "freertos/task.h"
  11. #include "audio_receiver.h"
  12. #include <inttypes.h>
  13. #include <stdlib.h>
  14. // SIDE NOTE; providing power from GPIO pins is capped ~20mA.
  15. #if CONFIG_I2S_GND_IO >= 0
  16. #define I2S_GND_PIN CONFIG_I2S_GND_IO
  17. #endif
  18. #if CONFIG_I2S_VCC_IO >= 0
  19. #define I2S_VCC_PIN CONFIG_I2S_VCC_IO
  20. #endif
  21. // DACXSMT引脚必须拉高电平才能在外部DAC上启用输出
  22. #define DAC_XSMT_PIN 19
  23. #define TAG "audio_output"
  24. #define I2S_SCK_PIN CONFIG_I2S_SCK_IO
  25. #define I2S_BCK_PIN CONFIG_I2S_BCK_IO
  26. #define I2S_LRCK_PIN CONFIG_I2S_WS_IO
  27. #define I2S_DOUT_PIN CONFIG_I2S_DO_IO
  28. #define OUTPUT_RATE CONFIG_OUTPUT_SAMPLE_RATE_HZ
  29. #define FRAME_SAMPLES 352
  30. // DMA ring-buffer configuration. Total DMA latency (in samples) is
  31. // I2S_DMA_DESC_NUM × I2S_DMA_FRAME_NUM
  32. // which at OUTPUT_RATE gives the hardware pipeline delay in µs.
  33. // Keep these in sync with the i2s_chan_config_t initialisation below.
  34. #define I2S_DMA_DESC_NUM 8
  35. #define I2S_DMA_FRAME_NUM 256
  36. /* Max output frames after resampling one input frame */
  37. #define MAX_RESAMPLE_FRAMES \
  38. ((size_t)((FRAME_SAMPLES + 2) * ((double)OUTPUT_RATE / 44100) + 16))
  39. #if CONFIG_FREERTOS_UNICORE
  40. #define PLAYBACK_CORE 0
  41. #else
  42. #define PLAYBACK_CORE 1
  43. #endif
  44. static i2s_chan_handle_t tx_handle = NULL;
  45. static TaskHandle_t playback_task_handle = NULL;
  46. static volatile bool playback_running = false;
  47. static volatile bool flush_requested = false;
  48. static SemaphoreHandle_t s_audio_mutex = NULL;
  49. static volatile int source_rate = 44100;
  50. static volatile bool resample_reinit_needed = false;
  51. static volatile audio_channel_mode_t channel_mode = AUDIO_CHANNEL_STEREO;
  52. static void apply_volume(int16_t *buf, size_t n) {
  53. #ifndef CONFIG_DAC_CONTROLS_VOLUME
  54. int32_t vol = airplay_get_volume_q15();
  55. for (size_t i = 0; i < n; i++) {
  56. buf[i] = (int16_t)(((int32_t)buf[i] * vol) >> 15);
  57. }
  58. #endif
  59. }
  60. // Apply the selected channel mode to an interleaved stereo buffer (L,R,...).
  61. // LEFT/RIGHT route the chosen source channel to BOTH outputs so the selected
  62. // track is heard from both speakers; STEREO leaves the buffer untouched.
  63. static void apply_channel_mode(int16_t *buf, size_t frames) {
  64. audio_channel_mode_t mode = channel_mode;
  65. if (mode == AUDIO_CHANNEL_STEREO) {
  66. return;
  67. }
  68. size_t src = (mode == AUDIO_CHANNEL_RIGHT) ? 1 : 0;
  69. for (size_t i = 0; i < frames; i++) {
  70. int16_t s = buf[i * 2 + src];
  71. buf[i * 2] = s;
  72. buf[i * 2 + 1] = s;
  73. }
  74. }
  75. static void playback_task(void *arg) {
  76. int16_t *pcm = malloc((size_t)(FRAME_SAMPLES + 1) * 2 * sizeof(int16_t));
  77. int16_t *silence = calloc((size_t)FRAME_SAMPLES * 2, sizeof(int16_t));
  78. int16_t *resample_buf = malloc(MAX_RESAMPLE_FRAMES * 2 * sizeof(int16_t));
  79. if (!pcm || !silence || !resample_buf) {
  80. ESP_LOGE(TAG, "Failed to allocate buffers");
  81. free(pcm);
  82. free(silence);
  83. playback_task_handle = NULL;
  84. free(resample_buf);
  85. vTaskDelete(NULL);
  86. return;
  87. }
  88. size_t written;
  89. while (playback_running) {
  90. if (resample_reinit_needed) {
  91. resample_reinit_needed = false;
  92. audio_resample_init((uint32_t)source_rate, OUTPUT_RATE, 2);
  93. }
  94. if (flush_requested) {
  95. flush_requested = false;
  96. audio_resample_reset();
  97. i2s_channel_disable(tx_handle);
  98. i2s_channel_enable(tx_handle);
  99. }
  100. size_t samples = audio_receiver_read(pcm, FRAME_SAMPLES + 1);
  101. if (samples > 0) {
  102. if (s_audio_mutex) xSemaphoreTakeRecursive(s_audio_mutex, portMAX_DELAY);
  103. ESP_LOGD(TAG, "Read %u samples from receiver", (unsigned int)samples);
  104. int16_t *play_buf = pcm;
  105. size_t play_samples = samples;
  106. if (audio_resample_is_active()) {
  107. play_samples = audio_resample_process(pcm, samples, resample_buf,
  108. MAX_RESAMPLE_FRAMES);
  109. play_buf = resample_buf;
  110. }
  111. ESP_LOGD(TAG, "Resampled to %u samples", (unsigned int)play_samples);
  112. apply_volume(play_buf, play_samples * 2);
  113. apply_channel_mode(play_buf, play_samples);
  114. led_audio_feed(play_buf, play_samples);
  115. i2s_channel_write(tx_handle, play_buf, play_samples * 4, &written,
  116. portMAX_DELAY);
  117. if (s_audio_mutex) xSemaphoreGiveRecursive(s_audio_mutex);
  118. ESP_LOGD(TAG, "I2S write: %u bytes written", (unsigned int)written);
  119. taskYIELD();
  120. } else {
  121. // ESP_LOGW(TAG, "Receiver underflow - playing silence");
  122. led_audio_feed(silence, FRAME_SAMPLES);
  123. i2s_channel_write(tx_handle, silence, (size_t)FRAME_SAMPLES * 4, &written,
  124. pdMS_TO_TICKS(10));
  125. vTaskDelay(1);
  126. }
  127. }
  128. free(pcm);
  129. free(silence);
  130. playback_task_handle = NULL;
  131. vTaskDelete(NULL);
  132. }
  133. esp_err_t audio_output_init(void) {
  134. if (s_audio_mutex == NULL) {
  135. s_audio_mutex = xSemaphoreCreateRecursiveMutex();
  136. }
  137. i2s_chan_config_t chan_cfg =
  138. I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER);
  139. chan_cfg.dma_desc_num = I2S_DMA_DESC_NUM;
  140. chan_cfg.dma_frame_num = I2S_DMA_FRAME_NUM;
  141. ESP_RETURN_ON_ERROR(i2s_new_channel(&chan_cfg, &tx_handle, NULL), TAG,
  142. "channel create failed");
  143. i2s_std_config_t std_cfg = {
  144. .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(OUTPUT_RATE),
  145. .slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT,
  146. I2S_SLOT_MODE_STEREO),
  147. .gpio_cfg =
  148. {
  149. .mclk = I2S_SCK_PIN,
  150. .bclk = I2S_BCK_PIN,
  151. .ws = I2S_LRCK_PIN,
  152. .dout = I2S_DOUT_PIN,
  153. .din = I2S_GPIO_UNUSED,
  154. },
  155. };
  156. #ifdef I2S_GND_PIN
  157. gpio_reset_pin(I2S_GND_PIN);
  158. gpio_set_direction(I2S_GND_PIN, GPIO_MODE_OUTPUT);
  159. gpio_set_level(I2S_GND_PIN, 0);
  160. #endif
  161. #ifdef I2S_VCC_PIN
  162. gpio_reset_pin(I2S_VCC_PIN);
  163. gpio_set_direction(I2S_VCC_PIN, GPIO_MODE_OUTPUT);
  164. gpio_set_level(I2S_VCC_PIN, 1);
  165. #endif
  166. ESP_RETURN_ON_ERROR(i2s_channel_init_std_mode(tx_handle, &std_cfg), TAG,
  167. "std mode init failed");
  168. ESP_RETURN_ON_ERROR(i2s_channel_enable(tx_handle), TAG,
  169. "channel enable failed");
  170. ESP_LOGI(TAG, "I2S initialized: Rate=%u, DMA_Desc=%d, DMA_Frame=%d",
  171. (unsigned int)OUTPUT_RATE, I2S_DMA_DESC_NUM, I2S_DMA_FRAME_NUM);
  172. // DAC XSMT: pull high to enable external DAC output
  173. #ifdef DAC_XSMT_PIN
  174. gpio_reset_pin(DAC_XSMT_PIN);
  175. gpio_set_direction(DAC_XSMT_PIN, GPIO_MODE_OUTPUT);
  176. gpio_set_level(DAC_XSMT_PIN, 1);
  177. ESP_LOGI(TAG, "DAC XSMT pin %d set high", DAC_XSMT_PIN);
  178. #endif
  179. // MCLK/BCLK/LRCK are now running. Some codecs need this edge to finish their
  180. // clock setup; amplifiers that manage power from board RTSP events can ignore
  181. // the hook.
  182. dac_on_i2s_started();
  183. audio_resample_init(44100, OUTPUT_RATE, 2);
  184. return ESP_OK;
  185. }
  186. void audio_output_start(void) {
  187. if (playback_task_handle != NULL) {
  188. return; // already running
  189. }
  190. playback_running = true;
  191. xTaskCreatePinnedToCore(playback_task, "audio_play", 4096, NULL, 7,
  192. &playback_task_handle, PLAYBACK_CORE);
  193. }
  194. void audio_output_stop(void) {
  195. if (playback_task_handle == NULL) {
  196. return;
  197. }
  198. playback_running = false;
  199. // Wait for task to exit cleanly
  200. int timeout = 40;
  201. while (playback_task_handle != NULL && timeout-- > 0) {
  202. vTaskDelay(pdMS_TO_TICKS(50));
  203. }
  204. if (playback_task_handle != NULL) {
  205. ESP_LOGW(TAG, "Playback task did not exit within timeout");
  206. } else {
  207. ESP_LOGI(TAG, "Playback task stopped");
  208. }
  209. }
  210. esp_err_t audio_output_write(const void *data, size_t bytes, TickType_t wait) {
  211. size_t written = 0;
  212. if (s_audio_mutex) xSemaphoreTakeRecursive(s_audio_mutex, portMAX_DELAY);
  213. esp_err_t err = i2s_channel_write(tx_handle, data, bytes, &written, wait);
  214. if (s_audio_mutex) xSemaphoreGiveRecursive(s_audio_mutex);
  215. return err;
  216. }
  217. void audio_output_set_sample_rate(uint32_t rate) {
  218. // Only safe to call when no writer task is actively using I2S
  219. // (AirPlay playback task must be stopped, BT calls this before
  220. // the I2S writer task starts consuming data)
  221. ESP_LOGI(TAG, "Setting sample rate to %" PRIu32 " Hz", rate);
  222. if (tx_handle == NULL) {
  223. ESP_LOGW(TAG, "I2S 通道未初始化,跳过采样率时钟配置");
  224. return;
  225. }
  226. i2s_channel_disable(tx_handle);
  227. i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(rate);
  228. i2s_channel_reconfig_std_clock(tx_handle, &clk_cfg);
  229. i2s_channel_enable(tx_handle);
  230. }
  231. void audio_output_flush(void) {
  232. flush_requested = true;
  233. }
  234. void audio_output_lock(void) {
  235. if (s_audio_mutex) xSemaphoreTakeRecursive(s_audio_mutex, portMAX_DELAY);
  236. }
  237. void audio_output_unlock(void) {
  238. if (s_audio_mutex) xSemaphoreGiveRecursive(s_audio_mutex);
  239. }
  240. void audio_output_set_source_rate(int rate) {
  241. if (rate > 0 && rate != source_rate) {
  242. source_rate = rate;
  243. resample_reinit_needed = true;
  244. }
  245. }
  246. uint32_t audio_output_get_hardware_latency_us(void) {
  247. return (
  248. uint32_t)(((uint64_t)I2S_DMA_DESC_NUM * I2S_DMA_FRAME_NUM * 1000000ULL) /
  249. OUTPUT_RATE);
  250. }
  251. audio_channel_mode_t audio_output_cycle_channel_mode(void) {
  252. audio_channel_mode_t next;
  253. switch (channel_mode) {
  254. case AUDIO_CHANNEL_STEREO:
  255. next = AUDIO_CHANNEL_LEFT;
  256. break;
  257. case AUDIO_CHANNEL_LEFT:
  258. next = AUDIO_CHANNEL_RIGHT;
  259. break;
  260. default:
  261. next = AUDIO_CHANNEL_STEREO;
  262. break;
  263. }
  264. channel_mode = next;
  265. ESP_LOGI(TAG, "Channel mode: %s",
  266. next == AUDIO_CHANNEL_LEFT ? "LEFT only"
  267. : next == AUDIO_CHANNEL_RIGHT ? "RIGHT only"
  268. : "STEREO");
  269. return next;
  270. }
  271. audio_channel_mode_t audio_output_get_channel_mode(void) {
  272. return channel_mode;
  273. }