DSD input from ADC

If you have a simple question and just want an answer.
Imrich
Junior Member
Posts: 5
Joined: Wed Jun 15, 2016 11:59 am

DSD input from ADC

Post by Imrich »

Hi,
I am using the XS1-U8A-64-FB96 and i have working 2ioxs build configuration USB-Audio-2.0_6.12.6 with ADC PCM4202 allows recording to PC up to 192k sample rate. This ADC support DSD64/128 output and I want record it to wav with added DoP markers. Idea is that if I set 176400Hz sample rate to recording then ADC will sends DSD output data.
Tried someone to change ConfigAudioPorts() and deliver() functions to accept DSD input data?
Is there some way like use existing code for PDM MICs or it must be all configure manualy?
Thanks for advice.


User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

Tried someone to change ConfigAudioPorts() and deliver() functions to accept DSD input data?
Not aware of anyone doing this... It feels completely doable though. You will need to read the 32b DSD data from the port every other cycle, and split the 32b data into two 16b chunks with DSD markers added, every cycle. The modifications could closely follow and be added to this section (the inner loop of the I2S/DSD port loop) which does it the other way around for output (and generates the clocks):

Code: Select all

else if(dsdMode == DSD_MODE_DOP)
        {
        if(!everyOther)
            {
                dsdSample_l = ((samplesOut[0] & 0xffff00) << 8);
                dsdSample_r = ((samplesOut[1] & 0xffff00) << 8);

                everyOther = 1;

                switch (divide)
                {
                    case 8:
                    p_dsd_clk <: 0xF0F0F0F0;
                    p_dsd_clk <: 0xF0F0F0F0;
                    p_dsd_clk <: 0xF0F0F0F0;
                    p_dsd_clk <: 0xF0F0F0F0;
                    break;

                    case 4:
                    p_dsd_clk <: 0xCCCCCCCC;
                    p_dsd_clk <: 0xCCCCCCCC;
                    break;

                    case 2:
                    p_dsd_clk <: 0xAAAAAAAA;
                    break;
                }
            }
            else // everyOther
            {
                everyOther = 0;
                dsdSample_l =  dsdSample_l | ((samplesOut[0] & 0xffff00) >> 8);
                dsdSample_r =  dsdSample_r | ((samplesOut[1] & 0xffff00) >> 8);

                // Output 16 clocks DSD to all
                //p_dsd_dac[0] <: bitrev(dsdSample_l);
                //p_dsd_dac[1] <: bitrev(dsdSample_r);
                asm volatile("out res[%0], %1"::"r"(p_dsd_dac[0]),"r"(bitrev(dsdSample_l)));
                asm volatile("out res[%0], %1"::"r"(p_dsd_dac[1]),"r"(bitrev(dsdSample_r)));
                switch (divide)
                {
                    case 8:
                    p_dsd_clk <: 0xF0F0F0F0;
                    p_dsd_clk <: 0xF0F0F0F0;
                    p_dsd_clk <: 0xF0F0F0F0;
                    p_dsd_clk <: 0xF0F0F0F0;
                    break;

                    case 4:
                    p_dsd_clk <: 0xCCCCCCCC;
                    p_dsd_clk <: 0xCCCCCCCC;
                    break;

                    case 2:
                    p_dsd_clk <: 0xAAAAAAAA;
                    break;
                }

            }
        }
Some other changes will be needed though as dsdMode == DSD_MODE_DOP is only set when the markers are seen in the output stream. You would need a mechanism to force DoP mode.. I don't see any technical challenges to this though.

Is there some way like use existing code for PDM MICs or it must be all configure manualy?
You could do - its essentially a set of low pass FIR filters which convert PDM to PCM. The PDM mic SNR is probably in the 80db+ range, which is very good for voice applications, but not so suitable for audiophile apps.

I guess it depends where you want to do the conversion to PCM..
Imrich
Junior Member
Posts: 5
Joined: Wed Jun 15, 2016 11:59 am

Post by Imrich »

Thanks for the response and knowledge. If I understand correctly I have to read the 32b DSD input data clocked with DSD input bitclock frequency and into every cycle send marker with 16b DSD data to the input stream like PCM input data. But why I need a mechanism to force DoP mode? In this case when XMOS is slave and ADC master is really I need it? Not be enough if I will use it like input PCM mode with asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_dsd_adc[index++])); it will be correct? Thx
User avatar
Ross
XCore Expert
Posts: 966
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

Agree that it should be fairy straight forward to add this.

Do you wish to sometimes record in PCM/I2S mode - if so how do you initiate the mode switch?
Imrich
Junior Member
Posts: 5
Joined: Wed Jun 15, 2016 11:59 am

Post by Imrich »

Ross wrote: Do you wish to sometimes record in PCM/I2S mode - if so how do you initiate the mode switch?
DSD/PCM mode switching will be initiate by setting sample rate 176k or 352k from the recording software, so I will not do record to PCM for these sample rates but only to DSD64 or DSD128. AudioHwConfig() sends changed FS through I2C to second MCU that set ADC to DSD master mode. This way seems to be easiest but maybe PCM/DSD button on the device will be better.