Streaming Channels in parallel
Streaming Channels in parallel
I'd like to have streaming channels in parallel.
A picture says more than .....
xtimecomposer reports that I use Channel1 in more than 2 parallel statements.
How else to solve this ? and how to synchronize the outputs ?
Most probably I can run all filters and Delay on 1 core. This is just an experiment.
best regards
Simon
A picture says more than .....
xtimecomposer reports that I use Channel1 in more than 2 parallel statements.
How else to solve this ? and how to synchronize the outputs ?
Most probably I can run all filters and Delay on 1 core. This is just an experiment.
best regards
Simon
A channel connects exactly two channel ends. You can just
split channel 1 into two channels, say 1a and 1b, and output
the same data to both. If you output the correct amount of
data everywhere, things are always synchronised.
split channel 1 into two channels, say 1a and 1b, and output
the same data to both. If you output the correct amount of
data everywhere, things are always synchronised.
How do I split a channel without completely rewriting the I2S master code ?
The I2S master function is called by
I need to have one ADC channel in and 2 DAC channels out.
So I'd like to call my split function with
or hide the i2s resources and mcl/bclk settings
Would it be someting like :
The I2S master function is called by
Code: Select all
i2s_master( i2s_resource_s ,c_aud ,mclk_bclk_div );
So I'd like to call my split function with
Code: Select all
i2s_split(i2s_resource_s, AdcCannel, DacChannel0, DacChannel1, mclk_bclk_div);
Code: Select all
i2s_split(AdcCannel, DacChannel0, DacChannel1);
Code: Select all
void i2s_split( streaming chanend AdcChannel,
streaming chanend DacChannel0,
streaming chanend DacChannel1 )
{
unsigned mclk_bclk_div = MCLK_FREQ/(SAMP_FREQ * 64);
audio_hw_init();
audio_hw_config( SAMP_FREQ ); // Configure the clocking
i2s_master( i2s_resource_s ,AdcChannel ,mclk_bclk_div );
i2s_master( i2s_resource_s ,DacChannel0 ,mclk_bclk_div );
i2s_master( i2s_resource_s ,DacChannel1 ,mclk_bclk_div );
}
- sethu_jangala
- XCore Expert
- Posts: 589
- Joined: Wed Feb 29, 2012 10:03 am
By splitting the channel he means using two channels and send same data over both the channels as shown below:segher wrote:A channel connects exactly two channel ends. You can just
split channel 1 into two channels, say 1a and 1b, and output
the same data to both. If you output the correct amount of
data everywhere, things are always synchronised.
Code: Select all
void i2s_master(chanend channel_1a, chanend channel_1b )
{
unsigned data;
data = read_i2s_data();
channel_1a<:data;
channel_1b<:data;
}
- Attachments
-
- unnamed.jpg
- (27.23 KiB) Not downloaded yet
- unnamed.jpg
- (27.23 KiB) Not downloaded yet
I do understand that.By splitting the channel he means using two channels and send same data over both the channels as shown below:
However the I2S module found on xcore github has no i2s_read function.
The i2s_master which is present has a different interface.
Being :
Code: Select all
void i2s_master(r_i2s &r_i2s, streaming chanend c_data, unsigned mclk_bclk_div)
and push the new samples from 2 receiving channels in to 1 channel c_data again.
Schematically :
Code: Select all
AdcChannel0
/
c_data -
\
AdcChannel1
Code: Select all
DacChannel0
\
- c_data
/
DacChannel1
Code: Select all
for (i=0; i< NUM_OF_IN_CHANNELS; i++)
{
c_data :> InputSamples;
AdcChannel0 <: InputSamples;
AdcChannel1 <: InputSamples;
}
for (i=0; i< NUM_OF_OUT_CHANNELS; i++)
{
OutputSamples <: DacChannel0;
c_data <: OutputSamples;
OutputSamples <: DacChannel1;
c_data <: OutputSamples;
}
Pops up the next question.
Streaming channels do not seem to require a handshake.
If the process of retrieving new samples is busy for NUM_OF_INPUT_CHANNELS-1, being a left sample and right sample, is it blocking the writing of the output samples ? or not ?
How is this performed on HW ?
- sethu_jangala
- XCore Expert
- Posts: 589
- Joined: Wed Feb 29, 2012 10:03 am
Yes.stdefeber wrote: Would it be something like this ?
Code: Select all
for (i=0; i< NUM_OF_IN_CHANNELS; i++) { c_data :> InputSamples; AdcChannel0 <: InputSamples; AdcChannel1 <: InputSamples; } for (i=0; i< NUM_OF_OUT_CHANNELS; i++) { OutputSamples <: DacChannel0; c_data <: OutputSamples; OutputSamples <: DacChannel1; c_data <: OutputSamples; }
Streaming channels are same as normal channels except that handshake is not done for each data transfer.stdefeber wrote: Pops up the next question.
Streaming channels do not seem to require a handshake.
If the process of retrieving new samples is busy for NUM_OF_INPUT_CHANNELS-1, being a left sample and right sample, is it blocking the writing of the output samples ? or not ?
How is this performed on HW ?
Yes, the code you wrote above blocks until there is some data available in the c_data channel. If you want to make this non blocking, you need to use select statement:
Code: Select all
select
{
case c_data :> InputSamples:
AdcChannel0 <: InputSamples;
AdcChannel1 <: InputSamples;
break;
default:
//write your code here
break;
}
Concluding, to split and to combine all channels (AdcChannel0, AdcChannel1, DacChannel0, DacChannel1) to one channel (c_data) again, it would to be something like below.
Code: Select all
select
{
case c_data :> InputSamples:
AdcChannel0 <: InputSamples;
AdcChannel1 <: InputSamples;
break;
case DacChannel0 :> OutputSample;
c_data <: OutputSample;
case DacChannel1 :> OutputSample;
c_data <: OutputSample;
break;
default:
i2s_master(r_i2s &r_i2s, streaming chanend c_data, unsigned mclk_bclk_div);
break;
}
Code: Select all
void audio_io_test(streaming chanend AdcChannel0,
streaming chanend AdcChannel1,
streaming chanend DacChannel0,
streaming chanend DacChannel1 )
{
int InputSample;
int OutputSample;
streaming chan c_data;
while(1)
{
select
{
case c_data :> InputSample:
AdcChannel0 <: InputSample;
AdcChannel1 <: InputSample;
break;
case DacChannel0 :> OutputSample;
c_data <: OutputSample;
break;
case DacChannel1 :> OutputSample;
c_data <: OutputSample;
break;
default:
i2s_source(c_data);
break;
}
}
}
This does not seem to work !
I am getting
Code: Select all
xmake CONFIG=Release all
Creating dependencies for audio_io_test.xc
Compiling audio_io_test.xc
../src/audio_io_test.xc: In function `audio_io_test':
../src/audio_io_test.xc:57: error: parse error before ';' token
xmake[1]: *** [.build_Release/src/audio_io_test.xc.o] Error 1
xmake: *** [bin/Release/app_loopback.xe] Error 2
I haven't looked into your case specifically but you can declare a chan variable only inside a multicore main function. It needs to be passed exactly to two functions at the place of the chanend argument of those two functions. This instructs the tools that these two functions communicate with each other through a channel and will setup the chanends accordingly. A chan variable is not a real variable, it does not exist after building the application, just an instruction to the tools.
Forgot to mention, the error is on case 2 and 3 only.
@bianco
Then why am I able to assign channels in case 1 and default statement ?
@bianco
Then why am I able to assign channels in case 1 and default statement ?