@@ -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,78 @@ 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 = sources [0 ];
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 there are no sinks active, then there is nothing to do */
245+ if (num_of_sinks == 0 )
246+ return 0 ;
251247
252- look_ups [i ] = get_lookup_table (dev , cd , buffer_pipeline_id (sink ));
253- sinks_stream [i ] = & sink -> stream ;
254- }
248+ /* the same number of frames is distributed to every sink, so it is
249+ * limited by both the source availability and every active sink's free
250+ * space
251+ */
252+ frames = source_get_data_frames_available (source );
253+ for (i = 0 ; i < num_of_sinks ; i ++ ) {
254+ if (sink_get_state (sinks [i ]) != dev -> state )
255+ continue ;
256+
257+ frames = MIN (frames , sink_get_free_frames (sinks [i ]));
255258 }
256259
257- /* if there are no sinks active, then sinks[] is also empty */
258- if (num_output_buffers == 0 )
260+ if (!frames )
259261 return 0 ;
260262
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 );
263+ /* the source is read-only and shared by all sinks, so it is obtained
264+ * once here and released once after all sinks have been served
265+ */
266+ source_bytes = frames * source_get_frame_bytes (source );
267+ ret = source_get_data (source , source_bytes , & source_data , & source_start ,
268+ & source_size );
269+ if (ret )
270+ return ret ;
264271
265272 /* 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 );
273+ for (i = 0 ; i < num_of_sinks ; i ++ ) {
274+ struct sof_sink * sink = sinks [i ];
275+ uint32_t pipeline_id = sink_get_pipeline_id (sink );
276+ struct mux_look_up * look_up ;
277+
278+ /* skip sinks that are not in the same state as the component */
279+ if (sink_get_state (sink ) != dev -> state )
280+ continue ;
281+
282+ /* return if configuration for this pipeline is missing */
283+ if (get_stream_index (dev , cd , pipeline_id ) < 0 ) {
284+ source_release_data (source , 0 );
285+ return - EINVAL ;
286+ }
287+
288+ look_up = get_lookup_table (dev , cd , pipeline_id );
289+ demux_prepare_active_look_up (cd , sink , source , look_up );
290+ ret = cd -> demux (dev , sink , source , source_data , source_start ,
291+ source_size , frames , & cd -> active_lookup );
292+ if (ret ) {
293+ source_release_data (source , 0 );
294+ return ret ;
272295 }
273- mod -> output_buffers [i ].size = sink_bytes ;
274296 }
275297
276- /* Update consumed */
277- mod -> input_buffers [ 0 ]. consumed = source_bytes ;
298+ /* consume the processed data from the source */
299+ source_release_data ( source , source_bytes ) ;
278300 return 0 ;
279301}
280302
@@ -305,58 +327,88 @@ static int demux_trigger(struct processing_module *mod, int cmd)
305327
306328/* process and copy stream data from source to sink buffers */
307329static 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 )
330+ struct sof_source * * sources , int num_of_sources ,
331+ struct sof_sink * * sinks , int num_of_sinks )
310332{
311333 struct comp_data * cd = module_get_private_data (mod );
312334 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 ;
335+ struct sof_sink * sink = sinks [0 ];
336+ struct sof_source * active_sources [MUX_MAX_STREAMS ] = { NULL };
337+ struct cir_buf_source source_bufs [MUX_MAX_STREAMS ] = { 0 };
338+ size_t source_bytes [MUX_MAX_STREAMS ] = { 0 };
339+ struct cir_buf_sink sink_buf ;
340+ size_t sink_bytes , size ;
341+ uint32_t frames ;
342+ int i , idx , ret ;
318343
319344 comp_dbg (dev , "entry" );
320345
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- }
346+ /* if there are no sources or sinks active, then there is nothing to do */
347+ if (num_of_sinks == 0 || num_of_sources == 0 )
348+ return 0 ;
335349
336- sources_stream [i ] = & source -> stream ;
337- }
338- j ++ ;
350+ /* the same number of frames is taken from every active source and
351+ * written to the single sink, so it is limited by both the sink free
352+ * space and every active source's availability
353+ */
354+ frames = sink_get_free_frames (sink );
355+ for (i = 0 ; i < num_of_sources ; i ++ ) {
356+ struct sof_source * source = sources [i ];
357+
358+ /* skip sources that are not in the same state as the component */
359+ if (source_get_comp_state (source ) != dev -> state )
360+ continue ;
361+
362+ /* map the source to its configured stream index */
363+ idx = get_stream_index (dev , cd , source_get_pipeline_id (source ));
364+ if (idx < 0 )
365+ return idx ;
366+
367+ active_sources [idx ] = source ;
368+ frames = MIN (frames , source_get_data_frames_available (source ));
339369 }
340370
341- /* check if there are any sources active */
342- if (num_input_buffers == 0 )
371+ if (!frames )
343372 return 0 ;
344373
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 ] );
374+ /* build the active routing table for the current connections */
375+ mux_prepare_active_look_up (cd , sink , active_sources );
347376
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 ++ ;
377+ /* acquire the single sink circular buffer for the whole period */
378+ sink_bytes = frames * sink_get_frame_bytes (sink );
379+ ret = sink_get_buffer (sink , sink_bytes , & sink_buf .ptr , & sink_buf .buf_start , & size );
380+ if (ret )
381+ return ret ;
382+ sink_buf .buf_end = (char * )sink_buf .buf_start + size ;
383+
384+ /* acquire every active source circular buffer */
385+ for (i = 0 ; i < MUX_MAX_STREAMS ; i ++ ) {
386+ if (!active_sources [i ])
387+ continue ;
388+
389+ source_bytes [i ] = frames * source_get_frame_bytes (active_sources [i ]);
390+ ret = source_get_data (active_sources [i ], source_bytes [i ], & source_bufs [i ].ptr ,
391+ & source_bufs [i ].buf_start , & size );
392+ if (ret ) {
393+ /* release the sources acquired so far and the sink */
394+ for (-- i ; i >= 0 ; i -- )
395+ if (active_sources [i ])
396+ source_release_data (active_sources [i ], 0 );
397+ sink_commit_buffer (sink , 0 );
398+ return ret ;
399+ }
400+ source_bufs [i ].buf_end = (const char * )source_bufs [i ].buf_start + size ;
358401 }
359- mod -> output_buffers [0 ].size = sink_bytes ;
402+
403+ /* produce output */
404+ cd -> mux (dev , sink , & sink_buf , active_sources , source_bufs , frames , & cd -> active_lookup );
405+
406+ /* commit the produced data and consume from every active source */
407+ sink_commit_buffer (sink , sink_bytes );
408+ for (i = 0 ; i < MUX_MAX_STREAMS ; i ++ )
409+ if (active_sources [i ])
410+ source_release_data (active_sources [i ], source_bytes [i ]);
411+
360412 return 0 ;
361413}
362414
@@ -443,7 +495,7 @@ static const struct module_interface mux_interface = {
443495 .set_configuration = mux_set_config ,
444496 .get_configuration = mux_get_config ,
445497 .prepare = mux_prepare ,
446- .process_audio_stream = mux_process ,
498+ .process = mux_process ,
447499 .reset = mux_reset ,
448500 .free = mux_free ,
449501};
@@ -454,7 +506,7 @@ static const struct module_interface demux_interface = {
454506 .set_configuration = mux_set_config ,
455507 .get_configuration = mux_get_config ,
456508 .prepare = mux_prepare ,
457- .process_audio_stream = demux_process ,
509+ .process = demux_process ,
458510 .trigger = demux_trigger ,
459511 .reset = mux_reset ,
460512 .free = mux_free ,
0 commit comments