This commit is contained in:
Ross Owen
2017-01-20 11:39:35 +00:00
3 changed files with 36 additions and 57 deletions

View File

@@ -58,27 +58,16 @@ static unsigned samplesIn[2][MAX(NUM_USB_CHAN_IN, IN_CHAN_COUNT)];
#endif #endif
static int inDownsamplingCounter = 0; static int inDownsamplingCounter = 0;
static int outDownsamplingCounter = 0; #if (I2S_DOWNSAMPLE_FACTOR_IN > 1)
#if (I2S_DOWNSAMPLE_FACTOR_IN > 1) || (I2S_DOWNSAMPLE_FACTOR_OUT > 1)
#include "src.h" #include "src.h"
static union ds3Data static union ds3Data
{ {
long long doubleWordAlignmentEnsured; long long doubleWordAlignmentEnsured;
/* delay lines = [Number of I2S channels][Number of samples/phases][Taps per phase] */ /* [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]; 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; } ds3Data;
#if (I2S_DOWNSAMPLE_FACTOR_IN > 1)
static int64_t inputDs3Sum[I2S_DOWNSAMPLE_CHANS_IN]; static int64_t inputDs3Sum[I2S_DOWNSAMPLE_CHANS_IN];
#endif // (I2S_DOWNSAMPLE_FACTOR_IN > 1) #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) #if (DSD_CHANS_DAC != 0)
extern buffered out port:32 p_dsd_dac[DSD_CHANS_DAC]; extern buffered out port:32 p_dsd_dac[DSD_CHANS_DAC];
@@ -266,6 +255,7 @@ static inline void TransferAdatTxSamples(chanend c_adat_out, const unsigned samp
/* sampsFromAudioToUsb: The sample frame that was received from the audio interfaces and that the device is going to send to the host */ /* sampsFromAudioToUsb: The sample frame that was received from the audio interfaces and that the device is going to send to the host */
void UserBufferManagement(unsigned sampsFromUsbToAudio[], unsigned sampsFromAudioToUsb[], client audManage_if i_audMan); void UserBufferManagement(unsigned sampsFromUsbToAudio[], unsigned sampsFromAudioToUsb[], client audManage_if i_audMan);
#ifndef NO_USB
#pragma unsafe arrays #pragma unsafe arrays
static inline unsigned DoSampleTransfer(chanend c_out, const int readBuffNo, const unsigned underflowWord, client audManage_if i_audMan) static inline unsigned DoSampleTransfer(chanend c_out, const int readBuffNo, const unsigned underflowWord, client audManage_if i_audMan)
{ {
@@ -323,6 +313,15 @@ static inline unsigned DoSampleTransfer(chanend c_out, const int readBuffNo, con
return 0; return 0;
} }
#else /* NO_USB */
#pragma unsafe arrays
static inline unsigned DoSampleTransfer(chanend c_out, const int readBuffNo, const unsigned underflowWord, client audManage_if i_audMan)
{
UserBufferManagement(samplesOut, samplesIn[readBuffNo], i_audMan);
return 0;
}
#endif /* NO_USB */
static inline void InitPorts(unsigned divide) static inline void InitPorts(unsigned divide)
{ {
unsigned tmp; unsigned tmp;
@@ -734,8 +733,6 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
#pragma xta endpoint "i2s_output_l" #pragma xta endpoint "i2s_output_l"
#if (I2S_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT != 0) #if (I2S_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT != 0)
if ((I2S_DOWNSAMPLE_FACTOR_OUT - 1) == outDownsamplingCounter)
{
index = 0; index = 0;
#pragma loop unroll #pragma loop unroll
/* Output "even" channel to DAC (i.e. left) */ /* Output "even" channel to DAC (i.e. left) */
@@ -749,7 +746,7 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
/* Clock out the LR Clock, the DAC data and Clock in the next sample into ADC */ /* Clock out the LR Clock, the DAC data and Clock in the next sample into ADC */
doI2SClocks(divide); doI2SClocks(divide);
#endif #endif
}
#ifdef ADAT_TX #ifdef ADAT_TX
TransferAdatTxSamples(c_adat_out, samplesOut, adatSmuxMode, 1); TransferAdatTxSamples(c_adat_out, samplesOut, adatSmuxMode, 1);
#endif #endif
@@ -870,8 +867,6 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
index = 0; index = 0;
#pragma xta endpoint "i2s_output_r" #pragma xta endpoint "i2s_output_r"
#if (I2S_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT != 0) #if (I2S_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT != 0)
if ((I2S_DOWNSAMPLE_FACTOR_OUT - 1) == outDownsamplingCounter)
{
/* Output "odd" channel to DAC (i.e. right) */ /* Output "odd" channel to DAC (i.e. right) */
#pragma loop unroll #pragma loop unroll
for(int i = 1; i < I2S_CHANS_DAC; i+=I2S_CHANS_PER_FRAME) for(int i = 1; i < I2S_CHANS_DAC; i+=I2S_CHANS_PER_FRAME)
@@ -883,11 +878,8 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
#ifndef CODEC_MASTER #ifndef CODEC_MASTER
doI2SClocks(divide); doI2SClocks(divide);
#endif #endif
}
else
{
++outDownsamplingCounter;
}
} // !dsdMode } // !dsdMode
#if (DSD_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT > 0) #if (DSD_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT > 0)
@@ -1249,7 +1241,9 @@ chanend ?c_config, chanend ?c
} }
#endif #endif
/* Handshake back */ /* Handshake back */
#ifndef NO_USB
outct(c_mix_out, XS1_CT_END); outct(c_mix_out, XS1_CT_END);
#endif
} }
} }
firstRun = 0; firstRun = 0;
@@ -1315,6 +1309,7 @@ chanend ?c_config, chanend ?c
null, i_audMan null, i_audMan
); );
#ifndef NO_USB
if(command == SET_SAMPLE_FREQ) if(command == SET_SAMPLE_FREQ)
{ {
curSamFreq = inuint(c_mix_out) * I2S_DOWNSAMPLE_FACTOR_IN; curSamFreq = inuint(c_mix_out) * I2S_DOWNSAMPLE_FACTOR_IN;
@@ -1357,6 +1352,8 @@ chanend ?c_config, chanend ?c
} }
} }
} }
#endif /* NO_USB */
#ifdef SPDIF_TX #ifdef SPDIF_TX
/* Notify S/PDIF task of impending new freq... */ /* Notify S/PDIF task of impending new freq... */
outct(c_spdif_out, XS1_CT_END); outct(c_spdif_out, XS1_CT_END);

View File

@@ -134,19 +134,6 @@
#endif #endif
#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. * @brief Only downsample one channel per input I2S frame.
* *
@@ -170,13 +157,6 @@
#define I2S_DOWNSAMPLE_CHANS_IN I2S_CHANS_ADC #define I2S_DOWNSAMPLE_CHANS_IN I2S_CHANS_ADC
#endif #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 * @brief Max supported sample frequency for device (Hz). Default: 192000
*/ */

View File

@@ -577,6 +577,7 @@ int main()
DFUHandler(dfuInterface, null); DFUHandler(dfuInterface, null);
#endif #endif
#endif #endif
#ifndef NO_USB
usb_audio_core(c_mix_out usb_audio_core(c_mix_out
#ifdef MIDI #ifdef MIDI
, c_midi , c_midi
@@ -594,6 +595,7 @@ int main()
VENDOR_REQUESTS_PARAMS_ VENDOR_REQUESTS_PARAMS_
); );
#endif /* NO_USB */
} }
on tile[AUDIO_IO_TILE]: usb_audio_io(c_mix_out, c_adc on tile[AUDIO_IO_TILE]: usb_audio_io(c_mix_out, c_adc