output_i2s.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  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. #include "squeezelite.h"
  22. #include "driver/i2s.h"
  23. #include "perf_trace.h"
  24. #include <signal.h>
  25. #include "time.h"
  26. #define DECLARE_ALL_MIN_MAX \
  27. DECLARE_MIN_MAX(o); \
  28. DECLARE_MIN_MAX(s); \
  29. DECLARE_MIN_MAX(req); \
  30. DECLARE_MIN_MAX(rec); \
  31. DECLARE_MIN_MAX(over); \
  32. DECLARE_MIN_MAX(i2s_time); \
  33. DECLARE_MIN_MAX(buffering);
  34. #define RESET_ALL_MIN_MAX \
  35. RESET_MIN_MAX(o); \
  36. RESET_MIN_MAX(s); \
  37. RESET_MIN_MAX(req); \
  38. RESET_MIN_MAX(rec); \
  39. RESET_MIN_MAX(over); \
  40. RESET_MIN_MAX(i2s_time); \
  41. RESET_MIN_MAX(buffering);
  42. #define STATS_PERIOD_MS 5000
  43. // Prevent compile errors if dac output is
  44. // included in the build and not actually activated in menuconfig
  45. #ifndef CONFIG_I2S_BCK_IO
  46. #define CONFIG_I2S_BCK_IO -1
  47. #endif
  48. #ifndef CONFIG_I2S_WS_IO
  49. #define CONFIG_I2S_WS_IO -1
  50. #endif
  51. #ifndef CONFIG_I2S_DO_IO
  52. #define CONFIG_I2S_DO_IO -1
  53. #endif
  54. #ifndef CONFIG_I2S_NUM
  55. #define CONFIG_I2S_NUM -1
  56. #endif
  57. #define LOCK mutex_lock(outputbuf->mutex)
  58. #define UNLOCK mutex_unlock(outputbuf->mutex)
  59. #define FRAME_BLOCK MAX_SILENCE_FRAMES
  60. extern struct outputstate output;
  61. extern struct buffer *streambuf;
  62. extern struct buffer *outputbuf;
  63. extern u8_t *silencebuf;
  64. static log_level loglevel;
  65. static bool running, isI2SStarted;
  66. static i2s_config_t i2s_config;
  67. static int bytes_per_frame;
  68. static thread_type thread, stats_thread;
  69. static u8_t *obuf;
  70. DECLARE_ALL_MIN_MAX;
  71. static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR,
  72. s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr);
  73. static void *output_thread_i2s();
  74. static void *output_thread_i2s_stats();
  75. /****************************************************************************************
  76. * Initialize the DAC output
  77. */
  78. void output_init_i2s(log_level level, char *device, unsigned output_buf_size, char *params, unsigned rates[], unsigned rate_delay, unsigned idle) {
  79. loglevel = level;
  80. #ifdef CONFIG_I2S_BITS_PER_CHANNEL
  81. switch (CONFIG_I2S_BITS_PER_CHANNEL) {
  82. case 24:
  83. output.format = S24_BE;
  84. bytes_per_frame = 2*3;
  85. break;
  86. case 16:
  87. output.format = S16_BE;
  88. bytes_per_frame = 2*2;
  89. break;
  90. case 8:
  91. output.format = S8_BE;
  92. bytes_per_frame = 2*4;
  93. break;
  94. default:
  95. LOG_ERROR("Unsupported bit depth %d",CONFIG_I2S_BITS_PER_CHANNEL);
  96. break;
  97. }
  98. #else
  99. output.format = S16_LE;
  100. bytes_per_frame = 2*2;
  101. #endif
  102. output.write_cb = &_i2s_write_frames;
  103. obuf = malloc(FRAME_BLOCK * bytes_per_frame);
  104. if (!obuf) {
  105. LOG_ERROR("Cannot allocate i2s buffer");
  106. return;
  107. }
  108. running=true;
  109. // todo: move this to a hardware abstraction layer
  110. //hal_dac_init(device);
  111. i2s_config.mode = I2S_MODE_MASTER | I2S_MODE_TX; // Only TX
  112. i2s_config.sample_rate = output.current_sample_rate;
  113. i2s_config.bits_per_sample = bytes_per_frame * 8 / 2;
  114. i2s_config.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT; //2-channels
  115. i2s_config.communication_format = I2S_COMM_FORMAT_I2S| I2S_COMM_FORMAT_I2S_MSB;
  116. // todo: tune this parameter. Expressed in number of samples. Byte size depends on bit depth.
  117. i2s_config.dma_buf_count = 10;
  118. // From the I2S driver source, the DMA buffer size is 4092 bytes.
  119. // so buf_len * 2 channels * 2 bytes/sample should be < 4092 or else it will be resized.
  120. i2s_config.dma_buf_len = FRAME_BLOCK/2;
  121. i2s_config.use_apll = false;
  122. i2s_config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1; //Interrupt level 1
  123. i2s_pin_config_t pin_config = { .bck_io_num = CONFIG_I2S_BCK_IO, .ws_io_num =
  124. CONFIG_I2S_WS_IO, .data_out_num = CONFIG_I2S_DO_IO, .data_in_num = -1 //Not used
  125. };
  126. LOG_INFO("Initializing I2S with rate: %d, bits per sample: %d, buffer len: %d, number of buffers: %d ",
  127. i2s_config.sample_rate, i2s_config.bits_per_sample, i2s_config.dma_buf_len, i2s_config.dma_buf_count);
  128. i2s_driver_install(CONFIG_I2S_NUM, &i2s_config, 0, NULL);
  129. i2s_set_pin(CONFIG_I2S_NUM, &pin_config);
  130. i2s_set_clk(CONFIG_I2S_NUM, output.current_sample_rate, i2s_config.bits_per_sample, 2);
  131. isI2SStarted=false;
  132. i2s_stop(CONFIG_I2S_NUM);
  133. pthread_attr_t attr;
  134. pthread_attr_init(&attr);
  135. pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN + OUTPUT_THREAD_STACK_SIZE);
  136. pthread_create(&thread, &attr, output_thread_i2s, NULL);
  137. pthread_attr_destroy(&attr);
  138. #if HAS_PTHREAD_SETNAME_NP
  139. pthread_setname_np(thread, "output_i2s");
  140. #endif
  141. // leave stack size to default
  142. pthread_create(&stats_thread, NULL, output_thread_i2s_stats, NULL);
  143. #if HAS_PTHREAD_SETNAME_NP
  144. pthread_setname_np(stats_thread, "output_i2s_sts");
  145. #endif
  146. }
  147. /****************************************************************************************
  148. * Terminate DAC output
  149. */
  150. void output_close_i2s(void) {
  151. i2s_driver_uninstall(CONFIG_I2S_NUM);
  152. free(obuf);
  153. }
  154. /****************************************************************************************
  155. * Write frames to the output buffer
  156. */
  157. static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR,
  158. s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr) {
  159. #if BYTES_PER_FRAME == 8
  160. s32_t *optr;
  161. #endif
  162. if (!silence) {
  163. if (output.fade == FADE_ACTIVE && output.fade_dir == FADE_CROSS && *cross_ptr) {
  164. _apply_cross(outputbuf, out_frames, cross_gain_in, cross_gain_out, cross_ptr);
  165. }
  166. #if BYTES_PER_FRAME == 4
  167. if (gainL != FIXED_ONE || gainR!= FIXED_ONE) {
  168. _apply_gain(outputbuf, out_frames, gainL, gainR);
  169. }
  170. memcpy(obuf, outputbuf->readp, out_frames * bytes_per_frame);
  171. #else
  172. optr = (s32_t*) outputbuf->readp;
  173. #endif
  174. } else {
  175. #if BYTES_PER_FRAME == 4
  176. memcpy(obuf, silencebuf, out_frames * bytes_per_frame);
  177. #else
  178. optr = (s32_t*) silencebuf;
  179. #endif
  180. }
  181. #if BYTES_PER_FRAME == 8
  182. IF_DSD(
  183. if (output.outfmt == DOP) {
  184. update_dop((u32_t *) optr, out_frames, output.invert);
  185. } else if (output.outfmt != PCM && output.invert)
  186. dsd_invert((u32_t *) optr, out_frames);
  187. )
  188. _scale_and_pack_frames(obuf, optr, out_frames, gainL, gainR, output.format);
  189. #endif
  190. return out_frames;
  191. }
  192. /****************************************************************************************
  193. * Main output thread
  194. */
  195. static void *output_thread_i2s() {
  196. frames_t frames = 0;
  197. size_t bytes;
  198. uint32_t timer_start = 0;
  199. while (running) {
  200. TIME_MEASUREMENT_START(timer_start);
  201. LOCK;
  202. if (output.state == OUTPUT_OFF) {
  203. UNLOCK;
  204. LOG_INFO("Output state is off.");
  205. if(isI2SStarted) {
  206. isI2SStarted=false;
  207. i2s_stop(CONFIG_I2S_NUM);
  208. }
  209. usleep(200000);
  210. continue;
  211. }
  212. output.device_frames =0;
  213. output.updated = gettime_ms();
  214. output.frames_played_dmp = output.frames_played;
  215. frames = _output_frames( FRAME_BLOCK );
  216. SET_MIN_MAX(frames,rec);
  217. SET_MIN_MAX_SIZED(_buf_used(outputbuf),o,outputbuf->size);
  218. SET_MIN_MAX_SIZED(_buf_used(streambuf),s,streambuf->size);
  219. SET_MIN_MAX( TIME_MEASUREMENT_GET(timer_start),buffering);
  220. UNLOCK;
  221. if (frames) {
  222. // now send all the data
  223. TIME_MEASUREMENT_START(timer_start);
  224. if(!isI2SStarted)
  225. {
  226. isI2SStarted=true;
  227. LOG_INFO("Restarting I2S.");
  228. i2s_start(CONFIG_I2S_NUM);
  229. }
  230. if (i2s_config.sample_rate != output.current_sample_rate) {
  231. LOG_INFO("changing sampling rate %u to %u", i2s_config.sample_rate, output.current_sample_rate);
  232. i2s_config.sample_rate = output.current_sample_rate;
  233. i2s_set_sample_rates(CONFIG_I2S_NUM, i2s_config.sample_rate);
  234. }
  235. i2s_write(CONFIG_I2S_NUM, obuf, frames * bytes_per_frame, &bytes, portMAX_DELAY);
  236. if (bytes != frames * bytes_per_frame)
  237. {
  238. LOG_WARN("I2S DMA Overflow! available bytes: %d, I2S wrote %d bytes", frames * bytes_per_frame, bytes);
  239. }
  240. SET_MIN_MAX( TIME_MEASUREMENT_GET(timer_start),i2s_time);
  241. frames = 0;
  242. }
  243. }
  244. return 0;
  245. }
  246. /****************************************************************************************
  247. * Stats output thread
  248. */
  249. static void *output_thread_i2s_stats() {
  250. while (running) {
  251. LOCK;
  252. output_state state = output.state;
  253. UNLOCK;
  254. if(state>OUTPUT_STOPPED){
  255. LOG_INFO( "Output State: %d, current sample rate: %d, bytes per frame: %d",state,output.current_sample_rate, bytes_per_frame);
  256. LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD1);
  257. LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD2);
  258. LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD3);
  259. LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD4);
  260. LOG_INFO(LINE_MIN_MAX_FORMAT_STREAM, LINE_MIN_MAX_STREAM("stream",s));
  261. LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("output",o));
  262. LOG_INFO(LINE_MIN_MAX_FORMAT_FOOTER);
  263. LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("requested",req));
  264. LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("received",rec));
  265. LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("overflow",over));
  266. LOG_INFO(LINE_MIN_MAX_FORMAT_FOOTER);
  267. LOG_INFO("");
  268. LOG_INFO(" ----------+----------+-----------+-----------+ ");
  269. LOG_INFO(" max (us) | min (us) | avg(us) | count | ");
  270. LOG_INFO(" ----------+----------+-----------+-----------+ ");
  271. LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("Buffering(us)",buffering));
  272. LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("i2s tfr(us)",i2s_time));
  273. LOG_INFO(" ----------+----------+-----------+-----------+");
  274. RESET_ALL_MIN_MAX;
  275. }
  276. usleep(STATS_PERIOD_MS *1000);
  277. }
  278. return NULL;
  279. }