diff --git a/module_usb_audio/audio_io/audio_io.xc b/module_usb_audio/audio_io/audio_io.xc index 57512d1b..c002d218 100755 --- a/module_usb_audio/audio_io/audio_io.xc +++ b/module_usb_audio/audio_io/audio_io.xc @@ -58,16 +58,27 @@ static unsigned samplesIn[2][MAX(NUM_USB_CHAN_IN, IN_CHAN_COUNT)]; #endif static int inDownsamplingCounter = 0; -#if (I2S_DOWNSAMPLE_FACTOR_IN > 1) +static int outDownsamplingCounter = 0; +#if (I2S_DOWNSAMPLE_FACTOR_IN > 1) || (I2S_DOWNSAMPLE_FACTOR_OUT > 1) #include "src.h" static union ds3Data { long long doubleWordAlignmentEnsured; - /* [Number of I2S channels][Number of samples/phases][Taps per phase] */ + /* delay lines = [Number of I2S channels][Number of samples/phases][Taps per phase] */ +#if (I2S_DOWNSAMPLE_FACTOR_IN > 1) int32_t inputDelayLine[I2S_DOWNSAMPLE_CHANS_IN][I2S_DOWNSAMPLE_FACTOR_IN][24]; +#endif // (I2S_DOWNSAMPLE_FACTOR_IN > 1) +#if (I2S_DOWNSAMPLE_FACTOR_OUT > 1) + int32_t outputDelayLine[I2S_DOWNSAMPLE_CHANS_OUT][I2S_DOWNSAMPLE_FACTOR_OUT][24]; +#endif // (I2S_DOWNSAMPLE_FACTOR_OUT > 1) } ds3Data; +#if (I2S_DOWNSAMPLE_FACTOR_IN > 1) static int64_t inputDs3Sum[I2S_DOWNSAMPLE_CHANS_IN]; #endif // (I2S_DOWNSAMPLE_FACTOR_IN > 1) +#if (I2S_DOWNSAMPLE_FACTOR_OUT > 1) +static int64_t outputDs3Sum[I2S_DOWNSAMPLE_CHANS_OUT]; +#endif // (I2S_DOWNSAMPLE_FACTOR_OUT > 1) +#endif // (I2S_DOWNSAMPLE_FACTOR_IN > 1) || (I2S_DOWNSAMPLE_FACTOR_OUT > 1) #if (DSD_CHANS_DAC != 0) extern buffered out port:32 p_dsd_dac[DSD_CHANS_DAC]; @@ -723,20 +734,22 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, #pragma xta endpoint "i2s_output_l" #if (I2S_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT != 0) - index = 0; -#pragma loop unroll - /* Output "even" channel to DAC (i.e. left) */ - for(int i = 0; i < I2S_CHANS_DAC; i+=I2S_CHANS_PER_FRAME) + if ((I2S_DOWNSAMPLE_FACTOR_OUT - 1) == outDownsamplingCounter) { - p_i2s_dac[index++] <: bitrev(samplesOut[frameCount +i]); - } + index = 0; +#pragma loop unroll + /* Output "even" channel to DAC (i.e. left) */ + for(int i = 0; i < I2S_CHANS_DAC; i+=I2S_CHANS_PER_FRAME) + { + p_i2s_dac[index++] <: bitrev(samplesOut[frameCount +i]); + } #endif #ifndef CODEC_MASTER - /* Clock out the LR Clock, the DAC data and Clock in the next sample into ADC */ - doI2SClocks(divide); + /* Clock out the LR Clock, the DAC data and Clock in the next sample into ADC */ + doI2SClocks(divide); #endif - + } #ifdef ADAT_TX TransferAdatTxSamples(c_adat_out, samplesOut, adatSmuxMode, 1); #endif @@ -857,19 +870,24 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, index = 0; #pragma xta endpoint "i2s_output_r" #if (I2S_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT != 0) - /* Output "odd" channel to DAC (i.e. right) */ -#pragma loop unroll - for(int i = 1; i < I2S_CHANS_DAC; i+=I2S_CHANS_PER_FRAME) + if ((I2S_DOWNSAMPLE_FACTOR_OUT - 1) == outDownsamplingCounter) { - p_i2s_dac[index++] <: bitrev(samplesOut[frameCount + i]); - } + /* Output "odd" channel to DAC (i.e. right) */ +#pragma loop unroll + for(int i = 1; i < I2S_CHANS_DAC; i+=I2S_CHANS_PER_FRAME) + { + p_i2s_dac[index++] <: bitrev(samplesOut[frameCount + i]); + } #endif #ifndef CODEC_MASTER - doI2SClocks(divide); + doI2SClocks(divide); #endif - - + } + else + { + ++outDownsamplingCounter; + } } // !dsdMode #if (DSD_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT > 0) diff --git a/module_usb_audio/devicedefines.h b/module_usb_audio/devicedefines.h index b88d334b..4ea7137f 100644 --- a/module_usb_audio/devicedefines.h +++ b/module_usb_audio/devicedefines.h @@ -134,6 +134,19 @@ #endif #endif +/** + * @brief Output I2S (host to device) channels can be downsampled by a factor of 3. + * + * Default: 1 i.e. downsampling is disabled. + */ +#ifndef I2S_DOWNSAMPLE_FACTOR_OUT +#define I2S_DOWNSAMPLE_FACTOR_OUT (1) +#else + #if (I2S_DOWNSAMPLE_FACTOR_OUT != 3) && (I2S_DOWNSAMPLE_FACTOR_OUT != 1) + #error Unsupported I2S output downsampling configuration + #endif +#endif + /** * @brief Only downsample one channel per input I2S frame. * @@ -157,6 +170,13 @@ #define I2S_DOWNSAMPLE_CHANS_IN I2S_CHANS_ADC #endif +/** + * @brief Number of output (host to device) I2S channels to downsample. + * + * Default: The number of I2S output channels. + */ +#define I2S_DOWNSAMPLE_CHANS_OUT I2S_CHANS_ADC + /** * @brief Max supported sample frequency for device (Hz). Default: 192000 */