|
@@ -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);
|