From 5b4a6f9e94d6ff021052577586c8c5a3978c07f1 Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Thu, 27 Nov 2014 12:50:38 +0000 Subject: [PATCH] Mix map disabled when MAX_MIX_COUNT is 0. Started to change code to using XC unsafe pointers rather than xc_ptr.h. This results in nice speed up since compiler uses ldw with intermediate addressing from DP - saves a lot of processing in the loops. --- module_usb_audio/mixer/mixer.xc | 188 ++++++++++++++++++++------------ 1 file changed, 118 insertions(+), 70 deletions(-) diff --git a/module_usb_audio/mixer/mixer.xc b/module_usb_audio/mixer/mixer.xc index def1583a..01147865 100644 --- a/module_usb_audio/mixer/mixer.xc +++ b/module_usb_audio/mixer/mixer.xc @@ -36,8 +36,12 @@ static unsigned abs(int x) } #endif -int samples_array[NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT + 1]; /* One larger for an "off" channel for mixer sources" */ -xc_ptr samples; +static int samples_array[NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT + 1]; /* One larger for an "off" channel for mixer sources" */ + +unsafe +{ + static int volatile * const unsafe ptr_samples = samples_array; +} int savedsamples2[NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT]; @@ -155,7 +159,7 @@ static inline int doMix(xc_ptr samples, xc_ptr ptr, xc_ptr mult) #endif #pragma unsafe arrays -static inline void giveSamplesToHost(chanend c, xc_ptr samples, xc_ptr ptr, xc_ptr multIn) +static inline void GiveSamplesToHost(chanend c, xc_ptr ptr, xc_ptr multIn) { #if defined(IN_VOLUME_IN_MIXER) && defined(IN_VOLUME_AFTER_MIX) int mult; @@ -164,12 +168,21 @@ static inline void giveSamplesToHost(chanend c, xc_ptr samples, xc_ptr ptr, xc_p #endif #pragma loop unroll - for (int i=0;i 0 read_via_xc_ptr_indexed(index,ptr,i); - read_via_xc_ptr_indexed(sample,samples,index); +#else + index = i + NUM_USB_CHAN_OUT; +#endif + unsafe + { + //read_via_xc_ptr_indexed(sample,samples,index); + sample = ptr_samples[index]; + } #if defined(IN_VOLUME_IN_MIXER) && defined(IN_VOLUME_AFTER_MIX) #warning IN Vols in mixer, AFTER mix & map @@ -183,97 +196,108 @@ static inline void giveSamplesToHost(chanend c, xc_ptr samples, xc_ptr ptr, xc_p #else outuint(c,sample); #endif - - } + } } #pragma unsafe arrays -static inline void getSamplesFromHost(chanend c, xc_ptr samples, int base, unsigned underflow) +static inline void GetSamplesFromHost(chanend c, unsigned underflow) { if(!underflow) { #pragma loop unroll - for (int i=0;i samples_from_host_streams[i]) - { - samples_from_host_streams[i] = x; - } + /* Compute peak level data */ + x = abs(sample); + if(x > samples_from_host_streams[i]) + { + samples_from_host_streams[i] = x; + } #endif #if defined(OUT_VOLUME_IN_MIXER) && !defined(OUT_VOLUME_AFTER_MIX) #warning OUT Vols in mixer, BEFORE mix & map - read_via_xc_ptr_indexed(mult, multOut, i); - {h, l} = macs(mult, sample, 0, 0); - h<<=3; + read_via_xc_ptr_indexed(mult, multOut, 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) + 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 - write_via_xc_ptr_indexed(multOut, index, val); - write_via_xc_ptr_indexed(samples,base+i,h); + write_via_xc_ptr_indexed(multOut, index, val); + write_via_xc_ptr_indexed(samples, i, h); #else - write_via_xc_ptr_indexed(samples,base+i,sample); + ptr_samples[i] = sample; #endif -} } + } + } } #pragma unsafe arrays -static inline void giveSamplesToDevice(chanend c, xc_ptr samples, xc_ptr ptr, xc_ptr multOut, unsigned underflow) +static inline void GiveSamplesToDevice(chanend c, xc_ptr ptr, xc_ptr multOut, unsigned underflow) { - outuint(c, underflow); if(!underflow) { #pragma loop unroll - for (int i=0;i 0 + /* If mixer turned on sort out the channel mapping */ + + /* Read pointer to sample from the map */ + read_via_xc_ptr_indexed(index, ptr, i); + + /* Read the actual sample value */ + read_via_xc_ptr_indexed(sample, samples, index); +#else + unsafe + { + /* Read the actual sample value */ + sample = ptr_samples[i]; + } +#endif #if defined(OUT_VOLUME_IN_MIXER) && defined(OUT_VOLUME_AFTER_MIX) + /* Do volume control processing */ #warning OUT Vols in mixer, AFTER mix & map - read_via_xc_ptr_indexed(mult, multOut, i); - {h, l} = macs(mult, sample, 0, 0); - h<<=3; // Shift used to be done in audio thread but now done here incase of 32bit support + read_via_xc_ptr_indexed(mult, multOut, i); + {h, l} = macs(mult, sample, 0, 0); + h<<=3; // Shift used to be done in audio thread but now done here incase of 32bit support +#error #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) + 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, h); + outuint(c, h); #else - outuint(c, sample); + outuint(c, sample); #endif - } + } } } #pragma unsafe arrays -static inline void getSamplesFromDevice(chanend c, xc_ptr samples, int base) +static inline void GetSamplesFromDevice(chanend c) { #if defined(IN_VOLUME_IN_MIXER) && !defined(IN_VOLUME_AFTER_MIX) int mult; @@ -303,13 +327,20 @@ static inline void getSamplesFromDevice(chanend c, xc_ptr samples, int base) #endif #if defined(IN_VOLUME_IN_MIXER) && !defined(IN_VOLUME_AFTER_MIX) + /* Read relevant multiplier */ read_via_xc_ptr_indexed(mult, multIn, i); + + /* Do the multiply */ {h, l} = macs(mult, sample, 0, 0); h <<=3; - write_via_xc_ptr_indexed(samples,base+i,h); + write_via_xc_ptr_indexed(samples, NUM_USB_CHAN_OUT+i, h); #else - write_via_xc_ptr_indexed(samples,base+i,sample); -#endif + /* No volume processing */ + unsafe + { + ptr_samples[NUM_USB_CHAN_OUT + i] = sample; + } +#endif } } @@ -323,15 +354,20 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2) #endif unsigned cmd; + unsigned underflow = 1; + while (1) { #pragma xta endpoint "mixer1_req" /* Request from audio() */ inuint(c_mixer2); - + + GiveSamplesToDevice(c_mixer2, samples_to_device_map, multOut, underflow); + GetSamplesFromDevice(c_mixer2); + /* Request data from decouple thread */ outuint(c_host, 0); - + /* Between request to decouple and respose ~ 400nS latency for interrupt to fire */ select { @@ -381,7 +417,6 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2) #endif break; #endif /* if MAX_MIX_COUNT > 0 */ - #ifdef IN_VOLUME_IN_MIXER case SET_MIX_IN_VOL: index = inuint(c_mix_ctl); @@ -468,6 +503,9 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2) sampFreq = inuint(c_host); mixer1_mix2_flag = sampFreq > 96000; + /* Wait for request */ + inuint(c_mixer2); + /* Inform mixer2 (or audio()) about freq change */ outct(c_mixer2, command); outuint(c_mixer2, sampFreq); @@ -475,7 +513,11 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2) case SET_STREAM_FORMAT_OUT: case SET_STREAM_FORMAT_IN: - /* Inform mixer2 (or audio()) about format change */ + + /* Wait for request */ + inuint(c_mixer2); + + /* Inform mixer2 (or audio()) about format change */ outct(c_mixer2, command); outuint(c_mixer2, inuint(c_host)); outuint(c_mixer2, inuint(c_host)); @@ -486,9 +528,14 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2) } #pragma loop unroll + /* Reset the mix values back to 0 */ for (int i=0;i 0 outuint(c_mixer2, underflow); - giveSamplesToHost(c_host, samples, samples_to_host_map, multIn); + GiveSamplesToHost(c_host, samples, samples_to_host_map, multIn); outuint(c_mixer2, 0); inuint(c_mixer2); @@ -564,10 +611,9 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2) } #else /* IF MAX_MIX_COUNT > 0 */ /* No mixes, this thread runs on its own doing just volume */ - giveSamplesToDevice(c_mixer2, samples, samples_to_device_map, multOut, underflow); - getSamplesFromDevice(c_mixer2, samples, NUM_USB_CHAN_OUT); - giveSamplesToHost(c_host, samples, samples_to_host_map, multIn); - getSamplesFromHost(c_host, samples, 0, underflow); + + GiveSamplesToHost(c_host, samples_to_host_map, multIn); + GetSamplesFromHost(c_host, underflow); #endif } } @@ -711,7 +757,8 @@ void mixer(chanend c_mix_in, chanend c_mix_out, chanend c_mix_ctl) #endif multOut = array_to_xc_ptr((multOut_array,unsigned[])); multIn = array_to_xc_ptr((multIn_array,unsigned[])); - samples = array_to_xc_ptr((samples_array,unsigned[])); + + //samples = array_to_xc_ptr((samples_array,unsigned[])); samples_to_host_map = array_to_xc_ptr((samples_to_host_map_array,unsigned[])); samples_to_device_map = array_to_xc_ptr((samples_to_device_map_array,unsigned[])); @@ -729,8 +776,9 @@ void mixer(chanend c_mix_in, chanend c_mix_out, chanend c_mix_ctl) #endif for (int i=0;i