diff --git a/components/squeezelite/output.c b/components/squeezelite/output.c index d54dcef0..08e9665e 100644 --- a/components/squeezelite/output.c +++ b/components/squeezelite/output.c @@ -254,10 +254,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; - - wrote = output.write_cb(out_frames, silence, gainL, gainR, cross_gain_in, cross_gain_out, &cross_ptr); + wrote = output.write_cb(out_frames, silence, gainL, gainR, output.channels, cross_gain_in, cross_gain_out, &cross_ptr); if (wrote <= 0) { frames -= size; diff --git a/components/squeezelite/output_bt.c b/components/squeezelite/output_bt.c index eed7ba88..50d81611 100644 --- a/components/squeezelite/output_bt.c +++ b/components/squeezelite/output_bt.c @@ -40,7 +40,7 @@ static uint8_t *btout; static frames_t oframes; static bool stats; -static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, +static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, u8_t flags, s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr); #define DECLARE_ALL_MIN_MAX \ @@ -79,7 +79,7 @@ void output_close_bt(void) { equalizer_close(); } -static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, +static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, u8_t flags, s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr) { assert(btout != NULL); @@ -90,7 +90,7 @@ static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t g _apply_cross(outputbuf, out_frames, cross_gain_in, cross_gain_out, cross_ptr); } - _apply_gain(outputbuf, out_frames, gainL, gainR); + _apply_gain(outputbuf, out_frames, gainL, gainR, flags); #if BYTES_PER_FRAME == 4 memcpy(btout + oframes * BYTES_PER_FRAME, outputbuf->readp, out_frames * BYTES_PER_FRAME); @@ -112,7 +112,7 @@ static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t g memcpy(btout + oframes * BYTES_PER_FRAME, buf, out_frames * BYTES_PER_FRAME); } - output_visu_export(btout + oframes * BYTES_PER_FRAME, out_frames, output.current_sample_rate, silence, ((gainL & ~MONO_FLAG) + (gainR & ~MONO_FLAG)) / 2); + output_visu_export(btout + oframes * BYTES_PER_FRAME, out_frames, output.current_sample_rate, silence, (gainL + gainR) / 2); oframes += out_frames; diff --git a/components/squeezelite/output_i2s.c b/components/squeezelite/output_i2s.c index cb51984c..49dc2c72 100644 --- a/components/squeezelite/output_i2s.c +++ b/components/squeezelite/output_i2s.c @@ -101,7 +101,7 @@ static struct { DECLARE_ALL_MIN_MAX; -static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, +static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, u8_t flags, s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr); static void *output_thread_i2s(void *arg); static void output_thread_i2s_stats(void *arg); @@ -398,20 +398,20 @@ bool output_volume_i2s(unsigned left, unsigned right) { /**************************************************************************************** * Write frames to the output buffer */ -static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, +static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, u8_t flags, s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr) { if (!silence) { if (output.fade == FADE_ACTIVE && output.fade_dir == FADE_CROSS && *cross_ptr) { _apply_cross(outputbuf, out_frames, cross_gain_in, cross_gain_out, cross_ptr); } - _apply_gain(outputbuf, out_frames, gainL, gainR); + _apply_gain(outputbuf, out_frames, gainL, gainR, flags); memcpy(obuf + oframes * BYTES_PER_FRAME, outputbuf->readp, out_frames * BYTES_PER_FRAME); } else { memcpy(obuf + oframes * BYTES_PER_FRAME, silencebuf, out_frames * BYTES_PER_FRAME); } - output_visu_export(obuf + oframes * BYTES_PER_FRAME, out_frames, output.current_sample_rate, silence, ((gainL & ~MONO_FLAG) + (gainR & ~MONO_FLAG)) / 2); + output_visu_export(obuf + oframes * BYTES_PER_FRAME, out_frames, output.current_sample_rate, silence, (gainL + gainR) / 2); oframes += out_frames; return out_frames; diff --git a/components/squeezelite/output_pack.c b/components/squeezelite/output_pack.c index c84d7c4e..dcf48056 100644 --- a/components/squeezelite/output_pack.c +++ b/components/squeezelite/output_pack.c @@ -43,34 +43,31 @@ s32_t to_gain(float f) { return (s32_t)(f * 65536.0F); } -void _scale_and_pack_frames(void *outputptr, s32_t *inputptr, frames_t cnt, s32_t gainL, s32_t gainR, output_format format) { +void _scale_and_pack_frames(void *outputptr, s32_t *inputptr, frames_t cnt, s32_t gainL, s32_t gainR, u8_t flags, 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)) { + if ((flags & MONO_LEFT) && (flags & MONO_RIGHT)) { 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) *ptr + (s64_t) *(ptr + 1)) / 2; ptr += 2; } - } else if (gainL & MONO_FLAG) { + } else if (flags & MONO_RIGHT) { s32_t *ptr = inputptr + 1; frames_t count = cnt; - gainL &= ~MONO_FLAG; while (count--) { *(ptr - 1) = *ptr; ptr += 2; } - } else if (gainR & MONO_FLAG) { + } else if (flags & MONO_LEFT) { s32_t *ptr = inputptr; frames_t count = cnt; - gainR &= ~MONO_FLAG; while (count--) { *(ptr + 1) = *ptr; ptr += 2; } - } + } switch(format) { #if DSD @@ -383,37 +380,37 @@ void _apply_cross(struct buffer *outputbuf, frames_t out_frames, s32_t cross_gai #if !WIN inline #endif -void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t gainR) { - if (gainL == FIXED_ONE && gainR == FIXED_ONE) { +void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t gainR, u8_t flags) { + if (gainL == FIXED_ONE && gainR == FIXED_ONE && !(flags & (MONO_LEFT | MONO_RIGHT))) { return; - } if ((gainR & MONO_FLAG) && (gainL & MONO_FLAG)) { + } else if ((flags & MONO_LEFT) && (flags & MONO_RIGHT)) { 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) { + + } else if (flags & MONO_RIGHT) { ISAMPLE_T *ptr = (ISAMPLE_T *)(void *)outputbuf->readp + 1; while (count--) { *(ptr - 1) = *ptr = gain(gainR, *ptr); ptr += 2; } - } else if (gainR & MONO_FLAG) { + } else if (flags & MONO_LEFT) { ISAMPLE_T *ptr = (ISAMPLE_T *)(void *)outputbuf->readp; while (count--) { *(ptr + 1) = *ptr = gain(gainL, *ptr); ptr += 2; } - } else { - ISAMPLE_T *ptrL = (ISAMPLE_T *)(void *)outputbuf->readp; + } else { + ISAMPLE_T *ptrL = (ISAMPLE_T *)(void *)outputbuf->readp; ISAMPLE_T *ptrR = (ISAMPLE_T *)(void *)outputbuf->readp + 1; while (count--) { *ptrL = gain(gainL, *ptrL); *ptrR = gain(gainR, *ptrR); ptrL += 2; ptrR += 2; } - } + } } diff --git a/components/squeezelite/squeezelite.h b/components/squeezelite/squeezelite.h index ddb7a4b3..b34d6451 100644 --- a/components/squeezelite/squeezelite.h +++ b/components/squeezelite/squeezelite.h @@ -472,7 +472,6 @@ void _wake_create(event_event*); #define MAX_SILENCE_FRAMES 2048 #define FIXED_ONE 0x10000 -#define MONO_FLAG 0x20000 #ifndef BYTES_PER_FRAME #define BYTES_PER_FRAME 8 @@ -655,6 +654,8 @@ typedef enum { FADE_INACTIVE = 0, FADE_DUE, FADE_ACTIVE } fade_state; typedef enum { FADE_UP = 1, FADE_DOWN, FADE_CROSS } fade_dir; typedef enum { FADE_NONE = 0, FADE_CROSSFADE, FADE_IN, FADE_OUT, FADE_INOUT } fade_mode; +#define MONO_RIGHT 0x02 +#define MONO_LEFT 0x01 #define MAX_SUPPORTED_SAMPLERATES 18 #define TEST_RATES = { 768000, 705600, 384000, 352800, 192000, 176400, 96000, 88200, 48000, 44100, 32000, 24000, 22500, 16000, 12000, 11025, 8000, 0 } @@ -675,7 +676,7 @@ struct outputstate { unsigned latency; int pa_hostapi_option; #endif - int (* write_cb)(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr); + int (* write_cb)(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, u8_t flags, s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr); unsigned start_frames; unsigned frames_played; unsigned frames_played_dmp;// frames played at the point delay is measured @@ -758,9 +759,9 @@ void output_close_stdout(void); #endif // output_pack.c -void _scale_and_pack_frames(void *outputptr, s32_t *inputptr, frames_t cnt, s32_t gainL, s32_t gainR, output_format format); +void _scale_and_pack_frames(void *outputptr, s32_t *inputptr, frames_t cnt, s32_t gainL, s32_t gainR, u8_t flags, output_format format); void _apply_cross(struct buffer *outputbuf, frames_t out_frames, s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr); -void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t gainR); +void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t gainR, u8_t flags); s32_t gain(s32_t gain, s32_t sample); s32_t to_gain(float f);