20 #include "AudioConfig.h"
21 #include "AudioTools/CoreAudio/AudioLogger.h"
22 #include "AudioTools/CoreAudio/AudioStreams.h"
23 #include "AudioTools/CoreAudio/AudioI2S/I2SConfig.h"
24 #include "AudioTools/CoreAudio/AudioI2S/I2SStream.h"
27 #ifndef SPDIF_DATA_PIN
28 #define SPDIF_DATA_PIN 23
31 #define I2S_NUM ((i2s_port_t)0)
32 #define I2S_BITS_PER_SAMPLE (32)
33 #define I2S_CHANNELS 2
34 #define BMC_BITS_PER_SAMPLE 64
35 #define BMC_BITS_FACTOR (BMC_BITS_PER_SAMPLE / I2S_BITS_PER_SAMPLE)
36 #define SPDIF_BLOCK_SAMPLES 192
37 #define SPDIF_BUF_DIV 2
38 #define DMA_BUF_COUNT 2
40 (SPDIF_BLOCK_SAMPLES * BMC_BITS_PER_SAMPLE / I2S_BITS_PER_SAMPLE / \
42 #define I2S_BUG_MAGIC (26 * 1000 * 1000)
43 #define SPDIF_BLOCK_SIZE \
44 (SPDIF_BLOCK_SAMPLES * (BMC_BITS_PER_SAMPLE / 8) * I2S_CHANNELS)
45 #define SPDIF_BUF_SIZE (SPDIF_BLOCK_SIZE / SPDIF_BUF_DIV)
46 #define SPDIF_BUF_ARRAY_SIZE (SPDIF_BUF_SIZE / sizeof(uint32_t))
49 #define BMC_B 0x33173333
50 #define BMC_M 0x331d3333
51 #define BMC_W 0x331b3333
52 #define BMC_MW_DIF (BMC_M ^ BMC_W)
54 #define SYNC_FLIP ((BMC_B ^ BMC_M) >> (SYNC_OFFSET * 8))
62 static const uint16_t bmc_tab_uint[256] = {
63 0x3333, 0xb333, 0xd333, 0x5333, 0xcb33, 0x4b33, 0x2b33, 0xab33, 0xcd33,
64 0x4d33, 0x2d33, 0xad33, 0x3533, 0xb533, 0xd533, 0x5533, 0xccb3, 0x4cb3,
65 0x2cb3, 0xacb3, 0x34b3, 0xb4b3, 0xd4b3, 0x54b3, 0x32b3, 0xb2b3, 0xd2b3,
66 0x52b3, 0xcab3, 0x4ab3, 0x2ab3, 0xaab3, 0xccd3, 0x4cd3, 0x2cd3, 0xacd3,
67 0x34d3, 0xb4d3, 0xd4d3, 0x54d3, 0x32d3, 0xb2d3, 0xd2d3, 0x52d3, 0xcad3,
68 0x4ad3, 0x2ad3, 0xaad3, 0x3353, 0xb353, 0xd353, 0x5353, 0xcb53, 0x4b53,
69 0x2b53, 0xab53, 0xcd53, 0x4d53, 0x2d53, 0xad53, 0x3553, 0xb553, 0xd553,
70 0x5553, 0xcccb, 0x4ccb, 0x2ccb, 0xaccb, 0x34cb, 0xb4cb, 0xd4cb, 0x54cb,
71 0x32cb, 0xb2cb, 0xd2cb, 0x52cb, 0xcacb, 0x4acb, 0x2acb, 0xaacb, 0x334b,
72 0xb34b, 0xd34b, 0x534b, 0xcb4b, 0x4b4b, 0x2b4b, 0xab4b, 0xcd4b, 0x4d4b,
73 0x2d4b, 0xad4b, 0x354b, 0xb54b, 0xd54b, 0x554b, 0x332b, 0xb32b, 0xd32b,
74 0x532b, 0xcb2b, 0x4b2b, 0x2b2b, 0xab2b, 0xcd2b, 0x4d2b, 0x2d2b, 0xad2b,
75 0x352b, 0xb52b, 0xd52b, 0x552b, 0xccab, 0x4cab, 0x2cab, 0xacab, 0x34ab,
76 0xb4ab, 0xd4ab, 0x54ab, 0x32ab, 0xb2ab, 0xd2ab, 0x52ab, 0xcaab, 0x4aab,
77 0x2aab, 0xaaab, 0xcccd, 0x4ccd, 0x2ccd, 0xaccd, 0x34cd, 0xb4cd, 0xd4cd,
78 0x54cd, 0x32cd, 0xb2cd, 0xd2cd, 0x52cd, 0xcacd, 0x4acd, 0x2acd, 0xaacd,
79 0x334d, 0xb34d, 0xd34d, 0x534d, 0xcb4d, 0x4b4d, 0x2b4d, 0xab4d, 0xcd4d,
80 0x4d4d, 0x2d4d, 0xad4d, 0x354d, 0xb54d, 0xd54d, 0x554d, 0x332d, 0xb32d,
81 0xd32d, 0x532d, 0xcb2d, 0x4b2d, 0x2b2d, 0xab2d, 0xcd2d, 0x4d2d, 0x2d2d,
82 0xad2d, 0x352d, 0xb52d, 0xd52d, 0x552d, 0xccad, 0x4cad, 0x2cad, 0xacad,
83 0x34ad, 0xb4ad, 0xd4ad, 0x54ad, 0x32ad, 0xb2ad, 0xd2ad, 0x52ad, 0xcaad,
84 0x4aad, 0x2aad, 0xaaad, 0x3335, 0xb335, 0xd335, 0x5335, 0xcb35, 0x4b35,
85 0x2b35, 0xab35, 0xcd35, 0x4d35, 0x2d35, 0xad35, 0x3535, 0xb535, 0xd535,
86 0x5535, 0xccb5, 0x4cb5, 0x2cb5, 0xacb5, 0x34b5, 0xb4b5, 0xd4b5, 0x54b5,
87 0x32b5, 0xb2b5, 0xd2b5, 0x52b5, 0xcab5, 0x4ab5, 0x2ab5, 0xaab5, 0xccd5,
88 0x4cd5, 0x2cd5, 0xacd5, 0x34d5, 0xb4d5, 0xd4d5, 0x54d5, 0x32d5, 0xb2d5,
89 0xd2d5, 0x52d5, 0xcad5, 0x4ad5, 0x2ad5, 0xaad5, 0x3355, 0xb355, 0xd355,
90 0x5355, 0xcb55, 0x4b55, 0x2b55, 0xab55, 0xcd55, 0x4d55, 0x2d55, 0xad55,
91 0x3555, 0xb555, 0xd555, 0x5555,
93 static const int16_t *bmc_tab = (int16_t *)bmc_tab_uint;
95 static uint32_t spdif_buf[SPDIF_BUF_ARRAY_SIZE];
96 static uint32_t *spdif_ptr =
nullptr;
110 int pin_data = SPDIF_DATA_PIN;
111 int buffer_count = 30;
112 int buffer_size = 384;
139 LOGE(
"Unsupported number of channels: %d", cfg.
channels);
143 LOGE(
"Unsupported bits per sample: %d - must be 16!",
154 spdif_ptr = spdif_buf;
157 int sample_rate = cfg.
sample_rate * BMC_BITS_FACTOR;
162 int bclk = sample_rate * I2S_BITS_PER_SAMPLE * I2S_CHANNELS;
163 int mclk = (I2S_BUG_MAGIC / bclk) * bclk;
170 i2s_cfg.pin_bck = -1;
171 i2s_cfg.pin_data = cfg.pin_data;
173 i2s_cfg.buffer_count = cfg.buffer_count;
174 i2s_cfg.buffer_size = cfg.buffer_size;
176 i2s_cfg.i2s_format = I2S_STD_FORMAT;
179 i2s_cfg.use_apll =
true;
180 # if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0 , 0)
181 i2s_cfg.fixed_mclk = mclk;
184 i2sOn = i2s.begin(i2s_cfg);
198 LOGE(
"Unsupported bits per sample: %d - must be 16!",
219 size_t write(
const uint8_t *data,
size_t len) {
220 if (!i2sOn)
return 0;
221 const uint8_t *p = data;
224 while (p < (uint8_t *)data + len) {
228 (uint32_t)(((bmc_tab[*p] << 16) ^ bmc_tab[*(p + 1)]) << 1) >> 1;
233 (uint32_t)(((bmc_tab[*p] << 16) ^ bmc_tab[*(p)]) << 1) >> 1;
239 if (spdif_ptr >= &spdif_buf[SPDIF_BUF_ARRAY_SIZE]) {
241 ((uint8_t *)spdif_buf)[SYNC_OFFSET] ^= SYNC_FLIP;
243 i2s.
write((uint8_t *)spdif_buf,
sizeof(spdif_buf));
244 spdif_ptr = spdif_buf;
257 void spdif_buf_init(
void) {
260 uint32_t bmc_mw = BMC_W;
262 for (i = 0; i < (size_t)SPDIF_BUF_ARRAY_SIZE; i += 2) {
263 spdif_buf[i] = bmc_mw ^= BMC_MW_DIF;
268 using SPDIFStream = SPDIFOutput;