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.

This commit is contained in:
Ross Owen
2014-11-27 12:50:38 +00:00
parent dbbeddff03
commit 5b4a6f9e94

View File

@@ -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<NUM_USB_CHAN_IN;i++)
{
for (int i=0; i<NUM_USB_CHAN_IN; i++)
{
int sample;
int index;
#if MAX_MIX_COUNT > 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<NUM_USB_CHAN_OUT;i++)
{
int sample, x;
for (int i=0; i<NUM_USB_CHAN_OUT; i++)
unsafe {
int sample, x;
#if defined(OUT_VOLUME_IN_MIXER) && !defined(OUT_VOLUME_AFTER_MIX)
int mult;
int h;
unsigned l;
int mult;
int h;
unsigned l;
#endif
/* Receive sample from decouple */
sample = inuint(c);
/* Receive sample from decouple */
sample = inuint(c);
#if defined (LEVEL_METER_HOST) || defined(LEVEL_METER_LEDS)
/* Compute peak level data */
x = abs(sample);
if(x > 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<NUM_USB_CHAN_OUT;i++)
{
int sample,x;
for (int i=0; i<NUM_USB_CHAN_OUT; i++)
{
int sample, x;
#if defined(OUT_VOLUME_IN_MIXER) && defined(OUT_VOLUME_AFTER_MIX)
int mult;
int h;
unsigned l;
int mult;
int h;
unsigned l;
#endif
int index;
int index;
/* 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)
#if MAX_MIX_COUNT > 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<MAX_MIX_COUNT;i++)
{
write_via_xc_ptr_indexed(samples, (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + i), 0);
//write_via_xc_ptr_indexed(samples, (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + i), 0);
unsafe
{
ptr_samples[NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + i] = 0;
}
}
/* Wait for handshake and pass on */
@@ -497,10 +544,10 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2)
}
else
{
unsigned underflow = inuint(c_host);
underflow = inuint(c_host);
#if MAX_MIX_COUNT > 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<NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT;i++)
{
write_via_xc_ptr_indexed(samples,i,0);
unsafe {
//write_via_xc_ptr_indexed(samples,i,0);
ptr_samples[i] = 0;
}
{