diff --git a/lib_xua/api/xua_conf_default.h b/lib_xua/api/xua_conf_default.h index b501b982..8a7333df 100644 --- a/lib_xua/api/xua_conf_default.h +++ b/lib_xua/api/xua_conf_default.h @@ -1082,9 +1082,9 @@ #define VOLUME_RES_MIXER (0x100) #endif -/* Handle out volume control in the mixer - disabled by default */ +/* Handle out volume control in the mixer - enabled by default */ #ifndef OUT_VOLUME_IN_MIXER -#define OUT_VOLUME_IN_MIXER (0) +#define OUT_VOLUME_IN_MIXER (1) #endif /* Apply out volume controls after the mix. Only relevant when OUT_VOLUME_IN_MIXER enabled. Enabled by default */ @@ -1294,9 +1294,9 @@ enum USBEndpointNumber_Out /* Some defines that allow us to remove unused code */ /* Useful for dropping lower part of macs in volume processing... */ -#if (FS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS > 24) || (FS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS > 24) || \ - (FS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS > 24) || (HS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS > 24) || \ - (HS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS > 24) || (HS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS > 24) +#if (FS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS > 24) || (HS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS > 24) || \ + (((FS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS > 24) || (HS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS > 24)) && (OUTPUT_FORMAT_COUNT > 1)) || \ + (((FS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS > 24) || (HS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS > 24)) && (OUTPUT_FORMAT_COUNT > 2)) #define STREAM_FORMAT_OUTPUT_RESOLUTION_32BIT_USED 1 #else #define STREAM_FORMAT_OUTPUT_RESOLUTION_32BIT_USED 0 diff --git a/lib_xua/src/core/buffer/decouple/decouple.xc b/lib_xua/src/core/buffer/decouple/decouple.xc index a387cddb..1e6ff484 100644 --- a/lib_xua/src/core/buffer/decouple/decouple.xc +++ b/lib_xua/src/core/buffer/decouple/decouple.xc @@ -67,6 +67,7 @@ unsigned int multIn[NUM_USB_CHAN_IN + 1]; static xc_ptr p_multIn; #endif +/* Default to something sensible but the following are setup at stream start (unless UAC1 only..) */ #if (AUDIO_CLASS == 2) int g_numUsbChan_In = NUM_USB_CHAN_IN; /* Number of channels to/from the USB bus - initialised to HS for UAC2.0 */ int g_numUsbChan_Out = NUM_USB_CHAN_OUT; @@ -143,7 +144,66 @@ unsigned unpackData = 0; unsigned packState = 0; unsigned packData = 0; -/* Default to something sensible but the following are setup at stream start (unless UAC1 only..) */ +static inline void SendSamples4(chanend c_mix_out) +{ + /* Doing this checking allows us to unroll */ + if(g_numUsbChan_Out == NUM_USB_CHAN_OUT) + { + /* Buffering not underflow condition send out some samples...*/ +#pragma loop unroll + for(int i = 0; i < NUM_USB_CHAN_OUT; i++) + { + int sample; + int mult; + int h; + unsigned l; + + read_via_xc_ptr(sample, g_aud_from_host_rdptr); + g_aud_from_host_rdptr+=4; + +#if (OUTPUT_VOLUME_CONTROL == 1) && (!OUT_VOLUME_IN_MIXER) + asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i)); + {h, l} = macs(mult, sample, 0, 0); + h <<= 3; +#if (STREAM_FORMAT_OUTPUT_RESOLUTION_32BIT_USED == 1) + h |= (l >>29) & 0x7; // Note: This step is not required if we assume sample depth is 24bit (rather than 32bit) + // Note: We need all 32bits for Native DSD +#endif + outuint(c_mix_out, h); +#else + outuint(c_mix_out, sample); +#endif + } + } + else + { +#pragma loop unroll + for(int i = 0; i < NUM_USB_CHAN_OUT_FS; i++) + { + int sample; + int mult; + int h; + unsigned l; + + read_via_xc_ptr(sample, g_aud_from_host_rdptr); + g_aud_from_host_rdptr+=4; + +#if (OUTPUT_VOLUME_CONTROL == 1) && (!OUT_VOLUME_IN_MIXER) + asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i)); + {h, l} = macs(mult, sample, 0, 0); + h <<= 3; +#if (STREAM_FORMAT_OUTPUT_RESOLUTION_32BIT_USED == 1) + h |= (l >>29) & 0x7; // Note: This step is not required if we assume sample depth is 24bit (rather than 32bit) + // Note: We need all 32bits for Native DSD +#endif + outuint(c_mix_out, h); +#else + outuint(c_mix_out, sample); +#endif + } + } +} + #pragma select handler #pragma unsafe arrays @@ -223,41 +283,17 @@ __builtin_unreachable(); __builtin_unreachable(); #endif /* Buffering not underflow condition send out some samples...*/ - for(int i = 0; i < g_numUsbChan_Out; i++) - { -#pragma xta endpoint "mixer_request" - int sample; - int mult; - int h; - unsigned l; - - read_via_xc_ptr(sample, g_aud_from_host_rdptr); - g_aud_from_host_rdptr+=4; - -#if (OUTPUT_VOLUME_CONTROL == 1) && (!OUT_VOLUME_IN_MIXER) - asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i)); - {h, l} = macs(mult, sample, 0, 0); - h <<= 3; -#if (STREAM_FORMAT_OUTPUT_RESOLUTION_32BIT_USED == 1) - h |= (l >>29)& 0x7; // Note: This step is not required if we assume sample depth is 24bit (rather than 32bit) - // Note: We need all 32bits for Native DSD -#endif - outuint(c_mix_out, h); -#else - outuint(c_mix_out, sample); -#endif - } - + SendSamples4(c_mix_out); break; case 3: #if (STREAM_FORMAT_OUTPUT_SUBSLOT_3_USED == 0) __builtin_unreachable(); #endif - /* Buffering not underflow condition send out some samples...*/ + /* Note, in this case the unpacking of data is more of an overhead than the loop overhead + * so we do not currently make attempts to unroll */ for(int i = 0; i < g_numUsbChan_Out; i++) { -#pragma xta endpoint "mixer_request" int sample; int mult; int h; diff --git a/lib_xua/src/core/mixer/mixer.xc b/lib_xua/src/core/mixer/mixer.xc index d99323ba..db19d0d0 100644 --- a/lib_xua/src/core/mixer/mixer.xc +++ b/lib_xua/src/core/mixer/mixer.xc @@ -7,19 +7,18 @@ #include "xua.h" #include "xua_commands.h" #include "dbcalc.h" -#include "print.h" -#if defined (LEVEL_METER_HOST) || defined(LEVEL_METER_LEDS) +/* FAST_MIXER has a bit of a nasty implentation but is more efficient */ +#ifndef FAST_MIXER +#define FAST_MIXER (1) +#endif + +#if defined (LEVEL_METER_HOST) || defined(LEVEL_METER_LEDS) || !FAST_MIXER #include "xc_ptr.h" #endif #if (MIXER) -/* FAST_MIXER has a bit of a nasty implentation but is more effcient */ -#ifndef FAST_MIXER -#define FAST_MIXER (1) -#endif - #if (OUT_VOLUME_IN_MIXER) static unsigned int multOut_array[NUM_USB_CHAN_OUT + 1]; unsafe @@ -140,6 +139,8 @@ static inline int doMix(volatile int * unsafe samples, volatile int * unsafe con read_via_xc_ptr_indexed(source, mixMap, i); sample = samples[source]; read_via_xc_ptr_indexed(weight, mult, i); + + {h,l} = macs(sample, weight, h, l); } @@ -212,7 +213,7 @@ static inline void GetSamplesFromHost(chanend c) for (int i=0; i