output_i2s.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. /*
  2. * Squeezelite for esp32
  3. *
  4. * (c) Sebastien 2019
  5. * Philippe G. 2019, philippe_44@outlook.com
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. *
  20. */
  21. /*
  22. Synchronisation is almost broken with i2s. The esp32 driver is not clear
  23. about what it does when it starts, not when sampling rate changes (which
  24. does stop/start). For example, if no frame is provided using i2_write, it
  25. cycle on the last buffer or something like that.
  26. But above that, when squeezelite wants to get current time (output.updated)
  27. and number of frames sent at that time (outout.frames_played_dmp), this
  28. should be corrected by the number of frames in the pipepline of I2S
  29. (output.device_frames) but that value is unknown so all we can do is assuming
  30. that every time we assess these values, the I2S DMA is full so that at least
  31. we have a consitent matching between time & frames. This is not a solid
  32. hypothesis.
  33. It seems that to maximize that probability, the amount of frames written
  34. using i2s_write must be a divider of dma_buf_len otherwise when i2s_write
  35. returns, the fullness of the DMA buffer varies and as a result there is a
  36. big jitter in the time/frame matching and LMS then constantly adjust player's
  37. timing. A solution is to not use AccuratePlayPloint to force LMS to average
  38. these values (reported in STMt) but then if there is a gap at the beginning,
  39. it lasts for a while
  40. Even more complicated, I2S introduces a systematic delay of silence, counted
  41. in frames and equal to the size of the sum of DMA buffers. When LMS requests to
  42. "startAt", in reality, we start at the required time + the delay corresponding
  43. to this number of frames, which in ms changes with the sampling rate!
  44. Compensating that delay in LMS's UI works for a given sampling rate, but is
  45. different for every sampplin rate so this does not work either. For example,
  46. with 16 buffers of 512 bytes @ 44100, the delay is 16*512/44100 = 185 ms.
  47. Trying to compensate that delay inside squeezelite does not work well either
  48. because LMS sends a "startAt" which is only 150~200ms after present time and
  49. that might be less than the duration of the whole DMA buffer, so we can't
  50. anticpate what is already past
  51. Another issue is that when pause is requested, the part of the track which is
  52. in the DMA buffers will be played no matter what. We can't use i2s_stop and
  53. i2s_start as i2s_start seems to mess-up with buffer (in a not very clean or
  54. clear way). So the track will audibly stop a bit after pause is pressed, but
  55. more problem comes with the un-pause because LMS is not told that these frames
  56. have been played and in addition the "startAt" will have the same issue as the
  57. initial "startAt"
  58. So this is a lot of fun and I've not yet found a good solution
  59. */
  60. #include "squeezelite.h"
  61. #include "driver/i2s.h"
  62. #include "perf_trace.h"
  63. #include <signal.h>
  64. #include "time.h"
  65. #define LOCK mutex_lock(outputbuf->mutex)
  66. #define UNLOCK mutex_unlock(outputbuf->mutex)
  67. //#define FRAME_BLOCK MAX_SILENCE_FRAMES
  68. #define FRAME_BLOCK 512
  69. // Prevent compile errors if dac output is
  70. // included in the build and not actually activated in menuconfig
  71. #ifndef CONFIG_I2S_BCK_IO
  72. #define CONFIG_I2S_BCK_IO -1
  73. #endif
  74. #ifndef CONFIG_I2S_WS_IO
  75. #define CONFIG_I2S_WS_IO -1
  76. #endif
  77. #ifndef CONFIG_I2S_DO_IO
  78. #define CONFIG_I2S_DO_IO -1
  79. #endif
  80. #ifndef CONFIG_I2S_NUM
  81. #define CONFIG_I2S_NUM -1
  82. #endif
  83. #define DMA_BUF_COUNT 16
  84. #define DECLARE_ALL_MIN_MAX \
  85. DECLARE_MIN_MAX(o); \
  86. DECLARE_MIN_MAX(s); \
  87. DECLARE_MIN_MAX(rec); \
  88. DECLARE_MIN_MAX(i2s_time); \
  89. DECLARE_MIN_MAX(buffering);
  90. #define RESET_ALL_MIN_MAX \
  91. RESET_MIN_MAX(o); \
  92. RESET_MIN_MAX(s); \
  93. RESET_MIN_MAX(rec); \
  94. RESET_MIN_MAX(i2s_time); \
  95. RESET_MIN_MAX(buffering);
  96. #define STATS_PERIOD_MS 5000
  97. extern struct outputstate output;
  98. extern struct buffer *streambuf;
  99. extern struct buffer *outputbuf;
  100. extern u8_t *silencebuf;
  101. static log_level loglevel;
  102. static bool running, isI2SStarted;
  103. static i2s_config_t i2s_config;
  104. static int bytes_per_frame;
  105. static thread_type thread, stats_thread;
  106. static u8_t *obuf;
  107. DECLARE_ALL_MIN_MAX;
  108. static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR,
  109. s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr);
  110. static void *output_thread_i2s();
  111. static void *output_thread_i2s_stats();
  112. /****************************************************************************************
  113. * Initialize the DAC output
  114. */
  115. void output_init_i2s(log_level level, char *device, unsigned output_buf_size, char *params, unsigned rates[], unsigned rate_delay, unsigned idle) {
  116. loglevel = level;
  117. #ifdef CONFIG_I2S_BITS_PER_CHANNEL
  118. switch (CONFIG_I2S_BITS_PER_CHANNEL) {
  119. case 24:
  120. output.format = S24_BE;
  121. bytes_per_frame = 2*3;
  122. break;
  123. case 16:
  124. output.format = S16_BE;
  125. bytes_per_frame = 2*2;
  126. break;
  127. case 8:
  128. output.format = S8_BE;
  129. bytes_per_frame = 2*4;
  130. break;
  131. default:
  132. LOG_ERROR("Unsupported bit depth %d",CONFIG_I2S_BITS_PER_CHANNEL);
  133. break;
  134. }
  135. #else
  136. output.format = S16_LE;
  137. bytes_per_frame = 2*2;
  138. #endif
  139. output.write_cb = &_i2s_write_frames;
  140. obuf = malloc(FRAME_BLOCK * bytes_per_frame);
  141. if (!obuf) {
  142. LOG_ERROR("Cannot allocate i2s buffer");
  143. return;
  144. }
  145. running=true;
  146. i2s_config.mode = I2S_MODE_MASTER | I2S_MODE_TX; // Only TX
  147. i2s_config.sample_rate = output.current_sample_rate;
  148. i2s_config.bits_per_sample = bytes_per_frame * 8 / 2;
  149. i2s_config.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT; //2-channels
  150. i2s_config.communication_format = I2S_COMM_FORMAT_I2S| I2S_COMM_FORMAT_I2S_MSB;
  151. i2s_config.dma_buf_count = DMA_BUF_COUNT;
  152. // Counted in frames (but i2s allocates a buffer <= 4092 bytes)
  153. i2s_config.dma_buf_len = FRAME_BLOCK;
  154. i2s_config.use_apll = true;
  155. i2s_config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1; //Interrupt level 1
  156. i2s_pin_config_t pin_config = { .bck_io_num = CONFIG_I2S_BCK_IO, .ws_io_num =
  157. CONFIG_I2S_WS_IO, .data_out_num = CONFIG_I2S_DO_IO, .data_in_num = -1 //Not used
  158. };
  159. LOG_INFO("Initializing I2S with rate: %d, bits per sample: %d, buffer len: %d, number of buffers: %d ",
  160. i2s_config.sample_rate, i2s_config.bits_per_sample, i2s_config.dma_buf_len, i2s_config.dma_buf_count);
  161. i2s_driver_install(CONFIG_I2S_NUM, &i2s_config, 0, NULL);
  162. i2s_set_pin(CONFIG_I2S_NUM, &pin_config);
  163. i2s_set_clk(CONFIG_I2S_NUM, output.current_sample_rate, i2s_config.bits_per_sample, 2);
  164. i2s_zero_dma_buffer(CONFIG_I2S_NUM);
  165. i2s_stop(CONFIG_I2S_NUM);
  166. isI2SStarted=false;
  167. pthread_attr_t attr;
  168. pthread_attr_init(&attr);
  169. pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN + OUTPUT_THREAD_STACK_SIZE);
  170. pthread_create_name(&thread, &attr, output_thread_i2s, NULL, "output_i2s");
  171. pthread_attr_destroy(&attr);
  172. // leave stack size to default
  173. pthread_create_name(&stats_thread, NULL, output_thread_i2s_stats, NULL, "output_i2s_sts");
  174. }
  175. /****************************************************************************************
  176. * Terminate DAC output
  177. */
  178. void output_close_i2s(void) {
  179. LOCK;
  180. running = false;
  181. UNLOCK;
  182. pthread_join(thread, NULL);
  183. pthread_join(stats_thread, NULL);
  184. i2s_driver_uninstall(CONFIG_I2S_NUM);
  185. free(obuf);
  186. }
  187. /****************************************************************************************
  188. * Write frames to the output buffer
  189. */
  190. static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR,
  191. s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr) {
  192. #if BYTES_PER_FRAME == 8
  193. s32_t *optr;
  194. #endif
  195. if (!silence) {
  196. if (output.fade == FADE_ACTIVE && output.fade_dir == FADE_CROSS && *cross_ptr) {
  197. _apply_cross(outputbuf, out_frames, cross_gain_in, cross_gain_out, cross_ptr);
  198. }
  199. #if BYTES_PER_FRAME == 4
  200. if (gainL != FIXED_ONE || gainR!= FIXED_ONE) {
  201. _apply_gain(outputbuf, out_frames, gainL, gainR);
  202. }
  203. memcpy(obuf, outputbuf->readp, out_frames * bytes_per_frame);
  204. #else
  205. optr = (s32_t*) outputbuf->readp;
  206. #endif
  207. } else {
  208. #if BYTES_PER_FRAME == 4
  209. memcpy(obuf, silencebuf, out_frames * bytes_per_frame);
  210. #else
  211. optr = (s32_t*) silencebuf;
  212. #endif
  213. }
  214. #if BYTES_PER_FRAME == 8
  215. IF_DSD(
  216. if (output.outfmt == DOP) {
  217. update_dop((u32_t *) optr, out_frames, output.invert);
  218. } else if (output.outfmt != PCM && output.invert)
  219. dsd_invert((u32_t *) optr, out_frames);
  220. )
  221. _scale_and_pack_frames(obuf, optr, out_frames, gainL, gainR, output.format);
  222. #endif
  223. return out_frames;
  224. }
  225. /****************************************************************************************
  226. * Main output thread
  227. */
  228. static void *output_thread_i2s() {
  229. frames_t frames = 0;
  230. size_t bytes;
  231. uint32_t timer_start = 0;
  232. while (running) {
  233. TIME_MEASUREMENT_START(timer_start);
  234. LOCK;
  235. /*
  236. if (output.state == OUTPUT_OFF) {
  237. UNLOCK;
  238. LOG_INFO("Output state is off.");
  239. if (isI2SStarted) {
  240. isI2SStarted=false;
  241. i2s_stop(CONFIG_I2S_NUM);
  242. }
  243. usleep(200000);
  244. continue;
  245. }
  246. */
  247. //output.device_frames = DMA_BUF_COUNT * i2s_config.dma_buf_len;
  248. output.device_frames = 0;
  249. output.updated = gettime_ms();
  250. output.frames_played_dmp = output.frames_played;
  251. frames = _output_frames( FRAME_BLOCK );
  252. SET_MIN_MAX_SIZED(frames,rec,FRAME_BLOCK);
  253. SET_MIN_MAX_SIZED(_buf_used(outputbuf),o,outputbuf->size);
  254. SET_MIN_MAX_SIZED(_buf_used(streambuf),s,streambuf->size);
  255. SET_MIN_MAX( TIME_MEASUREMENT_GET(timer_start),buffering);
  256. UNLOCK;
  257. // must skip first frames as buffer filled with silence
  258. //if (output.state > OUTPUT_STOPPED && output.frames_played + frames < DMA_BUF_COUNT * i2s_config.dma_buf_len) continue;
  259. // now send all the data
  260. TIME_MEASUREMENT_START(timer_start);
  261. if (!isI2SStarted ) {
  262. isI2SStarted = true;
  263. LOG_INFO("Restarting I2S.");
  264. // start with a buffer full of silence
  265. i2s_zero_dma_buffer(CONFIG_I2S_NUM);
  266. i2s_start(CONFIG_I2S_NUM);
  267. }
  268. // TODO: this does not work well as set_sample_rates resets the fifos - it breaks synchronization
  269. if (i2s_config.sample_rate != output.current_sample_rate) {
  270. LOG_INFO("changing sampling rate %u to %u", i2s_config.sample_rate, output.current_sample_rate);
  271. i2s_config.sample_rate = output.current_sample_rate;
  272. i2s_set_sample_rates(CONFIG_I2S_NUM, i2s_config.sample_rate);
  273. }
  274. i2s_write(CONFIG_I2S_NUM, obuf, frames * bytes_per_frame, &bytes, portMAX_DELAY);
  275. if (bytes != frames * bytes_per_frame) {
  276. LOG_WARN("I2S DMA Overflow! available bytes: %d, I2S wrote %d bytes", frames * bytes_per_frame, bytes);
  277. }
  278. SET_MIN_MAX( TIME_MEASUREMENT_GET(timer_start),i2s_time);
  279. frames = 0;
  280. }
  281. return 0;
  282. }
  283. /****************************************************************************************
  284. * Stats output thread
  285. */
  286. static void *output_thread_i2s_stats() {
  287. while (running) {
  288. LOCK;
  289. output_state state = output.state;
  290. UNLOCK;
  291. if(state>OUTPUT_STOPPED){
  292. LOG_INFO( "Output State: %d, current sample rate: %d, bytes per frame: %d",state,output.current_sample_rate, bytes_per_frame);
  293. LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD1);
  294. LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD2);
  295. LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD3);
  296. LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD4);
  297. LOG_INFO(LINE_MIN_MAX_FORMAT_STREAM, LINE_MIN_MAX_STREAM("stream",s));
  298. LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("output",o));
  299. LOG_INFO(LINE_MIN_MAX_FORMAT_FOOTER);
  300. LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("received",rec));
  301. LOG_INFO(LINE_MIN_MAX_FORMAT_FOOTER);
  302. LOG_INFO("");
  303. LOG_INFO(" ----------+----------+-----------+-----------+ ");
  304. LOG_INFO(" max (us) | min (us) | avg(us) | count | ");
  305. LOG_INFO(" ----------+----------+-----------+-----------+ ");
  306. LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("Buffering(us)",buffering));
  307. LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("i2s tfr(us)",i2s_time));
  308. LOG_INFO(" ----------+----------+-----------+-----------+");
  309. RESET_ALL_MIN_MAX;
  310. }
  311. usleep(STATS_PERIOD_MS *1000);
  312. }
  313. return NULL;
  314. }