USB Audio Reference Design - click in DSD

Sub forums for various specialist XMOS applications. e.g. USB audio, motor control and robotics.
Post Reply
AlexAdvice
XCore Addict
Posts: 138
Joined: Sun Feb 23, 2014 11:30 am

USB Audio Reference Design - click in DSD

Post by AlexAdvice »

This topic was moved from Q&A.

Hello All,Is it possible to avoid clicks during DSD playback?I mean the clicks at the beginning and  at the end of playback (so PCM->DSD and DSD-PCM transition).Clicks are presents as in DoP, as  also in Native mode.I've tried to use mute line, to short the DAC's output to ground, but click appeared before the mute is activsted, so this did not help.Thank you. Read


AlexAdvice
XCore Addict
Posts: 138
Joined: Sun Feb 23, 2014 11:30 am

Post by AlexAdvice »

infiniteimprobability wrote:

It can be done, but it needs a little thought and work.

Native DSD is easier becasue the host signals a change in interface (USB interface) which allows the firmware to identify stream start/stop. This means mute code can be applied when changing modes outside of streaming. There should be hooks for this alread (UserAudioStreamStart/UserAudioStreamStop)

DoP is trickier. Of course DoP is transported as a PCM stream. It's only at the I2S driver layer that the DoP markers are detected. When 32 consequtive markers are detected, then I2S changes the DAC mode and starts extracting and transferring DSD to the DAC. This means track or stream starts of DoP will always have 32 PCM samples followed by PCM to DSD mode change. You may also get a pop at the end, especially if the host decides to stream 0s after playing the track, which of course are not DoP samples.

The key is to assert hardware mute before any mode changes happen. This can be done in the following code at the point where dsdMode = ... is executed.

Ultimately, this will all depend on your hardware (how well/quickly it can assert mute) and where you apply the mute code. If you do not have mute hardware it is harder. It can be done, but I know that certain DACs (eg. ESS) are a lot easier to make behave quietly on mode changes than others.

Code: Select all

#if (DSD_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT > 0)

        /* 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))

        {

            if((DSD_MASK(samplesOut[0]) == dsdMarker) && (DSD_MASK(samplesOut[1]) == dsdMarker))

            {

                dsdCount++;

                dsdMarker ^= DSD_MARKER_XOR;

                if(dsdCount == DSD_EN_THRESH)

                {

                    dsdMode = DSD_MODE_DOP;

                    dsdCount = 0;

                    dsdMarker = DSD_MARKER_2;

 

                    // Set clocks low

                    p_lrclk <: 0;

                    p_bclk <: 0;

                    p_dsd_clk <: 0;

                    return 0;

                }

            }

            else

            {

                dsdCount = 0;

                dsdMarker = DSD_MARKER_2;

            }

        }

        else if(dsdMode == DSD_MODE_DOP) // DSD DoP Mode

        {

            /* If we are running in DOP mode, check if we need to come out */

            if((DSD_MASK(samplesOut[0]) != DSD_MARKER_1) && (DSD_MASK(samplesOut[1]) != DSD_MARKER_1))

            {

                if((DSD_MASK(samplesOut[0]) != DSD_MARKER_2) && (DSD_MASK(samplesOut[1]) != DSD_MARKER_2))

                {

                    dsdMode = DSD_MODE_OFF;

                    // Set clocks low

                    p_lrclk <: 0;

                    p_bclk <: 0;

                    p_dsd_clk <: 0;

                    return 0;

                }

            }

        }

#endif
Last edited by AlexAdvice on Mon Mar 30, 2015 9:54 am, edited 1 time in total.
AlexAdvice
XCore Addict
Posts: 138
Joined: Sun Feb 23, 2014 11:30 am

Post by AlexAdvice »

Then I wrote:

Thank you for the reply.

I'm making the "mute" at audiostream.xc:

Code: Select all

void UserAudioStreamStart(void)
{
      MuteAudio(0);
}

void UserAudioStreamStop(void)
{
    MuteAudio(1);
}


also at audiohw.xc I make:

Code: Select all

void AudioHwConfig(unsigned samFreq, unsigned mClk, chanend ?c_codec, unsigned dsdMode,
    unsigned samRes_DAC, unsigned samRes_ADC)
{
    timer t;
    unsigned time;
    unsigned tmp;
    unsigned freq;

    /* Put codec in reset and set master clock select appropriately */

    /* Read current port output */
    PORT32A_PEEK(tmp);
    tmp &= (~ ( P32A_F0 | P32A_F1)); // clear these bits

    MuteAudio(1);

    if(dsdMode!=DSD_MODE_OFF){ // DSD Mode -------------------------------------------------------------------------
 

        DSD_PIN <: DSD_ON;
        if(dsdMode == DSD_MODE_NATIVE){
            tmp |=P32A_F1;  // Native Mode
            if (samFreq > 6000000)  tmp |=P32A_F0;  //  // DSD128
        }else{
            if (samFreq > 3000000)  tmp |=P32A_F0;  // > 3MHz e.g. 2.2822400 MHz */) // DSD128
        }
    }else{//                      PCM Mode -------------------------------------------------------------------------
        DSD_PIN <:DSD_OFF;
        if ((samFreq % 22050) == 0){/* Frequency select low for 441000 etc */
            tmp &= (~P32A_CLK_SEL);
            freq= samFreq /44100;
        }else{ //if((samFreq % 24000) == 0)  /* Frequency select high for 48000 etc */
            tmp |= P32A_CLK_SEL;
            freq= samFreq /48000;
        }

    PORT32A_OUT(tmp);

    /* Hold in reset for MIN_RESET_TIME */
    t :> time;
    time += MIN_RESET_TIME;
    t when timerafter(time) :> int _;

    if(dsdMode!=DSD_MODE_OFF){  // tmp:  For DSD set Mute Off here, for PCM - at UserAudioStreamStart() in audiostream.xc
      MuteAudio(0);
    }
}
But I get a huge click at the beginning and at the end of DSD playback.
Last edited by AlexAdvice on Mon Mar 30, 2015 9:55 am, edited 1 time in total.
AlexAdvice
XCore Addict
Posts: 138
Joined: Sun Feb 23, 2014 11:30 am

Post by AlexAdvice »

infiniteimprobability wrote:

"But I get a huge click at the beginning and at the end of DSD playback."

Can you sepearte out DSD native and DoP and say what happens on each? The handling for these is very different as mentioned.

The UserAudioStreamStart and UserAudioStreamStop functions are called directly from EP0 as soon as the interface changes which is the first notice that the firmware gets of incoming DSD native streaming. What you have shown should help with DSD native - you will need to make the other changes into audio.xc to handled DoP better.

Havce you looked on a scope to see what happens with the DAC output vs. mute line? That could be quite helpful

Finally, it may be worth moving this to a thread - I think the Q&A format is a bit limiting for this level of discussion..
AlexAdvice
XCore Addict
Posts: 138
Joined: Sun Feb 23, 2014 11:30 am

Post by AlexAdvice »

infiniteimprobability wrote:
Can you sepearte out DSD native and DoP and say what happens on each? The handling for these is very different as mentioned

...

Havce you looked on a scope to see what happens with the DAC output vs. mute line? That could be quite helpful
Hello,
I'm in a buisiness trip for 2 weeks, I can check these when I'll return.
AlexAdvice
XCore Addict
Posts: 138
Joined: Sun Feb 23, 2014 11:30 am

Post by AlexAdvice »

When the Mute signal is changed, I have huge 1-1.2ms spike at the output.
This happens at PCM->DSD and DSD->PCM transitions in Native DSD Mode.
In DoP mode - the same, plus during positioning on the DSD-file.

Solution maybe is to make 2ms delay of the I2S/DSD-bus signals.

I just answer in Q&A for the similar question:

[quote]
Hi,

I think you need to delay the outputs for 2ms using FIFO in XMOS firmware, but how to do this I don't know.

For DoP maybe it possible to make 2 checks of markers - one before FIFO, one after. The first will switch the control signals (Mute, DSP/PCM), and the second will actualy change the bus output (LRCLK->DSD), as now.

If you will do this, please share you solution, because I'm also want to avoid this pops in my design.
[/quote
AudioBoy
Member++
Posts: 19
Joined: Fri Jun 13, 2014 1:35 pm

Post by AudioBoy »

Hello friends,
did you solved the pops at PCM-DSD-PCM transitions?
Post Reply