XU316: lib_xua: DSD mode not detected in AudioHwConfig() Topic is solved

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
Harold Barrel
Member++
Posts: 17
Joined: Tue Apr 23, 2024 9:05 am

XU316: lib_xua: DSD mode not detected in AudioHwConfig()

Post by Harold Barrel »

Hello everyone, I opened a GitHub issue about this, and I wanted to ask if anyone has encountered the same thing.
I'm using an XK-EVK-XU316 board, and I enabled DSD playback in `lib_xua` (only DoP, no native).
After enabling DSD in the code, I'm able to play DSF files at DSD64/128 with Audirvana and Foobar2000 using DoP 1.0 or 1.1.

However, the `unsigned dsdMode` argument of `void AudioHwConfig()` is always set to `DSD_MODE_OFF`. I expect it to be `DSD_MODE_DOP` instead.
Is this functionality supposed to work correctly? Or is there some tweak to make DoP recognized?

Thanks in advance!
Michele


View Solution
User avatar
fabriceo
XCore Addict
Posts: 212
Joined: Mon Jan 08, 2018 4:14 pm

Post by fabriceo »

Hi Harold,
it can be seen in audio hub here:
https://github.com/xmos/lib_xua/blob/67 ... ub.xc#L791
that the dsdMode is properly set before calling AudioHwConfig(...) so if you do not get DSD_MODE_DOP then it might not be DoP ...
good lucjk
User avatar
Harold Barrel
Member++
Posts: 17
Joined: Tue Apr 23, 2024 9:05 am

Post by Harold Barrel »

Hi Fabriceo, thanks for the feedback.
So far I've used only the integrated UAC2 driver in Windows 11, maybe I should try the driver from Thesycon too...
User avatar
Harold Barrel
Member++
Posts: 17
Joined: Tue Apr 23, 2024 9:05 am

Post by Harold Barrel »

Hello again, after further testing with the XMOS ASIO driver, I can confirm that dsdMode isn't set to DSD_MODE_DOP, even though I'm playing DoP.
I know for sure that the audio isn't being converted to PCM, because the codec on the XK-EVK-XU316 board doesn't output music when I'm playing DoP: I hear low level noise, which is what you'd expect.
Could someone please try to reproduce this?

fabriceo wrote: Fri May 03, 2024 7:18 am Hi Harold,
it can be seen in audio hub here:
https://github.com/xmos/lib_xua/blob/67 ... ub.xc#L791
that the dsdMode is properly set before calling AudioHwConfig(...) so if you do not get DSD_MODE_DOP then it might not be DoP ...
good lucjk
On line 73, dsdMode is set to DSD_MODE_OFF: https://github.com/xmos/lib_xua/blob/67 ... hub.xc#L73
Then on line 910, dsdMode is set to inuint(c_aud): https://github.com/xmos/lib_xua/blob/67 ... ub.xc#L910
I couldn't find a function definition of the inuint function, so I don't know how it works.
User avatar
fabriceo
XCore Addict
Posts: 212
Joined: Mon Jan 08, 2018 4:14 pm

Post by fabriceo »

Dear Harold

I suspect that you do not send "bit perfect" DoP stream to the XU316 board.

let me try to put this in perspective.

When the player send DoP, the data sent over USB are flagged as "normal" PCM, like any other PCM music, but as you know there is a special pattern in the high bits, switching from 0xFA0000 to 0x050000.

in the xmos audio application, the task in charge of buffering the USB data will just pass them as-is to the Audio hub task which will test the DoP pattern. And then the value 0 will be received in the line 910 you pointed. (inuint is a library function used to read a 32bit data in the communication channel which exist between the USB and Audio task).
When the DoP pattern is recognized for a certain amount of samples, the dsdMode variable change from 0 to 1 and the Audio task reconfigure the I2S lines and the bit clock so that the 16bits packets of DoP music are grouped by 32bits and sent at half the sampling rate to the DAC

all of this works perfectly for a long time ago.

so if you hear a small noise in the DAC, it means that the PCM DoP stream is not decoded and sent as-is to the DAC.
One reason might be that the Player or Driver is applying a volume reduction which destroy the DoP pattern.

hope this helps in your investigation
User avatar
Harold Barrel
Member++
Posts: 17
Joined: Tue Apr 23, 2024 9:05 am

Post by Harold Barrel »

Dear Fabriceo, thank you for the additional details :-)
fabriceo wrote: Mon May 06, 2024 10:35 am so if you hear a small noise in the DAC, it means that the PCM DoP stream is not decoded and sent as-is to the DAC.
Exactly, which confirms that I'm actually sending a DoP stream to the XMOS.
I didn't configure the CODEC to decode PCM DoP (I don't even know if it can do it). So yes, hearing only noise when playing DoP was what I expected!
All I care about is getting DoP out of the single-bit ports PORT_I2S_DAC_DATA and PORT_I2S_ADC_DATA (which are XS1_PORT_1A and XS1_PORT_1N, respectively), which is what I'm getting and that's fine.
We have a custom DSD-->PCM FPGA chip that handles the conversion.
fabriceo wrote: Mon May 06, 2024 10:35 am One reason might be that the Player or Driver is applying a volume reduction which destroy the DoP pattern.
I know for sure it doesn't. Audirvana doesn't allow any volume control when playing DoP. I tested the same player+driver combinations with an XMOS-based device of ours (Weiss INT204), and that old XMOS is able to detect DoP without issues.


There's one further thing that I could do: I could use an oscilloscope or a logic analyzer to look at the output of XS1_PORT_1A/XS1_PORT_1N and verify that the DoP markers are correct. But as I'm not an electronics engineer, that would take me some time... So I'm wondering if anyone could try to reproduce this, after all it's just a couple lines of code needed to enable DoP on the XK-EVK-XU316 board.
User avatar
fabriceo
XCore Addict
Posts: 212
Joined: Mon Jan 08, 2018 4:14 pm

Post by fabriceo »

Harold
you need to get visibility on whats going on in the application by issuing some "print" over xtag in xscope mode in the DoDsdDopCheck() function... If you have not yet modified the app to enable debugging/prints, it worth doing it :)
User avatar
Harold Barrel
Member++
Posts: 17
Joined: Tue Apr 23, 2024 9:05 am

Post by Harold Barrel »

fabriceo wrote: Mon May 06, 2024 11:23 am you need to get visibility on whats going on in the application by issuing some "print" over xtag in xscope mode in the DoDsdDopCheck() function...
Okay, I will try to do this.
fabriceo wrote: Mon May 06, 2024 11:23 am If you have not yet modified the app to enable debugging/prints, it worth doing it :)
No, not yet... So far I've just used xgdb to run the executables and see if they fail at some point.
I will try to set this up, it will be useful for the future.

In the meantime I'll also check the output ports 1A and 1N to see if the DoP flags are there.
I have nice co-workers, they'll help me set up the oscilloscope for this.
User avatar
Harold Barrel
Member++
Posts: 17
Joined: Tue Apr 23, 2024 9:05 am

Post by Harold Barrel »

Okay, so I added some printfs inside DoDsdDopCheck():

Code: Select all

static inline int DoDsdDopCheck(unsigned &dsdMode, int &dsdCount, unsigned curSamFreq, unsigned samplesOut[], unsigned &dsdMarker)
{
    /* Check for DSD - note we only move into DoP mode if valid DoP Freq */
    /* Currently we only check on channel 0 - we get all 0's on channels without data */
    if((dsdMode == DSD_MODE_OFF) && (curSamFreq > 96000))
    {
        printf("\n");
        printf("curSamFreq: %i\n", curSamFreq);
        printf("dsdMarker: 0x%X\n", dsdMarker);
        printf("DSD_MASK(samplesOut[0]): 0x%X\n", DSD_MASK(samplesOut[0]));
        printf("DSD_MASK(samplesOut[1]): 0x%X\n", DSD_MASK(samplesOut[1]));
        if((DSD_MASK(samplesOut[0]) == dsdMarker) && (DSD_MASK(samplesOut[1]) == dsdMarker))
        {
            dsdCount++;
            dsdMarker ^= DSD_MARKER_XOR;
            if(dsdCount == DSD_EN_THRESH)
            {
                printf("Setting dsdMode = DSD_MODE_DOP\n");
                dsdMode = DSD_MODE_DOP;
                dsdCount = 0;
                dsdMarker = DSD_MARKER_2;
                return 0;
            }
        }
        
        ....

When I play DSD64 with foobar2000/Audirvana, the markers are correct, I now get an ET_ILLEGAL_RESOURCE (why??) and the XMOS crashes:

Code: Select all

....

curSamFreq: 176400
dsdMarker: 0x5
DSD_MASK(samplesOut[0]): 0x5
DSD_MASK(samplesOut[1]): 0x5

curSamFreq: 176400
dsdMarker: 0xFA
DSD_MASK(samplesOut[0]): 0xFA
DSD_MASK(samplesOut[1]): 0xFA
Setting dsdMode = DSD_MODE_DOP
xrun: Program received signal ET_ILLEGAL_RESOURCE, Resource exception.
      [Switching to tile[1] core[0] (dual issue)]
      ConfigAudioPorts (p_i2s_dac=@0x840a0, numPortsDac=2, p_lrclk=0, p_bclk=66304, divide=8, clk_audio_bclk=774, p_mclk_in=2097158, curSamFreq=<value optimized out>) at /home/michele/Projects/DWE-GIT/G26/xmos/lib_xua/lib_xua/src/core/ports/audioports.xc:39

      39                asm volatile ("setc res[%0], %1" :: "r" (p_lrclk), "r" (0x200006));

Why would I get an ET_ILLEGAL_RESOURCE? I'm re-using the same I2S 1-bit ports ports for DSD.
In the lib_xua documentation, there was written that the PORT_DSD_DAC0/PORT_DSD_DAC1 ports could be same as for I2S.
User avatar
fabriceo
XCore Addict
Posts: 212
Joined: Mon Jan 08, 2018 4:14 pm

Post by fabriceo »

hum, no idea, i m using same ports for i2s/dsd including lrclk for dsd1 without issue... please share with us any findings