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