output_i2s.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  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 a bit of a hack with i2s. The esp32 driver is always
  23. full when it starts, so there is a delay of the total length of buffers.
  24. In other words, i2s_write blocks at first call, until at least one buffer
  25. has been written (it uses a queue with produce / consume).
  26. The first hack is to consume that length at the beginning of tracks when
  27. synchronization is active. It's about ~180ms @ 44.1kHz
  28. The second hack is that we never know exactly the number of frames in the
  29. DMA buffers when we update the output.frames_played_dmp. We assume that
  30. after i2s_write, these buffers are always full so by measuring the gap
  31. between time after i2s_write and update of frames_played_dmp, we have a
  32. good idea of the error.
  33. The third hack is when sample rate changes, buffers are reset and we also
  34. do the change too early, but can't do that exaclty at the right time. So
  35. there might be a pop and a de-sync when sampling rate change happens. Not
  36. sure that using rate_delay would fix that
  37. */
  38. #include "squeezelite.h"
  39. #include "esp_pthread.h"
  40. #include "driver/i2s.h"
  41. #include "driver/i2c.h"
  42. #include "driver/gpio.h"
  43. #include "perf_trace.h"
  44. #include <signal.h>
  45. #include "adac.h"
  46. #include "time.h"
  47. #include "led.h"
  48. #include "monitor.h"
  49. #include "platform_config.h"
  50. #include "accessors.h"
  51. #include "globdefs.h"
  52. #define LOCK mutex_lock(outputbuf->mutex)
  53. #define UNLOCK mutex_unlock(outputbuf->mutex)
  54. #define FRAME_BLOCK MAX_SILENCE_FRAMES
  55. // must have an integer ratio with FRAME_BLOCK (see spdif comment)
  56. #define DMA_BUF_LEN 512
  57. #define DMA_BUF_COUNT 12
  58. #define DECLARE_ALL_MIN_MAX \
  59. DECLARE_MIN_MAX(o); \
  60. DECLARE_MIN_MAX(s); \
  61. DECLARE_MIN_MAX(rec); \
  62. DECLARE_MIN_MAX(i2s_time); \
  63. DECLARE_MIN_MAX(buffering);
  64. #define RESET_ALL_MIN_MAX \
  65. RESET_MIN_MAX(o); \
  66. RESET_MIN_MAX(s); \
  67. RESET_MIN_MAX(rec); \
  68. RESET_MIN_MAX(i2s_time); \
  69. RESET_MIN_MAX(buffering);
  70. #define STATS_PERIOD_MS 5000
  71. #define STAT_STACK_SIZE (3*1024)
  72. extern struct outputstate output;
  73. extern struct buffer *streambuf;
  74. extern struct buffer *outputbuf;
  75. extern u8_t *silencebuf;
  76. // by default no DAC selected
  77. struct adac_s *adac = &dac_external;
  78. static log_level loglevel;
  79. static bool jack_mutes_amp;
  80. static bool running, isI2SStarted;
  81. static i2s_config_t i2s_config;
  82. static int bytes_per_frame;
  83. static u8_t *obuf;
  84. static frames_t oframes;
  85. static bool spdif;
  86. static size_t dma_buf_frames;
  87. static pthread_t thread;
  88. static TaskHandle_t stats_task;
  89. static bool stats;
  90. static int amp_gpio = -1;
  91. DECLARE_ALL_MIN_MAX;
  92. static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR,
  93. s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr);
  94. static void *output_thread_i2s(void *arg);
  95. static void *output_thread_i2s_stats(void *arg);
  96. static void spdif_convert(ISAMPLE_T *src, size_t frames, u32_t *dst, size_t *count);
  97. static void (*jack_handler_chain)(bool inserted);
  98. #define I2C_PORT 0
  99. /****************************************************************************************
  100. * jack insertion handler
  101. */
  102. static void jack_handler(bool inserted) {
  103. // jack detection bounces a bit but that seems fine
  104. if (jack_mutes_amp) {
  105. LOG_INFO("switching amplifier %s", inserted ? "OFF" : "ON");
  106. if (inserted) adac->speaker(false);
  107. else adac->speaker(true);
  108. }
  109. // activate headset
  110. if (inserted) adac->headset(true);
  111. else adac->headset(false);
  112. // and chain if any
  113. if (jack_handler_chain) (jack_handler_chain)(inserted);
  114. }
  115. /****************************************************************************************
  116. * amp GPIO
  117. */
  118. void set_amp_gpio(int gpio, char *value) {
  119. if (!strcasecmp(value, "amp")) {
  120. amp_gpio = gpio;
  121. gpio_pad_select_gpio(amp_gpio);
  122. gpio_set_direction(amp_gpio, GPIO_MODE_OUTPUT);
  123. gpio_set_level(amp_gpio, 0);
  124. LOG_INFO("setting amplifier GPIO %d", amp_gpio);
  125. }
  126. }
  127. /****************************************************************************************
  128. * Initialize the DAC output
  129. */
  130. void output_init_i2s(log_level level, char *device, unsigned output_buf_size, char *params, unsigned rates[], unsigned rate_delay, unsigned idle) {
  131. loglevel = level;
  132. char *p;
  133. p = config_alloc_get_default(NVS_TYPE_STR, "jack_mutes_amp", "n", 0);
  134. jack_mutes_amp = (strcmp(p,"1") == 0 ||strcasecmp(p,"y") == 0);
  135. free(p);
  136. #ifdef CONFIG_I2S_BITS_PER_CHANNEL
  137. switch (CONFIG_I2S_BITS_PER_CHANNEL) {
  138. case 24:
  139. output.format = S24_BE;
  140. bytes_per_frame = 2*3;
  141. break;
  142. case 16:
  143. output.format = S16_BE;
  144. bytes_per_frame = 2*2;
  145. break;
  146. case 8:
  147. output.format = S8_BE;
  148. bytes_per_frame = 2*4;
  149. break;
  150. default:
  151. LOG_ERROR("Unsupported bit depth %d",CONFIG_I2S_BITS_PER_CHANNEL);
  152. break;
  153. }
  154. #else
  155. output.format = S16_LE;
  156. bytes_per_frame = 2*2;
  157. #endif
  158. output.write_cb = &_i2s_write_frames;
  159. obuf = malloc(FRAME_BLOCK * bytes_per_frame);
  160. if (!obuf) {
  161. LOG_ERROR("Cannot allocate i2s buffer");
  162. return;
  163. }
  164. running = true;
  165. // common I2S initialization
  166. i2s_config.mode = I2S_MODE_MASTER | I2S_MODE_TX;
  167. i2s_config.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT;
  168. i2s_config.communication_format = I2S_COMM_FORMAT_I2S| I2S_COMM_FORMAT_I2S_MSB;
  169. // in case of overflow, do not replay old buffer
  170. i2s_config.tx_desc_auto_clear = true;
  171. i2s_config.use_apll = true;
  172. i2s_config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1; //Interrupt level 1
  173. if (strcasestr(device, "spdif")) {
  174. spdif = true;
  175. i2s_pin_config_t i2s_pin_config = (i2s_pin_config_t) { .bck_io_num = CONFIG_SPDIF_BCK_IO, .ws_io_num = CONFIG_SPDIF_WS_IO,
  176. .data_out_num = CONFIG_SPDIF_DO_IO, .data_in_num = -1 };
  177. #ifndef CONFIG_SPDIF_LOCKED
  178. char *nvs_item = config_alloc_get(NVS_TYPE_STR, "spdif_config");
  179. if (nvs_item) {
  180. if ((p = strcasestr(nvs_item, "bck")) != NULL) i2s_pin_config.bck_io_num = atoi(strchr(p, '=') + 1);
  181. if ((p = strcasestr(nvs_item, "ws")) != NULL) i2s_pin_config.ws_io_num = atoi(strchr(p, '=') + 1);
  182. if ((p = strcasestr(nvs_item, "do")) != NULL) i2s_pin_config.data_out_num = atoi(strchr(p, '=') + 1);
  183. free(nvs_item);
  184. }
  185. #endif
  186. if (i2s_pin_config.bck_io_num == -1 || i2s_pin_config.ws_io_num == -1 || i2s_pin_config.data_out_num == -1) {
  187. LOG_WARN("Cannot initialize I2S for SPDIF bck:%d ws:%d do:%d", i2s_pin_config.bck_io_num,
  188. i2s_pin_config.ws_io_num,
  189. i2s_pin_config.data_out_num);
  190. }
  191. i2s_config.sample_rate = output.current_sample_rate * 2;
  192. i2s_config.bits_per_sample = 32;
  193. // Normally counted in frames, but 16 sample are transformed into 32 bits in spdif
  194. i2s_config.dma_buf_len = DMA_BUF_LEN / 2;
  195. i2s_config.dma_buf_count = DMA_BUF_COUNT * 2;
  196. /*
  197. In DMA, we have room for (LEN * COUNT) frames of 32 bits samples that
  198. we push at sample_rate * 2. Each of these peuso-frames is a single true
  199. audio frame. So the real depth is true frames is (LEN * COUNT / 2)
  200. */
  201. dma_buf_frames = DMA_BUF_COUNT * DMA_BUF_LEN / 2;
  202. i2s_driver_install(CONFIG_I2S_NUM, &i2s_config, 0, NULL);
  203. i2s_set_pin(CONFIG_I2S_NUM, &i2s_pin_config);
  204. LOG_INFO("SPDIF using I2S bck:%u, ws:%u, do:%u", i2s_pin_config.bck_io_num, i2s_pin_config.ws_io_num, i2s_pin_config.data_out_num);
  205. } else {
  206. #if CONFIG_SPDIF_DO_IO != -1
  207. gpio_pad_select_gpio(CONFIG_SPDIF_DO_IO);
  208. gpio_set_direction(CONFIG_SPDIF_DO_IO, GPIO_MODE_OUTPUT);
  209. gpio_set_level(CONFIG_SPDIF_DO_IO, 0);
  210. #endif
  211. i2s_config.sample_rate = output.current_sample_rate;
  212. i2s_config.bits_per_sample = bytes_per_frame * 8 / 2;
  213. // Counted in frames (but i2s allocates a buffer <= 4092 bytes)
  214. i2s_config.dma_buf_len = DMA_BUF_LEN;
  215. i2s_config.dma_buf_count = DMA_BUF_COUNT;
  216. dma_buf_frames = DMA_BUF_COUNT * DMA_BUF_LEN;
  217. // finally let DAC driver initialize I2C and I2S
  218. if (dac_tas57xx.init(I2C_PORT, CONFIG_I2S_NUM, &i2s_config)) adac = &dac_tas57xx;
  219. else if (dac_a1s.init(I2C_PORT, CONFIG_I2S_NUM, &i2s_config)) adac = &dac_a1s;
  220. else if (!dac_external.init(I2C_PORT, CONFIG_I2S_NUM, &i2s_config)) {
  221. LOG_WARN("DAC not configured and SPDIF not enabled, I2S will not continue");
  222. return;
  223. }
  224. }
  225. LOG_INFO("Initializing I2S mode %s with rate: %d, bits per sample: %d, buffer frames: %d, number of buffers: %d ",
  226. spdif ? "S/PDIF" : "normal",
  227. i2s_config.sample_rate, i2s_config.bits_per_sample, i2s_config.dma_buf_len, i2s_config.dma_buf_count);
  228. i2s_stop(CONFIG_I2S_NUM);
  229. i2s_zero_dma_buffer(CONFIG_I2S_NUM);
  230. isI2SStarted=false;
  231. adac->power(ADAC_STANDBY);
  232. jack_handler_chain = jack_handler_svc;
  233. jack_handler_svc = jack_handler;
  234. if (jack_mutes_amp && jack_inserted_svc()) adac->speaker(false);
  235. else adac->speaker(true);
  236. adac->headset(jack_inserted_svc());
  237. parse_set_GPIO(set_amp_gpio);
  238. esp_pthread_cfg_t cfg = esp_pthread_get_default_config();
  239. cfg.thread_name= "output_i2s";
  240. cfg.inherit_cfg = false;
  241. cfg.prio = CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT + 1;
  242. cfg.stack_size = PTHREAD_STACK_MIN + OUTPUT_THREAD_STACK_SIZE;
  243. esp_pthread_set_cfg(&cfg);
  244. pthread_create(&thread, NULL, output_thread_i2s, NULL);
  245. // do we want stats
  246. p = config_alloc_get_default(NVS_TYPE_STR, "stats", "n", 0);
  247. stats = p && (*p == '1' || *p == 'Y' || *p == 'y');
  248. free(p);
  249. // memory still used but at least task is not created
  250. if (stats) {
  251. static DRAM_ATTR StaticTask_t xTaskBuffer __attribute__ ((aligned (4)));
  252. static EXT_RAM_ATTR StackType_t xStack[STAT_STACK_SIZE] __attribute__ ((aligned (4)));
  253. stats_task = xTaskCreateStatic( (TaskFunction_t) output_thread_i2s_stats, "output_i2s_sts", STAT_STACK_SIZE, NULL, ESP_TASK_PRIO_MIN + 1, xStack, &xTaskBuffer);
  254. }
  255. }
  256. /****************************************************************************************
  257. * Terminate DAC output
  258. */
  259. void output_close_i2s(void) {
  260. LOCK;
  261. running = false;
  262. UNLOCK;
  263. pthread_join(thread, NULL);
  264. if (stats) vTaskDelete(stats_task);
  265. i2s_driver_uninstall(CONFIG_I2S_NUM);
  266. free(obuf);
  267. adac->deinit();
  268. }
  269. /****************************************************************************************
  270. * change volume
  271. */
  272. bool output_volume_i2s(unsigned left, unsigned right) {
  273. adac->volume(left, right);
  274. return false;
  275. }
  276. /****************************************************************************************
  277. * Write frames to the output buffer
  278. */
  279. static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR,
  280. s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr) {
  281. #if BYTES_PER_FRAME == 8
  282. s32_t *optr;
  283. #endif
  284. if (!silence) {
  285. if (output.fade == FADE_ACTIVE && output.fade_dir == FADE_CROSS && *cross_ptr) {
  286. _apply_cross(outputbuf, out_frames, cross_gain_in, cross_gain_out, cross_ptr);
  287. }
  288. #if BYTES_PER_FRAME == 4
  289. if (gainL != FIXED_ONE || gainR!= FIXED_ONE) {
  290. _apply_gain(outputbuf, out_frames, gainL, gainR);
  291. }
  292. memcpy(obuf + oframes * bytes_per_frame, outputbuf->readp, out_frames * bytes_per_frame);
  293. #else
  294. optr = (s32_t*) outputbuf->readp;
  295. #endif
  296. } else {
  297. #if BYTES_PER_FRAME == 4
  298. memcpy(obuf + oframes * bytes_per_frame, silencebuf, out_frames * bytes_per_frame);
  299. #else
  300. optr = (s32_t*) silencebuf;
  301. #endif
  302. }
  303. #if BYTES_PER_FRAME == 8
  304. IF_DSD(
  305. if (output.outfmt == DOP) {
  306. update_dop((u32_t *) optr, out_frames, output.invert);
  307. } else if (output.outfmt != PCM && output.invert)
  308. dsd_invert((u32_t *) optr, out_frames);
  309. )
  310. _scale_and_pack_frames(obuf + oframes * bytes_per_frame, optr, out_frames, gainL, gainR, output.format);
  311. #endif
  312. output_visu_export((s16_t*) (obuf + oframes * bytes_per_frame), out_frames, output.current_sample_rate, silence);
  313. oframes += out_frames;
  314. return out_frames;
  315. }
  316. /****************************************************************************************
  317. * Main output thread
  318. */
  319. static void *output_thread_i2s(void *arg) {
  320. size_t count = 0, bytes;
  321. frames_t iframes = FRAME_BLOCK;
  322. uint32_t timer_start = 0;
  323. int discard = 0;
  324. uint32_t fullness = gettime_ms();
  325. bool synced;
  326. output_state state = OUTPUT_OFF - 1;
  327. char *sbuf = NULL;
  328. // spdif needs 16 bytes per frame : 32 bits/sample, 2 channels, BMC encoded
  329. if (spdif && (sbuf = malloc(FRAME_BLOCK * 16)) == NULL) {
  330. LOG_ERROR("Cannot allocate SPDIF buffer");
  331. }
  332. while (running) {
  333. TIME_MEASUREMENT_START(timer_start);
  334. LOCK;
  335. // manage led display & analogue
  336. if (state != output.state) {
  337. LOG_INFO("Output state is %d", output.state);
  338. if (output.state == OUTPUT_OFF) {
  339. led_blink(LED_GREEN, 100, 2500);
  340. if (amp_gpio != -1) gpio_set_level(amp_gpio, 0);
  341. LOG_INFO("switching off amp GPIO %d", amp_gpio);
  342. } else if (output.state == OUTPUT_STOPPED) {
  343. adac->speaker(false);
  344. led_blink(LED_GREEN, 200, 1000);
  345. } else if (output.state == OUTPUT_RUNNING) {
  346. if (!jack_mutes_amp || !jack_inserted_svc()) adac->speaker(true);
  347. led_on(LED_GREEN);
  348. }
  349. }
  350. state = output.state;
  351. if (output.state == OUTPUT_OFF) {
  352. UNLOCK;
  353. if (isI2SStarted) {
  354. isI2SStarted = false;
  355. i2s_stop(CONFIG_I2S_NUM);
  356. adac->power(ADAC_STANDBY);
  357. count = 0;
  358. }
  359. usleep(100000);
  360. continue;
  361. } else if (output.state == OUTPUT_STOPPED) {
  362. synced = false;
  363. }
  364. oframes = 0;
  365. output.updated = gettime_ms();
  366. output.frames_played_dmp = output.frames_played;
  367. // try to estimate how much we have consumed from the DMA buffer (calculation is incorrect at the very beginning ...)
  368. output.device_frames = dma_buf_frames - ((output.updated - fullness) * output.current_sample_rate) / 1000;
  369. _output_frames( iframes );
  370. // oframes must be a global updated by the write callback
  371. output.frames_in_process = oframes;
  372. SET_MIN_MAX_SIZED(oframes,rec,iframes);
  373. SET_MIN_MAX_SIZED(_buf_used(outputbuf),o,outputbuf->size);
  374. SET_MIN_MAX_SIZED(_buf_used(streambuf),s,streambuf->size);
  375. SET_MIN_MAX( TIME_MEASUREMENT_GET(timer_start),buffering);
  376. /* must skip first whatever is in the pipe (but not when resuming).
  377. This test is incorrect when we pause a track that has just started,
  378. but this is higly unlikely and I don't have a better one for now */
  379. if (output.state == OUTPUT_START_AT) {
  380. discard = output.frames_played_dmp ? 0 : output.device_frames;
  381. synced = true;
  382. } else if (discard) {
  383. discard -= oframes;
  384. iframes = discard ? min(FRAME_BLOCK, discard) : FRAME_BLOCK;
  385. UNLOCK;
  386. continue;
  387. }
  388. UNLOCK;
  389. // now send all the data
  390. TIME_MEASUREMENT_START(timer_start);
  391. if (!isI2SStarted ) {
  392. isI2SStarted = true;
  393. LOG_INFO("Restarting I2S.");
  394. i2s_zero_dma_buffer(CONFIG_I2S_NUM);
  395. i2s_start(CONFIG_I2S_NUM);
  396. adac->power(ADAC_ON);
  397. if (amp_gpio != -1) gpio_set_level(amp_gpio, 1);
  398. }
  399. // this does not work well as set_sample_rates resets the fifos (and it's too early)
  400. if (i2s_config.sample_rate != output.current_sample_rate) {
  401. LOG_INFO("changing sampling rate %u to %u", i2s_config.sample_rate, output.current_sample_rate);
  402. /*
  403. if (synced)
  404. // can sleep for a buffer_queue - 1 and then eat a buffer (discard) if we are synced
  405. usleep(((DMA_BUF_COUNT - 1) * DMA_BUF_LEN * bytes_per_frame * 1000) / 44100 * 1000);
  406. discard = DMA_BUF_COUNT * DMA_BUF_LEN * bytes_per_frame;
  407. }
  408. */
  409. i2s_config.sample_rate = output.current_sample_rate;
  410. i2s_set_sample_rates(CONFIG_I2S_NUM, spdif ? i2s_config.sample_rate * 2 : i2s_config.sample_rate);
  411. i2s_zero_dma_buffer(CONFIG_I2S_NUM);
  412. //return;
  413. }
  414. // we assume that here we have been able to entirely fill the DMA buffers
  415. if (spdif) {
  416. spdif_convert((ISAMPLE_T*) obuf, oframes, (u32_t*) sbuf, &count);
  417. i2s_write(CONFIG_I2S_NUM, sbuf, oframes * 16, &bytes, portMAX_DELAY);
  418. bytes /= 4;
  419. } else {
  420. i2s_write(CONFIG_I2S_NUM, obuf, oframes * bytes_per_frame, &bytes, portMAX_DELAY);
  421. }
  422. fullness = gettime_ms();
  423. if (bytes != oframes * bytes_per_frame) {
  424. LOG_WARN("I2S DMA Overflow! available bytes: %d, I2S wrote %d bytes", oframes * bytes_per_frame, bytes);
  425. }
  426. SET_MIN_MAX( TIME_MEASUREMENT_GET(timer_start),i2s_time);
  427. }
  428. if (spdif) free(sbuf);
  429. return 0;
  430. }
  431. /****************************************************************************************
  432. * Stats output thread
  433. */
  434. static void *output_thread_i2s_stats(void *arg) {
  435. while (1) {
  436. // no need to lock
  437. output_state state = output.state;
  438. if(stats && state>OUTPUT_STOPPED){
  439. LOG_INFO( "Output State: %d, current sample rate: %d, bytes per frame: %d",state,output.current_sample_rate, bytes_per_frame);
  440. LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD1);
  441. LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD2);
  442. LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD3);
  443. LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD4);
  444. LOG_INFO(LINE_MIN_MAX_FORMAT_STREAM, LINE_MIN_MAX_STREAM("stream",s));
  445. LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("output",o));
  446. LOG_INFO(LINE_MIN_MAX_FORMAT_FOOTER);
  447. LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("received",rec));
  448. LOG_INFO(LINE_MIN_MAX_FORMAT_FOOTER);
  449. LOG_INFO("");
  450. LOG_INFO(" ----------+----------+-----------+-----------+ ");
  451. LOG_INFO(" max (us) | min (us) | avg(us) | count | ");
  452. LOG_INFO(" ----------+----------+-----------+-----------+ ");
  453. LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("Buffering(us)",buffering));
  454. LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("i2s tfr(us)",i2s_time));
  455. LOG_INFO(" ----------+----------+-----------+-----------+");
  456. RESET_ALL_MIN_MAX;
  457. }
  458. vTaskDelay( pdMS_TO_TICKS( STATS_PERIOD_MS ) );
  459. }
  460. return NULL;
  461. }
  462. /****************************************************************************************
  463. * SPDIF support
  464. */
  465. #define PREAMBLE_B (0xE8) //11101000
  466. #define PREAMBLE_M (0xE2) //11100010
  467. #define PREAMBLE_W (0xE4) //11100100
  468. #define VUCP ((0xCC) << 24)
  469. #define VUCP_MUTE ((0xD4) << 24) // To mute PCM, set VUCP = invalid.
  470. extern const u16_t spdif_bmclookup[256];
  471. /*
  472. SPDIF is supposed to be (before BMC encoding, from LSB to MSB)
  473. PPPP AAAA SSSS SSSS SSSS SSSS SSSS VUCP
  474. after BMC encoding, each bits becomes 2 hence this becomes a 64 bits word. The
  475. the trick is to start not with a PPPP sequence but with an VUCP sequence to that
  476. the 16 bits samples are aligned with a BMC word boundary. Note that the LSB of the
  477. audio is transmitted first (not the MSB) and that ESP32 libray sends R then L,
  478. contrary to what seems to be usually done, so (dst) order had to be changed
  479. */
  480. void spdif_convert(ISAMPLE_T *src, size_t frames, u32_t *dst, size_t *count) {
  481. u16_t hi, lo, aux;
  482. // frames are 2 channels of 16 bits
  483. frames *= 2;
  484. while (frames--) {
  485. #if BYTES_PER_FRAME == 4
  486. hi = spdif_bmclookup[(u8_t)(*src >> 8)];
  487. lo = spdif_bmclookup[(u8_t) *src];
  488. #else
  489. hi = spdif_bmclookup[(u8_t)(*src >> 24)];
  490. lo = spdif_bmclookup[(u8_t) *src >> 16];
  491. #endif
  492. lo ^= ~((s16_t)hi) >> 16;
  493. // 16 bits sample:
  494. *(dst+0) = ((u32_t)lo << 16) | hi;
  495. // 4 bits auxillary-audio-databits, the first used as parity
  496. aux = 0xb333 ^ (((u32_t)((s16_t)lo)) >> 17);
  497. // VUCP-Bits: Valid, Subcode, Channelstatus, Parity = 0
  498. // As parity is always 0, we can use fixed preambles
  499. if (++(*count) > 383) {
  500. *(dst+1) = VUCP | (PREAMBLE_B << 16 ) | aux; //special preamble for one of 192 frames
  501. *count = 0;
  502. } else {
  503. *(dst+1) = VUCP | ((((*count) & 0x01) ? PREAMBLE_W : PREAMBLE_M) << 16) | aux;
  504. }
  505. src++;
  506. dst += 2;
  507. }
  508. }
  509. const u16_t spdif_bmclookup[256] = { //biphase mark encoded values (least significant bit first)
  510. 0xcccc, 0x4ccc, 0x2ccc, 0xaccc, 0x34cc, 0xb4cc, 0xd4cc, 0x54cc,
  511. 0x32cc, 0xb2cc, 0xd2cc, 0x52cc, 0xcacc, 0x4acc, 0x2acc, 0xaacc,
  512. 0x334c, 0xb34c, 0xd34c, 0x534c, 0xcb4c, 0x4b4c, 0x2b4c, 0xab4c,
  513. 0xcd4c, 0x4d4c, 0x2d4c, 0xad4c, 0x354c, 0xb54c, 0xd54c, 0x554c,
  514. 0x332c, 0xb32c, 0xd32c, 0x532c, 0xcb2c, 0x4b2c, 0x2b2c, 0xab2c,
  515. 0xcd2c, 0x4d2c, 0x2d2c, 0xad2c, 0x352c, 0xb52c, 0xd52c, 0x552c,
  516. 0xccac, 0x4cac, 0x2cac, 0xacac, 0x34ac, 0xb4ac, 0xd4ac, 0x54ac,
  517. 0x32ac, 0xb2ac, 0xd2ac, 0x52ac, 0xcaac, 0x4aac, 0x2aac, 0xaaac,
  518. 0x3334, 0xb334, 0xd334, 0x5334, 0xcb34, 0x4b34, 0x2b34, 0xab34,
  519. 0xcd34, 0x4d34, 0x2d34, 0xad34, 0x3534, 0xb534, 0xd534, 0x5534,
  520. 0xccb4, 0x4cb4, 0x2cb4, 0xacb4, 0x34b4, 0xb4b4, 0xd4b4, 0x54b4,
  521. 0x32b4, 0xb2b4, 0xd2b4, 0x52b4, 0xcab4, 0x4ab4, 0x2ab4, 0xaab4,
  522. 0xccd4, 0x4cd4, 0x2cd4, 0xacd4, 0x34d4, 0xb4d4, 0xd4d4, 0x54d4,
  523. 0x32d4, 0xb2d4, 0xd2d4, 0x52d4, 0xcad4, 0x4ad4, 0x2ad4, 0xaad4,
  524. 0x3354, 0xb354, 0xd354, 0x5354, 0xcb54, 0x4b54, 0x2b54, 0xab54,
  525. 0xcd54, 0x4d54, 0x2d54, 0xad54, 0x3554, 0xb554, 0xd554, 0x5554,
  526. 0x3332, 0xb332, 0xd332, 0x5332, 0xcb32, 0x4b32, 0x2b32, 0xab32,
  527. 0xcd32, 0x4d32, 0x2d32, 0xad32, 0x3532, 0xb532, 0xd532, 0x5532,
  528. 0xccb2, 0x4cb2, 0x2cb2, 0xacb2, 0x34b2, 0xb4b2, 0xd4b2, 0x54b2,
  529. 0x32b2, 0xb2b2, 0xd2b2, 0x52b2, 0xcab2, 0x4ab2, 0x2ab2, 0xaab2,
  530. 0xccd2, 0x4cd2, 0x2cd2, 0xacd2, 0x34d2, 0xb4d2, 0xd4d2, 0x54d2,
  531. 0x32d2, 0xb2d2, 0xd2d2, 0x52d2, 0xcad2, 0x4ad2, 0x2ad2, 0xaad2,
  532. 0x3352, 0xb352, 0xd352, 0x5352, 0xcb52, 0x4b52, 0x2b52, 0xab52,
  533. 0xcd52, 0x4d52, 0x2d52, 0xad52, 0x3552, 0xb552, 0xd552, 0x5552,
  534. 0xccca, 0x4cca, 0x2cca, 0xacca, 0x34ca, 0xb4ca, 0xd4ca, 0x54ca,
  535. 0x32ca, 0xb2ca, 0xd2ca, 0x52ca, 0xcaca, 0x4aca, 0x2aca, 0xaaca,
  536. 0x334a, 0xb34a, 0xd34a, 0x534a, 0xcb4a, 0x4b4a, 0x2b4a, 0xab4a,
  537. 0xcd4a, 0x4d4a, 0x2d4a, 0xad4a, 0x354a, 0xb54a, 0xd54a, 0x554a,
  538. 0x332a, 0xb32a, 0xd32a, 0x532a, 0xcb2a, 0x4b2a, 0x2b2a, 0xab2a,
  539. 0xcd2a, 0x4d2a, 0x2d2a, 0xad2a, 0x352a, 0xb52a, 0xd52a, 0x552a,
  540. 0xccaa, 0x4caa, 0x2caa, 0xacaa, 0x34aa, 0xb4aa, 0xd4aa, 0x54aa,
  541. 0x32aa, 0xb2aa, 0xd2aa, 0x52aa, 0xcaaa, 0x4aaa, 0x2aaa, 0xaaaa
  542. };