Browse Source

combined channels - release

Philippe G 4 years ago
parent
commit
3f0882ead6

+ 2 - 2
components/squeezelite/output.c

@@ -254,8 +254,8 @@ frames_t _output_frames(frames_t avail) {
 		
 		out_frames = !silence ? min(size, cont_frames) : size;
 		
-		if (output.channels & 0x01) gainR = COPY_MONO;
-		else if (output.channels & 0x02) gainL = COPY_MONO;
+		if (output.channels & 0x01) gainR |= MONO_FLAG;
+		if (output.channels & 0x02) gainL |= MONO_FLAG;
 
 		wrote = output.write_cb(out_frames, silence, gainL, gainR, cross_gain_in, cross_gain_out, &cross_ptr);
 

+ 38 - 2
components/squeezelite/output_pack.c

@@ -50,6 +50,34 @@ s32_t to_gain(float f) {
 }
 
 void _scale_and_pack_frames(void *outputptr, s32_t *inputptr, frames_t cnt, s32_t gainL, s32_t gainR, output_format format) {
+	// in-place copy input samples if mono/combined is used (never happens with DSD active)
+	if ((gainR & MONO_FLAG) && (gainL & MONO_FLAG)) {
+		s32_t *ptr = inputptr;
+		frames_t count = cnt;
+		gainL &= ~MONO_FLAG; gainR &= ~MONO_FLAG;
+		while (count--) {
+			// use 64 bits integer for purists but should really not care
+			*ptr = *(ptr + 1) = ((s64_t) gain(gainL, *ptr) + (s64_t) gain(gainR, *(ptr + 1))) / 2;
+			ptr += 2;
+		}
+	} else if (gainL & MONO_FLAG) {
+		s32_t *ptr = inputptr + 1;
+		frames_t count = cnt;
+		gainL &= ~MONO_FLAG;
+		while (count--) {
+			*(ptr - 1) = *ptr;
+			ptr += 2;
+		}
+	} else if (gainR & MONO_FLAG) {
+		s32_t *ptr = inputptr;
+		frames_t count = cnt;
+		gainR &= ~MONO_FLAG;
+		while (count--) {
+			*(ptr + 1) = *ptr;
+			ptr += 2;
+		}
+    }
+	
 	switch(format) {
 #if DSD
 	case U32_LE:
@@ -364,13 +392,21 @@ inline
 void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t gainR) {
 	if (gainL == FIXED_ONE && gainR == FIXED_ONE) {
 		return;
-	} else if (gainL == COPY_MONO) {
+	} if ((gainR & MONO_FLAG) && (gainL & MONO_FLAG)) {
+		ISAMPLE_T *ptrL = (ISAMPLE_T *)(void *)outputbuf->readp;
+		ISAMPLE_T *ptrR = (ISAMPLE_T *)(void *)outputbuf->readp + 1;
+		gainL &= ~MONO_FLAG; gainR &= ~MONO_FLAG;
+		while (count--) {
+			*ptrL = *ptrR = (gain(gainL, *ptrL) + gain(gainR, *ptrR)) / 2;
+			ptrL += 2; ptrR += 2;
+		}
+	} else if (gainL & MONO_FLAG) {
 		ISAMPLE_T *ptr = (ISAMPLE_T *)(void *)outputbuf->readp + 1;
 		while (count--) {
 			*(ptr - 1) = *ptr = gain(gainR, *ptr);
 			ptr += 2;
 		}
-	} else if (gainR == COPY_MONO) {
+	} else if (gainR & MONO_FLAG) {
 		ISAMPLE_T *ptr = (ISAMPLE_T *)(void *)outputbuf->readp;
 		while (count--) {
 			*(ptr + 1) = *ptr = gain(gainL, *ptr);

+ 1 - 1
components/squeezelite/squeezelite.h

@@ -472,7 +472,7 @@ void _wake_create(event_event*);
 #define MAX_SILENCE_FRAMES 2048
 
 #define FIXED_ONE 	0x10000
-#define COPY_MONO	(FIXED_ONE + 1)
+#define MONO_FLAG	0x20000
 
 #ifndef BYTES_PER_FRAME
 #define BYTES_PER_FRAME 8