I am trying to make the following changes using app_usb_aud_xk_216_mc:
1. Take the channel inputs from USB and downmix them into stereo.
2. Output the stereo mix through i2s to an external codec. It looks like the SDIO1 pin (I've added a header to the board) would be good for this. Looks like that maps to XS1_PORT_1I.
3. I'd also like to disable the rest of the functionality, such as the onboard DAC/ADC i2s pathways, midi, spdif, adat. Some of the latter look easy to disable from customdefines.h
For #1, I haven't found any examples of how to use the mixer. There is no documentation titled `mixer` that I've seen.
For #2, I guess I need to add the i2s library, but will that conflict with the i2s code that is already in module_usb_audio? Do I just need to add it to the USB tile? Can I fit all my functionality on one tile?
USB Audio Reference Changes
-
- Member
- Posts: 9
- Joined: Tue Jan 16, 2018 8:37 pm
-
- XCore Expert
- Posts: 580
- Joined: Thu Nov 26, 2015 11:47 pm
Is there a reason you want to downmix on the board? Why don't you just make the board have 2 ch input, have your PC do the downmix automatically, and bypass the DAC with your CODEC?
-
- Member
- Posts: 9
- Joined: Tue Jan 16, 2018 8:37 pm
The reason for down-mixing on the board is because the product will have controls for mixing the channels further down the road.
-
Verified
- XCore Legend
- Posts: 1143
- Joined: Thu May 27, 2010 10:08 am
You could quite easily do this by adding some code in DoSampleTransfer() in audio.xc. There is an audio path from I2S to the host using samplesIn_1/0[] which you can modify on the way in and an audio path from the host to I2S via samplesOut[] which you can modify too.I am trying to make the following changes using app_usb_aud_xk_216_mc:
1. Take the channel inputs from USB and downmix them into stereo.
Yes, SDIO1 is fine - it maps to DAC0 in the port declarations in main.xc and corresponds to samplesOut[0..1] in the above function. The board is quite nice because you can pull the jumpers off and tap into the signals using headers.2. Output the stereo mix through i2s to an external codec. It looks like the SDIO1 pin (I've added a header to the board) would be good for this. Looks like that maps to XS1_PORT_1I.
Yes, customdefines.h is your friend. Be aware that I2S_CHANS_xxx and I2S_CHANS_xxx do not have to be equal. So you could have two channels from the host and 4 channels to the DAC if you so choose, for example.3. I'd also like to disable the rest of the functionality, such as the onboard DAC/ADC i2s pathways, midi, spdif, adat. Some of the latter look easy to disable from customdefines.h
It's not 100% comprehensive, but section 3.6 of https://www.xmos.com/download/private/s ... rc1%29.pdf has some info. If you are doing a simple down mix (mono = (left >> 1) + (right >> 1) it may be simpler to go with the above approach.For #1, I haven't found any examples of how to use the mixer. There is no documentation titled `mixer` that I've seen.
You would struggle with this approach. Just change I2S_CHANS_xxx to get what you want.For #2, I guess I need to add the i2s library, but will that conflict with the i2s code that is already in module_usb_audio? Do I just need to add it to the USB tile?
Definitely (it's 5 threads for the basic ref design with no spif, midi or mixer)Can I fit all my functionality on one tile?
Engineer at XMOS
-
- Member
- Posts: 9
- Joined: Tue Jan 16, 2018 8:37 pm
Thank you for your response--it will help me get this up and running today I think.
I think I can see the path to just passing two channels through to is2 in this approach, but if I need to do a more complex mix than two channels, where would a better place to start be?You could quite easily do this by adding some code in DoSampleTransfer() in audio.xc. There is an audio path from I2S to the host using samplesIn_1/0[] which you can modify on the way in and an audio path from the host to I2S via samplesOut[] which you can modify too.1. Take the channel inputs from USB and downmix them into stereo.
-
- XCore Addict
- Posts: 199
- Joined: Tue Jan 17, 2017 9:25 pm
DoSampleTranser handles as many audio channels as you have specified. I would use a streaming chanend to send audio out of DoSampleTransfer() to your own mixer. Do whatever processing you want in your own mixer. Then send the audio back over the streaming chanend to DoSampleTransfer(). For example, in one app, within DoSampleTransfer I send 4 channels from I2S ADC in and 4 channels from USB Playback to my custom mixer. I then do some processing and with the streaming chanend, send a L/R mix for headphones and 4 channels USB input back to DoSampleTransfer().jshi wrote:Thank you for your response--it will help me get this up and running today I think.
I think I can see the path to just passing two channels through to is2 in this approach, but if I need to do a more complex mix than two channels, where would a better place to start be?You could quite easily do this by adding some code in DoSampleTransfer() in audio.xc. There is an audio path from I2S to the host using samplesIn_1/0[] which you can modify on the way in and an audio path from the host to I2S via samplesOut[] which you can modify too.1. Take the channel inputs from USB and downmix them into stereo.
-
- Member
- Posts: 9
- Joined: Tue Jan 16, 2018 8:37 pm
Am I supposed to hardcode this within the function such as:RitchRock wrote:DoSampleTranser handles as many audio channels as you have specified. I would use a streaming chanend to send audio out of DoSampleTransfer() to your own mixer. Do whatever processing you want in your own mixer. Then send the audio back over the streaming chanend to DoSampleTransfer(). For example, in one app, within DoSampleTransfer I send 4 channels from I2S ADC in and 4 channels from USB Playback to my custom mixer. I then do some processing and with the streaming chanend, send a L/R mix for headphones and 4 channels USB input back to DoSampleTransfer().
Code: Select all
streaming chan c_mixer_in;
streaming chan c_mixer_out_left;
streaming chan c_mixer_out_right;
for(int i = I2S_CHANS_ADC; i < NUM_USB_CHAN_IN; i++)
{
outuint(c_mixer_in, samplesIn_0[i]);
}
}
doMyMix(c_mixer_in, c_mixer_out_left, c_mixer_out_right);
outuint(c_mixer_out_left, samplesOut[0]);
outuint(c_mixer_out_right,samplesOut[1]);
-
- XCore Addict
- Posts: 199
- Joined: Tue Jan 17, 2017 9:25 pm
First, review XMOS Programmign Guide section 2.2.3: https://www.xmos.com/download/private/X ... on)(E).pdf
I'm assuming doMymix() is your mixer. That should be started in parallel with audio() back in your main function, along with the streaming chanend. Then, the streaming chanend would be passed through audio() into DoSampleTransfer(). You can send audio to/from your mixer with calls like this:
I'm assuming doMymix() is your mixer. That should be started in parallel with audio() back in your main function, along with the streaming chanend. Then, the streaming chanend would be passed through audio() into DoSampleTransfer(). You can send audio to/from your mixer with calls like this:
Code: Select all
//First, fill a mixer buffer with the data you want to send to the mixer
//Something like mixSend[NUM_USB_CHAN_OUT + ADC_CHANS_IN]
//Once your buffer is filled with the latest samples, send to your streaming chanend associated with mixer input.
// I'm calling it c_Mixer in the code below
#pragma loop unroll
for(int k = 0; k < (NUM_USB_CHAN_OUT + ADC_CHANS_IN); k++)
{
c_Mixer <: mixSend[k];
}
//Nowreceive the processed samples back usinig the :> operator
c_Mixer :> mixReturn[k];
-
- Member
- Posts: 9
- Joined: Tue Jan 16, 2018 8:37 pm
I do not currently have a doMyMix() function; it was hypothetical.
I have had a little more time to look into this and because I'm starting with the USB reference application, it seems complicated. I read through the current mixer.xc file and tried to map out what it is doing to help understand.
I guess I will try wiping out what is in the DoSampleTransfer() down to only stuff that I need, and replacing the preconstructed mixer with my own, but it seems like the host device control software is supposed to be able to control path of mixes, so it should be possible to do what I need it to with the current code, but I'm not sure how host commands interact with the mixer yet.
I have had a little more time to look into this and because I'm starting with the USB reference application, it seems complicated. I read through the current mixer.xc file and tried to map out what it is doing to help understand.
I guess I will try wiping out what is in the DoSampleTransfer() down to only stuff that I need, and replacing the preconstructed mixer with my own, but it seems like the host device control software is supposed to be able to control path of mixes, so it should be possible to do what I need it to with the current code, but I'm not sure how host commands interact with the mixer yet.