diff --git a/components/squeezelite/output.c b/components/squeezelite/output.c index 23c2c572..d54dcef0 100644 --- a/components/squeezelite/output.c +++ b/components/squeezelite/output.c @@ -253,7 +253,7 @@ frames_t _output_frames(frames_t avail) { } out_frames = !silence ? min(size, cont_frames) : size; - + if (output.channels & 0x01) gainR |= MONO_FLAG; if (output.channels & 0x02) gainL |= MONO_FLAG; diff --git a/components/squeezelite/output_i2s.c b/components/squeezelite/output_i2s.c index 53adf37e..cb51984c 100644 --- a/components/squeezelite/output_i2s.c +++ b/components/squeezelite/output_i2s.c @@ -541,7 +541,7 @@ static void *output_thread_i2s(void *arg) { if (spdif) { spdif_convert((ISAMPLE_T*) obuf, oframes, (u32_t*) sbuf, &count); i2s_write(CONFIG_I2S_NUM, sbuf, oframes * 16, &bytes, portMAX_DELAY); - bytes /= 4; + bytes /= 16 / BYTES_PER_FRAME; #if BYTES_PER_FRAME == 4 } else if (i2s_config.bits_per_sample == 32) { i2s_write_expand(CONFIG_I2S_NUM, obuf, oframes * BYTES_PER_FRAME, 16, 32, &bytes, portMAX_DELAY); @@ -621,8 +621,9 @@ extern const u16_t spdif_bmclookup[256]; */ void spdif_convert(ISAMPLE_T *src, size_t frames, u32_t *dst, size_t *count) { u16_t hi, lo, aux; + register size_t cnt = *count; - // frames are 2 channels of 16 bits + // frames are 2 channels of 16/32 bits frames *= 2; while (frames--) { @@ -631,28 +632,38 @@ void spdif_convert(ISAMPLE_T *src, size_t frames, u32_t *dst, size_t *count) { lo = spdif_bmclookup[(u8_t) *src]; #else hi = spdif_bmclookup[(u8_t)(*src >> 24)]; - lo = spdif_bmclookup[(u8_t) *src >> 16]; + lo = spdif_bmclookup[(u8_t)(*src >> 16)]; #endif + // invert if last preceeding bit is 1 lo ^= ~((s16_t)hi) >> 16; - // 16 bits sample: + // first 16 bits *(dst+0) = ((u32_t)lo << 16) | hi; // 4 bits auxillary-audio-databits, the first used as parity +#if BYTES_PER_FRAME == 4 aux = 0xb333 ^ (((u32_t)((s16_t)lo)) >> 17); +#else + // we use 20 bits samples as we need to force parity + aux = spdif_bmclookup[(u8_t)(*src >> 12)]; + aux = (u8_t) (aux ^ (~((s16_t)lo) >> 16)); + aux |= (0xb3 ^ (((u16_t)((s8_t)aux)) >> 9)) << 8; +#endif // VUCP-Bits: Valid, Subcode, Channelstatus, Parity = 0 // As parity is always 0, we can use fixed preambles - if (++(*count) > 383) { + if (++cnt > 383) { *(dst+1) = VUCP | (PREAMBLE_B << 16 ) | aux; //special preamble for one of 192 frames - *count = 0; + cnt = 0; } else { - *(dst+1) = VUCP | ((((*count) & 0x01) ? PREAMBLE_W : PREAMBLE_M) << 16) | aux; + *(dst+1) = VUCP | (((cnt & 0x01) ? PREAMBLE_W : PREAMBLE_M) << 16) | aux; } src++; dst += 2; } + + *count = cnt; } const u16_t spdif_bmclookup[256] = { //biphase mark encoded values (least significant bit first) diff --git a/components/squeezelite/stream.c b/components/squeezelite/stream.c index 51691142..e8090ae1 100644 --- a/components/squeezelite/stream.c +++ b/components/squeezelite/stream.c @@ -453,7 +453,7 @@ void stream_file(const char *header, size_t header_len, unsigned threshold) { buf_flush(streambuf); LOCK; - + stream.header_len = header_len; memcpy(stream.header, header, header_len); *(stream.header+header_len) = '\0'; @@ -492,7 +492,7 @@ void stream_sock(u32_t ip, u16_t port, const char *header, size_t header_len, un // wait till we are not polling anymore while (polling && running) { usleep(10000); } #endif - + int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) {