@@ -156,10 +156,10 @@ static int get_stream_index(struct comp_dev *dev, struct comp_data *cd, uint32_t
156156}
157157
158158static void mux_prepare_active_look_up (struct comp_data * cd ,
159- struct audio_stream * sink ,
160- const struct audio_stream * * sources )
159+ struct sof_sink * sink ,
160+ struct sof_source * * sources )
161161{
162- const struct audio_stream * source ;
162+ struct sof_source * source ;
163163 int elem ;
164164 int active_elem = 0 ;
165165
@@ -169,8 +169,8 @@ static void mux_prepare_active_look_up(struct comp_data *cd,
169169 if (!source )
170170 continue ;
171171
172- if (cd -> lookup [0 ].copy_elem [elem ].in_ch >= audio_stream_get_channels (source ) ||
173- cd -> lookup [0 ].copy_elem [elem ].out_ch >= audio_stream_get_channels (sink ))
172+ if (cd -> lookup [0 ].copy_elem [elem ].in_ch >= source_get_channels (source ) ||
173+ cd -> lookup [0 ].copy_elem [elem ].out_ch >= sink_get_channels (sink ))
174174 continue ;
175175
176176 cd -> active_lookup .copy_elem [active_elem ] = cd -> lookup [0 ].copy_elem [elem ];
@@ -203,17 +203,17 @@ static struct mux_look_up *get_lookup_table(struct comp_dev *dev, struct comp_da
203203}
204204
205205static void demux_prepare_active_look_up (struct comp_data * cd ,
206- struct audio_stream * sink ,
207- const struct audio_stream * source ,
206+ struct sof_sink * sink ,
207+ struct sof_source * source ,
208208 struct mux_look_up * look_up )
209209{
210210 int elem ;
211211 int active_elem = 0 ;
212212
213213 /* init pointers */
214214 for (elem = 0 ; elem < look_up -> num_elems ; elem ++ ) {
215- if (look_up -> copy_elem [elem ].in_ch >= audio_stream_get_channels (source ) ||
216- look_up -> copy_elem [elem ].out_ch >= audio_stream_get_channels (sink ))
215+ if (look_up -> copy_elem [elem ].in_ch >= source_get_channels (source ) ||
216+ look_up -> copy_elem [elem ].out_ch >= sink_get_channels (sink ))
217217 continue ;
218218
219219 cd -> active_lookup .copy_elem [active_elem ] = look_up -> copy_elem [elem ];
@@ -225,56 +225,84 @@ static void demux_prepare_active_look_up(struct comp_data *cd,
225225
226226/* process and copy stream data from source to sink buffers */
227227static int demux_process (struct processing_module * mod ,
228- struct input_stream_buffer * input_buffers , int num_input_buffers ,
229- struct output_stream_buffer * output_buffers , int num_output_buffers )
228+ struct sof_source * * sources , int num_of_sources ,
229+ struct sof_sink * * sinks , int num_of_sinks )
230230{
231231 struct comp_data * cd = module_get_private_data (mod );
232232 struct comp_dev * dev = mod -> dev ;
233- struct comp_buffer * sink ;
234- struct audio_stream * sinks_stream [MUX_MAX_STREAMS ] = { NULL };
235- struct mux_look_up * look_ups [MUX_MAX_STREAMS ] = { NULL };
236- int frames ;
237- int sink_bytes ;
238- int source_bytes ;
233+ struct sof_source * source ;
234+ const void * source_data ;
235+ const void * source_start ;
236+ size_t source_size ;
237+ size_t source_bytes ;
238+ uint32_t frames ;
239+ int ret ;
239240 int i ;
240241
241242 comp_dbg (dev , "entry" );
242243
243- /* align sink streams with their respective configurations */
244- comp_dev_for_each_consumer (dev , sink ) {
245- if (comp_buffer_get_sink_state (sink ) == dev -> state ) {
246- i = get_stream_index (dev , cd , buffer_pipeline_id (sink ));
247- /* return if index wrong */
248- if (i < 0 ) {
249- return i ;
250- }
244+ if (sources == NULL && sources [0 ] == NULL ) {
245+ return 0 ;
246+ }
247+ source = sources [0 ];
251248
252- look_ups [i ] = get_lookup_table (dev , cd , buffer_pipeline_id (sink ));
253- sinks_stream [i ] = & sink -> stream ;
254- }
249+ /* if there are no sinks active, then there is nothing to do */
250+ if (num_of_sinks == 0 )
251+ return 0 ;
252+
253+ /* the same number of frames is distributed to every sink, so it is
254+ * limited by both the source availability and every active sink's free
255+ * space
256+ */
257+ frames = source_get_data_frames_available (source );
258+ for (i = 0 ; i < num_of_sinks ; i ++ ) {
259+ if (sink_get_state (sinks [i ]) != dev -> state )
260+ comp_warn (dev , "the sink %d has diffrent state, culd not process" , i );
261+ continue ;
262+
263+ frames = MIN (frames , sink_get_free_frames (sinks [i ]));
255264 }
256265
257- /* if there are no sinks active, then sinks[] is also empty */
258- if (num_output_buffers == 0 )
266+ if (!frames )
259267 return 0 ;
260268
261- frames = input_buffers [0 ].size ;
262- source_bytes = frames * audio_stream_frame_bytes (mod -> input_buffers [0 ].data );
263- sink_bytes = frames * audio_stream_frame_bytes (mod -> output_buffers [0 ].data );
269+ /* the source is read-only and shared by all sinks, so it is obtained
270+ * once here and released once after all sinks have been served
271+ */
272+ source_bytes = frames * source_get_frame_bytes (source );
273+ ret = source_get_data (source , source_bytes , & source_data , & source_start ,
274+ & source_size );
275+ if (ret )
276+ return ret ;
264277
265278 /* produce output, one sink at a time */
266- for (i = 0 ; i < num_output_buffers ; i ++ ) {
267- if (sinks_stream [i ]) {
268- demux_prepare_active_look_up (cd , sinks_stream [i ],
269- input_buffers [0 ].data , look_ups [i ]);
270- cd -> demux (dev , sinks_stream [i ], input_buffers [0 ].data ,
271- frames , & cd -> active_lookup );
279+ for (i = 0 ; i < num_of_sinks ; i ++ ) {
280+ struct sof_sink * sink = sinks [i ];
281+ uint32_t pipeline_id = sink_get_pipeline_id (sink );
282+ struct mux_look_up * look_up ;
283+
284+ /* skip sinks that are not in the same state as the component */
285+ if (sink_get_state (sink ) != dev -> state )
286+ continue ;
287+
288+ /* return if configuration for this pipeline is missing */
289+ if (get_stream_index (dev , cd , pipeline_id ) < 0 ) {
290+ source_release_data (source , 0 );
291+ return - EINVAL ;
292+ }
293+
294+ look_up = get_lookup_table (dev , cd , pipeline_id );
295+ demux_prepare_active_look_up (cd , sink , source , look_up );
296+ ret = cd -> demux (dev , sink , source , source_data , source_start ,
297+ source_size , frames , & cd -> active_lookup );
298+ if (ret ) {
299+ source_release_data (source , 0 );
300+ return ret ;
272301 }
273- mod -> output_buffers [i ].size = sink_bytes ;
274302 }
275303
276- /* Update consumed */
277- mod -> input_buffers [ 0 ]. consumed = source_bytes ;
304+ /* consume the processed data from the source */
305+ source_release_data ( source , source_bytes ) ;
278306 return 0 ;
279307}
280308
@@ -305,58 +333,88 @@ static int demux_trigger(struct processing_module *mod, int cmd)
305333
306334/* process and copy stream data from source to sink buffers */
307335static int mux_process (struct processing_module * mod ,
308- struct input_stream_buffer * input_buffers , int num_input_buffers ,
309- struct output_stream_buffer * output_buffers , int num_output_buffers )
336+ struct sof_source * * sources , int num_of_sources ,
337+ struct sof_sink * * sinks , int num_of_sinks )
310338{
311339 struct comp_data * cd = module_get_private_data (mod );
312340 struct comp_dev * dev = mod -> dev ;
313- struct comp_buffer * source ;
314- const struct audio_stream * sources_stream [MUX_MAX_STREAMS ] = { NULL };
315- int frames = 0 ;
316- int sink_bytes ;
317- int i , j ;
341+ struct sof_sink * sink = sinks [0 ];
342+ struct sof_source * active_sources [MUX_MAX_STREAMS ] = { NULL };
343+ struct cir_buf_source source_bufs [MUX_MAX_STREAMS ] = { 0 };
344+ size_t source_bytes [MUX_MAX_STREAMS ] = { 0 };
345+ struct cir_buf_sink sink_buf ;
346+ size_t sink_bytes , size ;
347+ uint32_t frames ;
348+ int i , idx , ret ;
318349
319350 comp_dbg (dev , "entry" );
320351
321- /* align source streams with their respective configurations */
322- j = 0 ;
323- comp_dev_for_each_producer (dev , source ) {
324- if (comp_buffer_get_source_state (source ) == dev -> state ) {
325- if (frames )
326- frames = MIN (frames , input_buffers [j ].size );
327- else
328- frames = input_buffers [j ].size ;
329-
330- i = get_stream_index (dev , cd , buffer_pipeline_id (source ));
331- /* return if index wrong */
332- if (i < 0 ) {
333- return i ;
334- }
352+ /* if there are no sources or sinks active, then there is nothing to do */
353+ if (num_of_sinks == 0 || num_of_sources == 0 )
354+ return 0 ;
335355
336- sources_stream [i ] = & source -> stream ;
337- }
338- j ++ ;
356+ /* the same number of frames is taken from every active source and
357+ * written to the single sink, so it is limited by both the sink free
358+ * space and every active source's availability
359+ */
360+ frames = sink_get_free_frames (sink );
361+ for (i = 0 ; i < num_of_sources ; i ++ ) {
362+ struct sof_source * source = sources [i ];
363+
364+ /* skip sources that are not in the same state as the component */
365+ if (source_get_comp_state (source ) != dev -> state )
366+ continue ;
367+
368+ /* map the source to its configured stream index */
369+ idx = get_stream_index (dev , cd , source_get_pipeline_id (source ));
370+ if (idx < 0 )
371+ return idx ;
372+
373+ active_sources [idx ] = source ;
374+ frames = MIN (frames , source_get_data_frames_available (source ));
339375 }
340376
341- /* check if there are any sources active */
342- if (num_input_buffers == 0 )
377+ if (!frames )
343378 return 0 ;
344379
345- sink_bytes = frames * audio_stream_frame_bytes ( mod -> output_buffers [ 0 ]. data );
346- mux_prepare_active_look_up (cd , output_buffers [ 0 ]. data , & sources_stream [ 0 ] );
380+ /* build the active routing table for the current connections */
381+ mux_prepare_active_look_up (cd , sink , active_sources );
347382
348- /* produce output */
349- cd -> mux (dev , output_buffers [0 ].data , & sources_stream [0 ], frames , & cd -> active_lookup );
350-
351- /* Update consumed per source using each source's own frame size */
352- j = 0 ;
353- comp_dev_for_each_producer (dev , source ) {
354- if (comp_buffer_get_source_state (source ) == dev -> state )
355- mod -> input_buffers [j ].consumed =
356- frames * audio_stream_frame_bytes (mod -> input_buffers [j ].data );
357- j ++ ;
383+ /* acquire the single sink circular buffer for the whole period */
384+ sink_bytes = frames * sink_get_frame_bytes (sink );
385+ ret = sink_get_buffer (sink , sink_bytes , & sink_buf .ptr , & sink_buf .buf_start , & size );
386+ if (ret )
387+ return ret ;
388+ sink_buf .buf_end = (char * )sink_buf .buf_start + size ;
389+
390+ /* acquire every active source circular buffer */
391+ for (i = 0 ; i < MUX_MAX_STREAMS ; i ++ ) {
392+ if (!active_sources [i ])
393+ continue ;
394+
395+ source_bytes [i ] = frames * source_get_frame_bytes (active_sources [i ]);
396+ ret = source_get_data (active_sources [i ], source_bytes [i ], & source_bufs [i ].ptr ,
397+ & source_bufs [i ].buf_start , & size );
398+ if (ret ) {
399+ /* release the sources acquired so far and the sink */
400+ for (-- i ; i >= 0 ; i -- )
401+ if (active_sources [i ])
402+ source_release_data (active_sources [i ], 0 );
403+ sink_commit_buffer (sink , 0 );
404+ return ret ;
405+ }
406+ source_bufs [i ].buf_end = (const char * )source_bufs [i ].buf_start + size ;
358407 }
359- mod -> output_buffers [0 ].size = sink_bytes ;
408+
409+ /* produce output */
410+ cd -> mux (dev , sink , & sink_buf , active_sources , source_bufs , frames , & cd -> active_lookup );
411+
412+ /* commit the produced data and consume from every active source */
413+ sink_commit_buffer (sink , sink_bytes );
414+ for (i = 0 ; i < MUX_MAX_STREAMS ; i ++ )
415+ if (active_sources [i ])
416+ source_release_data (active_sources [i ], source_bytes [i ]);
417+
360418 return 0 ;
361419}
362420
@@ -443,7 +501,7 @@ static const struct module_interface mux_interface = {
443501 .set_configuration = mux_set_config ,
444502 .get_configuration = mux_get_config ,
445503 .prepare = mux_prepare ,
446- .process_audio_stream = mux_process ,
504+ .process = mux_process ,
447505 .reset = mux_reset ,
448506 .free = mux_free ,
449507};
@@ -454,7 +512,7 @@ static const struct module_interface demux_interface = {
454512 .set_configuration = mux_set_config ,
455513 .get_configuration = mux_get_config ,
456514 .prepare = mux_prepare ,
457- .process_audio_stream = demux_process ,
515+ .process = demux_process ,
458516 .trigger = demux_trigger ,
459517 .reset = mux_reset ,
460518 .free = mux_free ,
0 commit comments