From 3f0882ead6bf9ebcbdadd5474ef0dd3900bef4cc Mon Sep 17 00:00:00 2001 From: Philippe G Date: Sat, 20 Feb 2021 17:34:25 -0800 Subject: [PATCH] combined channels - release --- components/squeezelite/output.c | 4 +-- components/squeezelite/output_pack.c | 40 ++++++++++++++++++++++++++-- components/squeezelite/squeezelite.h | 2 +- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/components/squeezelite/output.c b/components/squeezelite/output.c index c34aa9ff..23c2c572 100644 --- a/components/squeezelite/output.c +++ b/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); diff --git a/components/squeezelite/output_pack.c b/components/squeezelite/output_pack.c index 01f68e91..c886f104 100644 --- a/components/squeezelite/output_pack.c +++ b/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); diff --git a/components/squeezelite/squeezelite.h b/components/squeezelite/squeezelite.h index f2f2bd54..f7245f6c 100644 --- a/components/squeezelite/squeezelite.h +++ b/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