@@ -158,10 +158,10 @@ static int get_stream_index(struct comp_dev *dev, struct comp_data *cd, uint32_t
158158}
159159
160160static void mux_prepare_active_look_up (struct comp_data * cd ,
161- struct audio_stream * sink ,
162- const struct audio_stream * * sources )
161+ struct sof_sink * sink ,
162+ struct sof_source * * sources )
163163{
164- const struct audio_stream * source ;
164+ struct sof_source * source ;
165165 int elem ;
166166 int active_elem = 0 ;
167167
@@ -171,9 +171,10 @@ static void mux_prepare_active_look_up(struct comp_data *cd,
171171 if (!source )
172172 continue ;
173173
174- if (cd -> lookup [0 ].copy_elem [elem ].in_ch >= audio_stream_get_channels (source ) ||
175- cd -> lookup [0 ].copy_elem [elem ].out_ch >= audio_stream_get_channels (sink ))
174+ if (cd -> lookup [0 ].copy_elem [elem ].in_ch >= source_get_channels (source ) ||
175+ cd -> lookup [0 ].copy_elem [elem ].out_ch >= sink_get_channels (sink )) {
176176 continue ;
177+ }
177178
178179 cd -> active_lookup .copy_elem [active_elem ] = cd -> lookup [0 ].copy_elem [elem ];
179180 active_elem ++ ;
@@ -205,18 +206,19 @@ static struct mux_look_up *get_lookup_table(struct comp_dev *dev, struct comp_da
205206}
206207
207208static void demux_prepare_active_look_up (struct comp_data * cd ,
208- struct audio_stream * sink ,
209- const struct audio_stream * source ,
209+ struct sof_sink * sink ,
210+ struct sof_source * source ,
210211 struct mux_look_up * look_up )
211212{
212213 int elem ;
213214 int active_elem = 0 ;
214215
215216 /* init pointers */
216217 for (elem = 0 ; elem < look_up -> num_elems ; elem ++ ) {
217- if (look_up -> copy_elem [elem ].in_ch >= audio_stream_get_channels (source ) ||
218- look_up -> copy_elem [elem ].out_ch >= audio_stream_get_channels (sink ))
218+ if (look_up -> copy_elem [elem ].in_ch >= source_get_channels (source ) ||
219+ look_up -> copy_elem [elem ].out_ch >= sink_get_channels (sink )) {
219220 continue ;
221+ }
220222
221223 cd -> active_lookup .copy_elem [active_elem ] = look_up -> copy_elem [elem ];
222224 active_elem ++ ;
@@ -227,56 +229,89 @@ static void demux_prepare_active_look_up(struct comp_data *cd,
227229
228230/* process and copy stream data from source to sink buffers */
229231static int demux_process (struct processing_module * mod ,
230- struct input_stream_buffer * input_buffers , int num_input_buffers ,
231- struct output_stream_buffer * output_buffers , int num_output_buffers )
232+ struct sof_source * * sources , int num_of_sources ,
233+ struct sof_sink * * sinks , int num_of_sinks )
232234{
233235 struct comp_data * cd = module_get_private_data (mod );
234236 struct comp_dev * dev = mod -> dev ;
235- struct comp_buffer * sink ;
236- struct audio_stream * sinks_stream [MUX_MAX_STREAMS ] = { NULL };
237- struct mux_look_up * look_ups [MUX_MAX_STREAMS ] = { NULL };
238- int frames ;
239- int sink_bytes ;
240- int source_bytes ;
237+ struct sof_source * source ;
238+ const void * source_data ;
239+ const void * source_start ;
240+ size_t source_size ;
241+ size_t source_bytes ;
242+ uint32_t frames ;
243+ int ret ;
241244 int i ;
242245
243246 comp_dbg (dev , "entry" );
244247
245- /* align sink streams with their respective configurations */
246- comp_dev_for_each_consumer (dev , sink ) {
247- if (comp_buffer_get_sink_state (sink ) == dev -> state ) {
248- i = get_stream_index (dev , cd , buffer_pipeline_id (sink ));
249- /* return if index wrong */
250- if (i < 0 ) {
251- return i ;
252- }
248+ if (sources == NULL && sources [0 ] == NULL ) {
249+ return 0 ;
250+ }
251+ source = sources [0 ];
253252
254- look_ups [i ] = get_lookup_table (dev , cd , buffer_pipeline_id (sink ));
255- sinks_stream [i ] = & sink -> stream ;
253+ /* if there are no sinks active, then there is nothing to do */
254+ if (num_of_sinks == 0 ) {
255+ return 0 ;
256+ }
257+
258+ /* the same number of frames is distributed to every sink, so it is
259+ * limited by both the source availability and every active sink's free
260+ * space
261+ */
262+ frames = source_get_data_frames_available (source );
263+ for (i = 0 ; i < num_of_sinks ; i ++ ) {
264+ if (sink_get_state (sinks [i ]) != dev -> state ) {
265+ comp_warn (dev , "the sink %d has diffrent state, culd not process" , i );
266+ continue ;
256267 }
268+
269+ frames = MIN (frames , sink_get_free_frames (sinks [i ]));
257270 }
258271
259- /* if there are no sinks active, then sinks[] is also empty */
260- if (num_output_buffers == 0 )
272+ if (!frames ) {
261273 return 0 ;
274+ }
262275
263- frames = input_buffers [0 ].size ;
264- source_bytes = frames * audio_stream_frame_bytes (mod -> input_buffers [0 ].data );
265- sink_bytes = frames * audio_stream_frame_bytes (mod -> output_buffers [0 ].data );
276+ /* the source is read-only and shared by all sinks, so it is obtained
277+ * once here and released once after all sinks have been served
278+ */
279+ source_bytes = frames * source_get_frame_bytes (source );
280+ ret = source_get_data (source , source_bytes , & source_data , & source_start ,
281+ & source_size );
282+ if (ret ) {
283+ return ret ;
284+ }
266285
267286 /* produce output, one sink at a time */
268- for (i = 0 ; i < num_output_buffers ; i ++ ) {
269- if (sinks_stream [i ]) {
270- demux_prepare_active_look_up (cd , sinks_stream [i ],
271- input_buffers [0 ].data , look_ups [i ]);
272- cd -> demux (dev , sinks_stream [i ], input_buffers [0 ].data ,
273- frames , & cd -> active_lookup );
287+ for (i = 0 ; i < num_of_sinks ; i ++ ) {
288+ struct sof_sink * sink = sinks [i ];
289+ uint32_t pipeline_id = sink_get_pipeline_id (sink );
290+ struct mux_look_up * look_up ;
291+
292+ /* skip sinks that are not in the same state as the component */
293+ if (sink_get_state (sink ) != dev -> state ) {
294+ continue ;
295+ }
296+
297+ /* return if configuration for this pipeline is missing */
298+ if (get_stream_index (dev , cd , pipeline_id ) < 0 ) {
299+ source_release_data (source , 0 );
300+ return - EINVAL ;
301+ }
302+
303+ look_up = get_lookup_table (dev , cd , pipeline_id );
304+ demux_prepare_active_look_up (cd , sink , source , look_up );
305+ ret = cd -> demux (dev , sink , source , source_data , source_start ,
306+ source_size , frames , & cd -> active_lookup );
307+ if (ret ) {
308+ source_release_data (source , 0 );
309+ return ret ;
274310 }
275- mod -> output_buffers [i ].size = sink_bytes ;
276311 }
277312
278- /* Update consumed */
279- mod -> input_buffers [ 0 ]. consumed = source_bytes ;
313+ /* consume the processed data from the source */
314+ source_release_data ( source , source_bytes ) ;
280315 return 0 ;
281316}
282317
@@ -307,58 +342,96 @@ static int demux_trigger(struct processing_module *mod, int cmd)
307342
308343/* process and copy stream data from source to sink buffers */
309344static int mux_process (struct processing_module * mod ,
310- struct input_stream_buffer * input_buffers , int num_input_buffers ,
311- struct output_stream_buffer * output_buffers , int num_output_buffers )
345+ struct sof_source * * sources , int num_of_sources ,
346+ struct sof_sink * * sinks , int num_of_sinks )
312347{
313348 struct comp_data * cd = module_get_private_data (mod );
314349 struct comp_dev * dev = mod -> dev ;
315- struct comp_buffer * source ;
316- const struct audio_stream * sources_stream [MUX_MAX_STREAMS ] = { NULL };
317- int frames = 0 ;
318- int sink_bytes ;
319- int i , j ;
350+ struct sof_sink * sink = sinks [0 ];
351+ struct sof_source * active_sources [MUX_MAX_STREAMS ] = { NULL };
352+ struct cir_buf_source source_bufs [MUX_MAX_STREAMS ] = { 0 };
353+ size_t source_bytes [MUX_MAX_STREAMS ] = { 0 };
354+ struct cir_buf_sink sink_buf ;
355+ size_t sink_bytes , size ;
356+ uint32_t frames ;
357+ int i , idx , ret ;
320358
321359 comp_dbg (dev , "entry" );
322360
323- /* align source streams with their respective configurations */
324- j = 0 ;
325- comp_dev_for_each_producer (dev , source ) {
326- if (comp_buffer_get_source_state (source ) == dev -> state ) {
327- if (frames )
328- frames = MIN (frames , input_buffers [j ].size );
329- else
330- frames = input_buffers [j ].size ;
331-
332- i = get_stream_index (dev , cd , buffer_pipeline_id (source ));
333- /* return if index wrong */
334- if (i < 0 ) {
335- return i ;
336- }
361+ /* if there are no sources or sinks active, then there is nothing to do */
362+ if (num_of_sinks == 0 || num_of_sources == 0 ) {
363+ return 0 ;
364+ }
365+
366+ /* the same number of frames is taken from every active source and
367+ * written to the single sink, so it is limited by both the sink free
368+ * space and every active source's availability
369+ */
370+ frames = sink_get_free_frames (sink );
371+ for (i = 0 ; i < num_of_sources ; i ++ ) {
372+ struct sof_source * source = sources [i ];
337373
338- sources_stream [i ] = & source -> stream ;
374+ /* skip sources that are not in the same state as the component */
375+ if (source_get_comp_state (source ) != dev -> state ) {
376+ continue ;
339377 }
340- j ++ ;
378+
379+ /* map the source to its configured stream index */
380+ idx = get_stream_index (dev , cd , source_get_pipeline_id (source ));
381+ if (idx < 0 ) {
382+ return idx ;
383+ }
384+
385+ active_sources [idx ] = source ;
386+ frames = MIN (frames , source_get_data_frames_available (source ));
341387 }
342388
343- /* check if there are any sources active */
344- if (num_input_buffers == 0 )
389+ if (!frames ) {
345390 return 0 ;
391+ }
346392
347- sink_bytes = frames * audio_stream_frame_bytes ( mod -> output_buffers [ 0 ]. data );
348- mux_prepare_active_look_up (cd , output_buffers [ 0 ]. data , & sources_stream [ 0 ] );
393+ /* build the active routing table for the current connections */
394+ mux_prepare_active_look_up (cd , sink , active_sources );
349395
350- /* produce output */
351- cd -> mux (dev , output_buffers [0 ].data , & sources_stream [0 ], frames , & cd -> active_lookup );
352-
353- /* Update consumed per source using each source's own frame size */
354- j = 0 ;
355- comp_dev_for_each_producer (dev , source ) {
356- if (comp_buffer_get_source_state (source ) == dev -> state )
357- mod -> input_buffers [j ].consumed =
358- frames * audio_stream_frame_bytes (mod -> input_buffers [j ].data );
359- j ++ ;
396+ /* acquire the single sink circular buffer for the whole period */
397+ sink_bytes = frames * sink_get_frame_bytes (sink );
398+ ret = sink_get_buffer (sink , sink_bytes , & sink_buf .ptr , & sink_buf .buf_start , & size );
399+ if (ret ) {
400+ return ret ;
360401 }
361- mod -> output_buffers [0 ].size = sink_bytes ;
402+ sink_buf .buf_end = (char * )sink_buf .buf_start + size ;
403+
404+ /* acquire every active source circular buffer */
405+ for (i = 0 ; i < MUX_MAX_STREAMS ; i ++ ) {
406+ if (!active_sources [i ]) {
407+ continue ;
408+ }
409+
410+ source_bytes [i ] = frames * source_get_frame_bytes (active_sources [i ]);
411+ ret = source_get_data (active_sources [i ], source_bytes [i ], & source_bufs [i ].ptr ,
412+ & source_bufs [i ].buf_start , & size );
413+ if (ret ) {
414+ /* release the sources acquired so far and the sink */
415+ for (-- i ; i >= 0 ; i -- )
416+ if (active_sources [i ]) {
417+ source_release_data (active_sources [i ], 0 );
418+ }
419+ sink_commit_buffer (sink , 0 );
420+ return ret ;
421+ }
422+ source_bufs [i ].buf_end = (const char * )source_bufs [i ].buf_start + size ;
423+ }
424+
425+ /* produce output */
426+ cd -> mux (dev , sink , & sink_buf , active_sources , source_bufs , frames , & cd -> active_lookup );
427+
428+ /* commit the produced data and consume from every active source */
429+ sink_commit_buffer (sink , sink_bytes );
430+ for (i = 0 ; i < MUX_MAX_STREAMS ; i ++ )
431+ if (active_sources [i ]) {
432+ source_release_data (active_sources [i ], source_bytes [i ]);
433+ }
434+
362435 return 0 ;
363436}
364437
@@ -445,7 +518,7 @@ static const struct module_interface mux_interface = {
445518 .set_configuration = mux_set_config ,
446519 .get_configuration = mux_get_config ,
447520 .prepare = mux_prepare ,
448- .process_audio_stream = mux_process ,
521+ .process = mux_process ,
449522 .reset = mux_reset ,
450523 .free = mux_free ,
451524};
@@ -456,7 +529,7 @@ static const struct module_interface demux_interface = {
456529 .set_configuration = mux_set_config ,
457530 .get_configuration = mux_get_config ,
458531 .prepare = mux_prepare ,
459- .process_audio_stream = demux_process ,
532+ .process = demux_process ,
460533 .trigger = demux_trigger ,
461534 .reset = mux_reset ,
462535 .free = mux_free ,
0 commit comments