Multi-channel Audio - How to add data to an audio stream? Topic is solved

If you have a simple question and just want an answer.
MisterQ
Member++
Posts: 21
Joined: Thu Jan 05, 2017 3:35 pm

Multi-channel Audio - How to add data to an audio stream?

Post by MisterQ »

Respected Colleagues,

I have made a prototype multi-channel audio board based on the xCORE-200 Multichannel Audio Platform https://www.xmos.com/support/boards?product=18334 and I have tested it with USB AUDIO 2.0 REFERENCE SOFTWARE http://www.xmos.com/support/software/uac2.

This prototype board work correctly when I use 8 channels for input and 8 channels for output and I can make a correct recording of 8 channel audio trough NAudio ASIO, so this hardware works OK.

For mine application I need to record audio from 8 audio channels, and, at the same time, to record some additional binary and status data, that must be synchronized in time with the audio data.

So, I thought that easiest way is to put that binary data into additional two input audio channels, and to read them at the PC side among with audio data.

Is it possible, and if so, how to do this? How to put some data in the 9th and 10th audio input channel? So far, I can send 10 channels audio from the board and read them on the PC with the NAudio ASIO driver, but channels 9 and 10 for now are empty.

Can somebody help whit this? Does somebody have tried this? Some example?

Best regards,
Dragan
You do not have the required permissions to view the files attached to this post.
Last edited by MisterQ on Thu Jan 05, 2017 4:15 pm, edited 4 times in total.


View Solution
MisterQ
Member++
Posts: 21
Joined: Thu Jan 05, 2017 3:35 pm

Post by MisterQ »

XMOS Stuff ?

Anything ?

For now, this Audio Interface work only with XMOS USB Audio 2.0 Reference Software.

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

Post by infiniteimprobability »

Is it possible, and if so, how to do this? How to put some data in the 9th and 10th audio input channel? So far, I can send 10 channels audio from the board and read them on the PC with the NAudio ASIO driver, but channels 9 and 10 for now are empty.

Can somebody help whit this? Does somebody have tried this? Some example?
The reference design passes bit perfect data across an isochronous endpoint, and there is no reason why that shouldn't be arbitrary binary data rather than audio samples. You will need to make sure your host doesn't mess around with it (SRC or volume control) and you will need to make sure the device volume control is set to 100%.

The place to hook into this will be in audio_io.xc. This loops (in the function deliver() ) at the sample rate.

The input is double buffered (because one is being filled as the other emptied):

Code: Select all

static unsigned samplesIn[2][32];


but this is the place to insert data. So you would do something like:

Code: Select all

samplesIn[readBuffNo][8] = my_data[0];
samplesIn[readBuffNo][9]= my_data[1];
The data is transmitted to the host left justified. For example, if in 24b mode then the valid bits will be 0xffffff00 where 1 is valid and zero is don't care.

10 channels is OK - you can stream @ 192KHz/24b within the bandwidth of a single ISO endpoint.

Give it a try - make sure you don't do anything that takes too long (less than half of a sample period) otherwise you will start pushing out the loop and break timing.
guodian
Member++
Posts: 21
Joined: Sat Nov 12, 2016 10:48 am

Post by guodian »

Code: Select all

static unsigned samplesIn[2][32];

but this is the place to insert data. So you would do something like:

Code: Select all

samplesIn[readBuffNo][8] = my_data[0];
samplesIn[readBuffNo][9]= my_data[1];
I couldn't find out this array(samplesIn[2][32]) in the audio.xc file. But I found two arrays like it.

Code: Select all

/* Two buffers for ADC data to allow for DAC and ADC ports being offset */
static unsigned samplesIn_0[NUM_USB_CHAN_IN];
static unsigned samplesIn_1[I2S_CHANS_ADC];
And it transfers data in the loop of deliver()

Code: Select all

            for(int i = 0; i < I2S_CHANS_ADC; i+=I2S_CHANS_PER_FRAME)
            {
                // p_i2s_adc[index++] :> sample;
                // Manual IN instruction since compiler generates an extra setc per IN (bug #15256)
                unsigned sample;
                asm volatile("in %0, res[%1]" : "=r"(sample)  : "r"(p_i2s_adc[index++]));

                /* Note the use of readBuffNo changes based on frameCount */
                if(buffIndex)
                    samplesIn_1[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 0, 2, 4.. on each line.
                else
                    samplesIn_0[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample);
            }
Do you mean here?
MisterQ
Member++
Posts: 21
Joined: Thu Jan 05, 2017 3:35 pm

Post by MisterQ »

infiniteimprobability,

thanks for your answer.

But, where in the USB AUDIO 2.0 REFERENCE SOFTWARE http://www.xmos.com/support/software/uac2 is the file audio_io.xc ?

Are you talking about some else reference audio software?

Please advice.

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

Post by infiniteimprobability »

Hi - sorry, the file is actually:

Code: Select all

./sc_usb_audio/module_usb_audio/audio.xc
I was looking at an unreleased version..
MisterQ
Member++
Posts: 21
Joined: Thu Jan 05, 2017 3:35 pm

Post by MisterQ »

:)

Function deliver() doesn't exist in the file audio.xc, and anywhere in the project.

Please advice.

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

Post by infiniteimprobability »

Try line 434 :)

Code: Select all

grep -r -n deliver\( .
./sc_usb_audio/module_usb_audio/audio.xc:434:unsigned static deliver(chanend c_out, chanend ?c_spd_out,
./sc_usb_audio/module_usb_audio/audio.xc:887:static void dummy_deliver(chanend c_out, unsigned &command)
./sc_usb_audio/module_usb_audio/audio.xc:1209:                command = deliver(c_mix_out,
./sc_usb_audio/module_usb_audio/audio.xc:1256:                            dummy_deliver(c_mix_out, command);
./sc_usb_audio/module_usb_audio/audio.xc:1259:                        dummy_deliver(c_mix_out, command);
./sc_usb_audio/module_usb_audio/ports/audioports.xc:35:     * deliver() should return with this being the case */
MisterQ
Member++
Posts: 21
Joined: Thu Jan 05, 2017 3:35 pm

Post by MisterQ »

:) I thought it is a void function - deliver();

I have tried but channels 9 and 10 in generated audio file are empty.

In the file audio.xc, at the beginning of the function deliver I have placed:

static unsigned samplesIn[2][32];
unsigned my_data[2];
my_data[0] = 0xAAAAAA00;
my_data[1] = 0xCCCCCC00;

in the Main Audio Loop while (1) at the beginning I have placed:

samplesIn[readBuffNo][8] = my_data[0];
samplesIn[readBuffNo][9]= my_data[1];

What I am doing wrong?

Regards,
Dragan
You do not have the required permissions to view the files attached to this post.
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

Worked for me..
Screen Shot 2017-01-10 at 13.44.58.png

Code: Select all

        static int ramp;
        samplesIn[readBuffNo][8] = ramp;
        samplesIn[readBuffNo][9] = 0x7FFFFFFF;
        ramp+=20000;
            
        {
            /* Do samples transfer */
Inserted just before the samples were transferred - near the bottom of deliver()

Did you make sure that:

Code: Select all

I2S_CHANS_ADC=8 
and

Code: Select all

NUM_USB_CHAN_IN=10
?
You do not have the required permissions to view the files attached to this post.