I2S_CHANS_DAC and NUM_USB_CHAN_OUT

Discussions about USB Audio on XMOS devices
AlexAdvice
XCore Addict
Posts: 146
Joined: Sun Feb 23, 2014 11:30 am

I2S_CHANS_DAC and NUM_USB_CHAN_OUT

Post by AlexAdvice »

I want to use 2 stereo channels, and output to 2 I2S data lines to 2 stereo DACs:
DATA0 - both channel are from input right channel but one inverted.
DATA1 - both channel are from input left channel but one inverted.

If I set I2S_CHANS_DAC=4 and NUM_USB_CHAN_OUT=2 will it work ?
And where (in source code) I have to implement channel inversion and distribution?

Thank you.
User avatar
fabriceo
XCore Addict
Posts: 222
Joined: Mon Jan 08, 2018 4:14 pm

Post by fabriceo »

Hi Alex,
yes you can select different USB channels than I2S DACS.
the place to rework or create sample value is declared here:
https://github.com/xmos/lib_xua/blob/67 ... ault.c#L13

so just create your own version of UserBufferManagement() somewhere to overload the weak statement and your there.
AlexAdvice
XCore Addict
Posts: 146
Joined: Sun Feb 23, 2014 11:30 am

Post by AlexAdvice »

Hi fabriceo, thank toy for your answer.

1) What will happened if I use USB_CHAN=2 and DAC_CHAN=4 ?
in audio.xc buffer one declaraed as:
static unsigned samplesOut[NUM_USB_CHAN_OUT];
and ports are:
buffered out port:32 p_i2s_dac[I2S_WIRES_DAC]; where I2S_WIRES_DAC = (I2S_CHANS_DAC / I2S_CHANS_PER_FRAME)

so we have samplesOut[2] and p_i2s_dac[2].

After we have transfers:
for left channel:
index=0;
for(int i = 0; i < I2S_CHANS_DAC; i+=I2S_CHANS_PER_FRAME) // for(i=0; i<4; i+=2)
{
p_i2s_dac[index++] <: bitrev(samplesOut);
}

for right channels:
index=0;
for(int i = 1; i < I2S_CHANS_DAC; i+=I2S_CHANS_PER_FRAME) // for(i=1; i< 4: I+=2)
{
p_i2s_dac[index++] <: bitrev(samplesOut[ i]);
}

so if unroll these, we have:
LEFT:
p_i2s_dac[0] <: bitrev(samplesOut[0]);
p_i2s_dac[1] <: bitrev(samplesOut[2]); // A
RIGHT:
p_i2s_dac[0] <: bitrev(samplesOut[1]);
p_i2s_dac[1] <: bitrev(samplesOut[3]); // B

But samplesOut[2] have only 2 elements samplesOut[0] and samplesOut[1], so what will be output to the dac1 at A and B ?

Of course I can change this to:
LEFT:
p_i2s_dac[0] <: bitrev(samplesOut[0]);
p_i2s_dac[1] <: bitrev(-samplesOut[0]); // A
RIGHT:
p_i2s_dac[0] <: bitrev(samplesOut[1]);
p_i2s_dac[1] <: bitrev(-samplesOut[1]); // B

To obtain 2 left channels at dac0 and 2 right channel at dac1, but is this is a right way?
---------------------------
2) I use an old XMOS libraries and ref.design, so I do not have xua, and these functions.
Last edited by AlexAdvice on Sun May 05, 2024 10:53 am, edited 2 times in total.
User avatar
fabriceo
XCore Addict
Posts: 222
Joined: Mon Jan 08, 2018 4:14 pm

Post by fabriceo »

Hi Alex, you have a point... the sampleOut buffer will hold only 2 samples and you need 4 bins to deliver the i2s patterns to the 2 x I2S wires (=4 dacs).

make it easy : patch to extend the sampleOut buffer and then in buffermanagement you can easily create the 2 ones:
sampleOut[2] = sampleOut[1];
sampleOut[3] = -sampleOut[2]
sampleOut[1] = -sampleOut[0];

then the standard dac outputs will deliver the left+invert and right+invert

sorry this is a bit sharp , hope it helps :)
AlexAdvice
XCore Addict
Posts: 146
Joined: Sun Feb 23, 2014 11:30 am

Post by AlexAdvice »

Hi fabriceo, thanks.