Nope. Channels 9 and 10 are empty.
I2S_CHANS_ADC=8
NUM_USB_CHAN_IN=10
TARGET = xk-audio-216-mc.xn
Build Configuration: 2i10o10xxxxxx
xTIMEcomposer Version: Community_14.2.4 (build 15898, Dec-20-2016)
I have tried with fresh project from XMOS web site.
What is your compiler, project and build configuration?
Maybe there is a difference in some settings of compiler at your and mine system,
because compiler can manage buffer variables at your system, and not at mine ?
Please advice.
Regards,
Dragan
Multi-channel Audio - How to add data to an audio stream? Topic is solved
-
- Member++
- Posts: 21
- Joined: Thu Jan 05, 2017 3:35 pm
-
Verified
- XCore Legend
- Posts: 1142
- Joined: Thu May 27, 2010 10:08 am
I'm on the same versions as you - I don't think this is compiler related, likely more related to the source version I'm using against yours. I am now looking at 6.15.2 (see sw_usb_audio/changelog.rst)
The key thing is for the samples sent out by DoSampleTransfer() are written to just before this is called in the main loop. So look at this function - you'll see that the ADC ones are sent then remaining ones not mapped to ADC are sent afterwards:
So it's in fact samplesIn_0[8] and samplesIn_0[9] that need to be set to send your data across.
Try this...
The key thing is for the samples sent out by DoSampleTransfer() are written to just before this is called in the main loop. So look at this function - you'll see that the ADC ones are sent then remaining ones not mapped to ADC are sent afterwards:
Code: Select all
for(int i = I2S_CHANS_ADC; i < NUM_USB_CHAN_IN; i++)
{
outuint(c_out, samplesIn_0[i]);
}
Try this...
-
- Member++
- Posts: 21
- Joined: Thu Jan 05, 2017 3:35 pm
infiniteimprobability,
EVERYTHING WORK !
I have tried everything with Studio One Audio application.
To repeat infiniteimprobability suggestions at one place for future reference:
Declarations in the customdefines.h file:
Additional lines in the audio.xc file just under the line:
static unsigned samplesOut[NUM_USB_CHAN_OUT];)
Additional lines in the audio.xc file just under lines:
/* Send over the digi channels - no odd buffering required */
#pragma loop unroll
Additional lines in the Makefile file just under the line:
# Test build configs (Note these make use of the defaults in customdefines.h)
And that is all. Build project, download it to your board and enjoy.
THANKS to infiniteimprobability for the excellent idea!
Best regards,
Dragan
EVERYTHING WORK !
I have tried everything with Studio One Audio application.
To repeat infiniteimprobability suggestions at one place for future reference:
Declarations in the customdefines.h file:
Code: Select all
/* Number of USB streaming channels - Default is 10 in 10 out */
#define NUM_USB_CHAN_IN (10) /* Device to Host */
#define NUM_USB_CHAN_OUT (10) /* Host to Device */
/* Number of IS2 chans to DAC..*/
#define I2S_CHANS_DAC (8)
/* Number of I2S chans from ADC */
#define I2S_CHANS_ADC (8)
static unsigned samplesOut[NUM_USB_CHAN_OUT];)
Code: Select all
static unsigned samplesIn[2][32];
unsigned my_data[2];
/* Send over the digi channels - no odd buffering required */
#pragma loop unroll
Code: Select all
my_data[0] = 0xAAAAAAAA; // Some 32-bit value
my_data[1] = 0xCCCCCCCC; // Some 32-bit value
samplesIn_0[8] = my_data[0];
samplesIn_0[9] = my_data[1];
# Test build configs (Note these make use of the defaults in customdefines.h)
Code: Select all
# Audio Class 2, Input (10), Output (10), No MIDI, No SPDIF IN, No ADAT i/o, No TDM mode
XCC_FLAGS_2i10o10xxxxxx = $(BUILD_FLAGS)
INCLUDE_ONLY_IN_2i10o10xxxxxx =
THANKS to infiniteimprobability for the excellent idea!
Best regards,
Dragan
You do not have the required permissions to view the files attached to this post.
-
Verified
- XCore Legend
- Posts: 1142
- Joined: Thu May 27, 2010 10:08 am
Glad it works! Thanks for sharing the solution summary - it will likely help others.
Oh the joys of Windows..
Oh the joys of Windows..
-
- Member++
- Posts: 21
- Joined: Thu Jan 05, 2017 3:35 pm
infiniteimprobability,
can you help with data passing from the main.xc file to the audio.xc file.
In the audio.xc file I have variables which I use for feeding audio channels 9 and 10:
In the main.xc file I have a gpio_handler function which handle inputs and outputs:
I need to send values from gpio_handler function in the main.xc file to the function Receive_Data in the audio.xc file which use global variables my_data[2].
I have made a streaming chan and streaming chanend function in the audio.xc file, which correctly receive values from the gpio_handler in the main.xc file (tested on XSCOPE), but when I try to assign values to global variables my_data in the function Receive_Data error occur:
Obviously variable my_data is being called in two cores (as in the code example bellow), but I don't know how to pass data without breaking parallel usage rules.
Please advice.
Regards,
Dragan
can you help with data passing from the main.xc file to the audio.xc file.
In the audio.xc file I have variables which I use for feeding audio channels 9 and 10:
Code: Select all
unsigned my_data[2];
I need to send values from gpio_handler function in the main.xc file to the function Receive_Data in the audio.xc file which use global variables my_data[2].
I have made a streaming chan and streaming chanend function in the audio.xc file, which correctly receive values from the gpio_handler in the main.xc file (tested on XSCOPE), but when I try to assign values to global variables my_data in the function Receive_Data error occur:
Code: Select all
error: use of `my_data' violates parallel usage rules
Code: Select all
int g = 7;
void task1() { g = 7; }
void task2() { printf("%d",g);}
int main() {
par {
task1();
task2();
}
return 0;
}
Regards,
Dragan
-
Verified
- XCore Legend
- Posts: 1142
- Joined: Thu May 27, 2010 10:08 am
if you really want to do this via shared memory (and both tasks are on the same tile which is needed as there is no shared memory between tiles), then the first example here using unsafe pointers https://www.xcore.com/forum/viewtopic.php?f=26&t=3061 may help.
The natural way to do this in xc/xmos (which is a CSP machine) is to use an interface or channel. . Channels are easiest for simple data value passing. Remember that normal channel passing synchrnoises both side so that they only drop through when the data has been received and acknowledged. The example in section 2.2.3 here shows you how https://www.xmos.com/download/private/X ... 28F%29.pdf
The natural way to do this in xc/xmos (which is a CSP machine) is to use an interface or channel. . Channels are easiest for simple data value passing. Remember that normal channel passing synchrnoises both side so that they only drop through when the data has been received and acknowledged. The example in section 2.2.3 here shows you how https://www.xmos.com/download/private/X ... 28F%29.pdf
-
- Member++
- Posts: 21
- Joined: Thu Jan 05, 2017 3:35 pm
infiniteimprobability,
what should I change in this code:
Function in main.xc:
Function in audio.xc:
To mention that, if I omit lines with use of my_data variables, printf values of received data from the main.xc file are corect (tested with XSCOPE).
Please advice.
Regards,
Dragan
what should I change in this code:
Function in main.xc:
Code: Select all
unsigned My_GPIO_Data[2];
void gpio_handler(streaming chanend c_Inputs, streaming chanend c_Outputs,
client input_gpio_if INPUT_1, client input_gpio_if INPUT_2,
client input_gpio_if INPUT_3, client input_gpio_if INPUT_4,
client output_gpio_if OUTPUT_1, client output_gpio_if OUTPUT_2,
client output_gpio_if OUTPUT_3, client output_gpio_if OUTPUT_4) {
// Initially switch state set to OFF (LOW) and switch trigger set to HIGH
INPUT_4.event_when_pins_eq(1); // Active HIGH (Trigger transition from LOW to HIGH)
while (1)
{
select
{
// Trigger event on INPUT_4
case INPUT_4.event():
if (INPUT_4.input() == 1)
{
OUTPUT_4.output(1);
delay_milliseconds(250); // Debounce
INPUT_4.event_when_pins_eq(0); // Active LOW (Trigger transition from HIGH to LOW)
My_GPIO_Data[0] = 0xAAAAAA00;
My_GPIO_Data[1] = 0xCCCCCC00;
c_Inputs <: My_GPIO_Data[0];
c_Outputs <: My_GPIO_Data[1];
}
else
{
OUTPUT_4.output(0);
delay_milliseconds(250); // Debounce
INPUT_4.event_when_pins_eq(1); // Active HIGH (Trigger transition from LOW to HIGH)
My_GPIO_Data[0] = 0x00000000;
My_GPIO_Data[1] = 0x00000000;
c_Inputs <: My_GPIO_Data[0];
c_Outputs <: My_GPIO_Data[1];
}
break;
} // END Event Select
} // END while(1)
}
Code: Select all
unsigned my_data[2];
void Receive_Data(streaming chanend c_Inputs, streaming chanend c_Outputs) {
unsigned Inputs;
unsigned Outputs;
while (1)
{
select {
case c_Inputs :> Inputs:
my_data[0] = Inputs; // <<<<< ******************* ERROR
printf("IN: %0.8X\n",Inputs);
break;
case c_Outputs :> Outputs:
my_data[1] = Outputs; // <<<<< ******************* ERROR
printf("OUT: %0.8X\n",Outputs);
break;
default:
break;
}
}
}
Please advice.
Regards,
Dragan
-
Verified
- XCore Legend
- Posts: 1142
- Joined: Thu May 27, 2010 10:08 am
I'm not exactly sure what is going on your situation - it depends how you are calling those functions?
Where does the debugger say it's stuck?
I assume they are from the par{} so are tasks. One looks like a proxy from a GPIO interface to pass on a channel communication (which is a bit of a waste of a thread/core but should work) and the other is a receiver to dump into shared memory.
An alternative is you could just have the select with default case inline in audio.xc (saves a thread) and that gives you a poll in effect. However, there's no way it could tolerate a length printf call in that inner loop (it's generatring the I2S signals in real time).
Please read my previous post/link about how to use shared memory to solve your compiler issue - the info's already in there.
Where does the debugger say it's stuck?
I assume they are from the par{} so are tasks. One looks like a proxy from a GPIO interface to pass on a channel communication (which is a bit of a waste of a thread/core but should work) and the other is a receiver to dump into shared memory.
An alternative is you could just have the select with default case inline in audio.xc (saves a thread) and that gives you a poll in effect. However, there's no way it could tolerate a length printf call in that inner loop (it's generatring the I2S signals in real time).
Please read my previous post/link about how to use shared memory to solve your compiler issue - the info's already in there.
-
- Member++
- Posts: 21
- Joined: Thu Jan 05, 2017 3:35 pm
I have solved problem with parallel use of data in more than two tasks, without channeling data and sharing memory between cores.
First, values of samplesIn_0[8] and samplesIn_0[9] can not be altered from some other core or task without massive modifications of USB Audio 2.0 Reference Software, because they are already used in two parallel tasks inside the USB Audio 2.0 reference software.
SOLUTION: You must write your code in the same task, on the same core, where samplesIn_0[8] and samplesIn_0[9] are used.
Be aware that you have only 2 microseconds spare time for duration of your inserted code to be possible for audio stream at speed of 192 ksps to stay intact.
Trying to solve this problem I learned a lot about data transfer trough channels, but I am surprised, that so simple things in other compilers as creating threads and tasks, are such hard in XMOS xTIME. When I write code in, for example, Visual Studio C++ and want to open a new thread, I don't care where this thread is executing, at which core, or task, and is it parallel or not. Compiler must resolve this, not programmer.
Regards,
Dragan
First, values of samplesIn_0[8] and samplesIn_0[9] can not be altered from some other core or task without massive modifications of USB Audio 2.0 Reference Software, because they are already used in two parallel tasks inside the USB Audio 2.0 reference software.
SOLUTION: You must write your code in the same task, on the same core, where samplesIn_0[8] and samplesIn_0[9] are used.
Be aware that you have only 2 microseconds spare time for duration of your inserted code to be possible for audio stream at speed of 192 ksps to stay intact.
Trying to solve this problem I learned a lot about data transfer trough channels, but I am surprised, that so simple things in other compilers as creating threads and tasks, are such hard in XMOS xTIME. When I write code in, for example, Visual Studio C++ and want to open a new thread, I don't care where this thread is executing, at which core, or task, and is it parallel or not. Compiler must resolve this, not programmer.
Regards,
Dragan