Browse Source

Tweak 32 bits mode (enable 20 bits spdif)

Philippe G 4 years ago
parent
commit
6d45f6d1b6

+ 1 - 1
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;
 

+ 18 - 7
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)

+ 2 - 2
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) {