Distorted audio from DAC using 24-bit I2S bus Topic is solved

Discussions about USB Audio on XMOS devices
maxter
Member++
Posts: 24
Joined: Fri Jun 14, 2024 9:55 am

Distorted audio from DAC using 24-bit I2S bus

Post by maxter »

I have a custom board using the XMOS XU316 and a 24-bit DAC connected via I2S.
While sending a test tone via USB I found that when I the amplitude of the sine is above a certain level the audio gets distorted (seemingly some overflow).

I strongly suspect this is due to the different bit-width between the data sent from the XMOS and the DAC. I found that the XUA_I2S_N_BITS define allows only 16 or 32 bit configuration; is there a strong design reason for this or is it possible to modify the current i2s library to work in 24-bit mode?
View Solution
User avatar
Ross
Verified
XCore Legend
Posts: 1150
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

Check the I2S in the DAC is set to "I2S" or "standard" mode. Not left or right justified.

Most 24bit DACS will expect 32bits per channel via I2S and only use 24, discarding any other bits. An actual 24-bit i2s interface would be quite rare. We have had to interface to some DSPs in the past that required an actual 16bit I2S/TDM frame, hence the support.
Technical Director @ XMOS. Opinions expressed are my own
maxter
Member++
Posts: 24
Joined: Fri Jun 14, 2024 9:55 am

Post by maxter »

Ross wrote: Mon Nov 25, 2024 12:45 pm Check the I2S in the DAC is set to "I2S" or "standard" mode. Not left or right justified.

Most 24bit dacs will expect 32bits per channel via I2S and only use 24. An actual 24-bit i2s interface would be quite rare.
Unfortunately I think we are in the "rare" case: I double checked that the data format setting is I2S (by reading back the I2C register) and the DAC's datasheet (which doesn't have lots of information) reports "I2S, up to 24-bit data" both in the I2C register description and in the timing diagram.

If that was the case, how easy/difficult is it to modify the I2S library to send 24 bit of data instead of 32?
User avatar
Ross
Verified
XCore Legend
Posts: 1150
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

Which DAC is it out of interest?
Technical Director @ XMOS. Opinions expressed are my own
maxter
Member++
Posts: 24
Joined: Fri Jun 14, 2024 9:55 am

Post by maxter »

It's the Cirrus Logic CS4398.
User avatar
Ross
Verified
XCore Legend
Posts: 1150
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

The device has left justified mode as its default, are you sure it's in I2S mode? if you have access to control port set the Mode Control 1 Register (0x02) Digital Interface Format (DIF2:0) BITs 6-4 to 001 (default is 000)

or if using standalone mode pull M0 high.

To answer your question directly, I can't quite remember why 24 bit support wasn't allowed. There was a reason though... I don’t expect you to need it though.

Setting XUA_I2S_N_BITS to 24 and removing the error is worth a shot if you really want to give it a go.
Technical Director @ XMOS. Opinions expressed are my own
maxter
Member++
Posts: 24
Joined: Fri Jun 14, 2024 9:55 am

Post by maxter »

Ross wrote: Mon Nov 25, 2024 4:58 pm The device has left justified mode as its default, are you sure it's in I2S mode? if you have access to control port set the Mode Control 1 Register (0x02) Digital Interface Format (DIF2:0) BITs 6-4 to 001 (default is 000)

or if using standalone mode pull M0 high.
I am in control mode, and actively use I2C to control the device. The read-back value of register 0x02 is 0x10 - i.e. the data format is I2S.
Ross wrote: Mon Nov 25, 2024 4:58 pm To answer your question directly, I can't quite remember why 24 bit support wasn't allowed. There was a reason though... I don’t expect you to need it though.

Setting XUA_I2S_N_BITS to 24 and removing the error is worth a shot if you really want to give it a go.
I will give it a try.
maxter
Member++
Posts: 24
Joined: Fri Jun 14, 2024 9:55 am

Post by maxter »

Ross wrote: Mon Nov 25, 2024 4:58 pm Setting XUA_I2S_N_BITS to 24 and removing the error is worth a shot if you really want to give it a go.
Unfortunately I don't get any audio setting XUA_I2S_N_BITS to 24 and I get distorted audio with 16.

Tomorrow I will inspect the clocks and data with an oscilloscope to have a better picture of the I2S data.
Joe
Verified
Experienced Member
Posts: 78
Joined: Sun Dec 13, 2009 1:12 am

Post by Joe »

Probably a bit of confusion here as we're talking about two different specs. One is the bit clock rate relative to the lrck rate - this determines how many bit clocks there are per sample (i.e. bit "slots" which could be data). The other is how many of those bit "slots" are used (the data width).

We would generally always use BCLK as 64*Fs = LRCK i.e. 32 bit clocks for each left/right sample.

As the data is MSB justified in I2S the number of bits the I2S slave uses is for it to decide. So the master can send 32 bit data and the slave can choose how much of that data to use, it might use all 32 bits or only 24 or maybe even only 16 (It just discards the LSBs it cannot use).

When cirrus say "up to 24 bit data" for their I2S rx they mean they're only using 24 bits and discarding any others (should they exist). So it's fine to send all 32 bits to the DAC.

Cheers,
Joe
XMOS hardware grey beard.
maxter
Member++
Posts: 24
Joined: Fri Jun 14, 2024 9:55 am

Post by maxter »

Joe wrote: Tue Nov 26, 2024 11:41 am Probably a bit of confusion here as we're talking about two different specs. One is the bit clock rate relative to the lrck rate - this determines how many bit clocks there are per sample (i.e. bit "slots" which could be data). The other is how many of those bit "slots" are used (the data width).

We would generally always use BCLK as 64*Fs = LRCK i.e. 32 bit clocks for each left/right sample.

As the data is MSB justified in I2S the number of bits the I2S slave uses is for it to decide. So the master can send 32 bit data and the slave can choose how much of that data to use, it might use all 32 bits or only 24 or maybe even only 16 (It just discards the LSBs it cannot use).

When cirrus say "up to 24 bit data" for their I2S rx they mean they're only using 24 bits and discarding any others (should they exist). So it's fine to send all 32 bits to the DAC.

Cheers,
Joe
Thanks Joe, yes that became quite clear after I read the I2S spec and started looking at the clocks & data with an oscilloscope.

I still have a question/doubt, though: we configure our USB connection to use 24 bits (48kHz) and I was expecting that the 8 LSBs of the decoded data to be 0s but we definitely see one the oscilloscope some data there, is it "noise" or the initial 24-bits from the USB get somewhere "stretched" to fill the the whole 32 bits of an unsigned? If I set the USB connection as 16-bit I don't see any data on the lower 16 bits set on the I2S bus, as I'd expect.