@@ -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,9 +169,10 @@ 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 ;
175+ }
175176
176177 cd -> active_lookup .copy_elem [active_elem ] = cd -> lookup [0 ].copy_elem [elem ];
177178 active_elem ++ ;
@@ -203,18 +204,19 @@ static struct mux_look_up *get_lookup_table(struct comp_dev *dev, struct comp_da
203204}
204205
205206static void demux_prepare_active_look_up (struct comp_data * cd ,
206- struct audio_stream * sink ,
207- const struct audio_stream * source ,
207+ struct sof_sink * sink ,
208+ struct sof_source * source ,
208209 struct mux_look_up * look_up )
209210{
210211 int elem ;
211212 int active_elem = 0 ;
212213
213214 /* init pointers */
214215 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 ))
216+ if (look_up -> copy_elem [elem ].in_ch >= source_get_channels (source ) ||
217+ look_up -> copy_elem [elem ].out_ch >= sink_get_channels (sink )) {
217218 continue ;
219+ }
218220
219221 cd -> active_lookup .copy_elem [active_elem ] = look_up -> copy_elem [elem ];
220222 active_elem ++ ;
@@ -225,56 +227,89 @@ static void demux_prepare_active_look_up(struct comp_data *cd,
225227
226228/* process and copy stream data from source to sink buffers */
227229static 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 )
230+ struct sof_source * * sources , int num_of_sources ,
231+ struct sof_sink * * sinks , int num_of_sinks )
230232{
231233 struct comp_data * cd = module_get_private_data (mod );
232234 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 ;
235+ struct sof_source * source ;
236+ const void * source_data ;
237+ const void * source_start ;
238+ size_t source_size ;
239+ size_t source_bytes ;
240+ uint32_t frames ;
241+ int ret ;
239242 int i ;
240243
241244 comp_dbg (dev , "entry" );
242245
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- }
246+ if (sources == NULL && sources [0 ] == NULL ) {
247+ return 0 ;
248+ }
249+ source = sources [0 ];
251250
252- look_ups [i ] = get_lookup_table (dev , cd , buffer_pipeline_id (sink ));
253- sinks_stream [i ] = & sink -> stream ;
251+ /* if there are no sinks active, then there is nothing to do */
252+ if (num_of_sinks == 0 ) {
253+ return 0 ;
254+ }
255+
256+ /* the same number of frames is distributed to every sink, so it is
257+ * limited by both the source availability and every active sink's free
258+ * space
259+ */
260+ frames = source_get_data_frames_available (source );
261+ for (i = 0 ; i < num_of_sinks ; i ++ ) {
262+ if (sink_get_state (sinks [i ]) != dev -> state ) {
263+ comp_warn (dev , "the sink %d has diffrent state, culd not process" , i );
264+ continue ;
254265 }
266+
267+ frames = MIN (frames , sink_get_free_frames (sinks [i ]));
255268 }
256269
257- /* if there are no sinks active, then sinks[] is also empty */
258- if (num_output_buffers == 0 )
270+ if (!frames ) {
259271 return 0 ;
272+ }
260273
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 );
274+ /* the source is read-only and shared by all sinks, so it is obtained
275+ * once here and released once after all sinks have been served
276+ */
277+ source_bytes = frames * source_get_frame_bytes (source );
278+ ret = source_get_data (source , source_bytes , & source_data , & source_start ,
279+ & source_size );
280+ if (ret ) {
281+ return ret ;
282+ }
264283
265284 /* 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 );
285+ for (i = 0 ; i < num_of_sinks ; i ++ ) {
286+ struct sof_sink * sink = sinks [i ];
287+ uint32_t pipeline_id = sink_get_pipeline_id (sink );
288+ struct mux_look_up * look_up ;
289+
290+ /* skip sinks that are not in the same state as the component */
291+ if (sink_get_state (sink ) != dev -> state ) {
292+ continue ;
293+ }
294+
295+ /* return if configuration for this pipeline is missing */
296+ if (get_stream_index (dev , cd , pipeline_id ) < 0 ) {
297+ source_release_data (source , 0 );
298+ return - EINVAL ;
299+ }
300+
301+ look_up = get_lookup_table (dev , cd , pipeline_id );
302+ demux_prepare_active_look_up (cd , sink , source , look_up );
303+ ret = cd -> demux (dev , sink , source , source_data , source_start ,
304+ source_size , frames , & cd -> active_lookup );
305+ if (ret ) {
306+ source_release_data (source , 0 );
307+ return ret ;
272308 }
273- mod -> output_buffers [i ].size = sink_bytes ;
274309 }
275310
276- /* Update consumed */
277- mod -> input_buffers [ 0 ]. consumed = source_bytes ;
311+ /* consume the processed data from the source */
312+ source_release_data ( source , source_bytes ) ;
278313 return 0 ;
279314}
280315
@@ -305,58 +340,96 @@ static int demux_trigger(struct processing_module *mod, int cmd)
305340
306341/* process and copy stream data from source to sink buffers */
307342static 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 )
343+ struct sof_source * * sources , int num_of_sources ,
344+ struct sof_sink * * sinks , int num_of_sinks )
310345{
311346 struct comp_data * cd = module_get_private_data (mod );
312347 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 ;
348+ struct sof_sink * sink = sinks [0 ];
349+ struct sof_source * active_sources [MUX_MAX_STREAMS ] = { NULL };
350+ struct cir_buf_source source_bufs [MUX_MAX_STREAMS ] = { 0 };
351+ size_t source_bytes [MUX_MAX_STREAMS ] = { 0 };
352+ struct cir_buf_sink sink_buf ;
353+ size_t sink_bytes , size ;
354+ uint32_t frames ;
355+ int i , idx , ret ;
318356
319357 comp_dbg (dev , "entry" );
320358
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- }
359+ /* if there are no sources or sinks active, then there is nothing to do */
360+ if (num_of_sinks == 0 || num_of_sources == 0 ) {
361+ return 0 ;
362+ }
363+
364+ /* the same number of frames is taken from every active source and
365+ * written to the single sink, so it is limited by both the sink free
366+ * space and every active source's availability
367+ */
368+ frames = sink_get_free_frames (sink );
369+ for (i = 0 ; i < num_of_sources ; i ++ ) {
370+ struct sof_source * source = sources [i ];
335371
336- sources_stream [i ] = & source -> stream ;
372+ /* skip sources that are not in the same state as the component */
373+ if (source_get_comp_state (source ) != dev -> state ) {
374+ continue ;
337375 }
338- j ++ ;
376+
377+ /* map the source to its configured stream index */
378+ idx = get_stream_index (dev , cd , source_get_pipeline_id (source ));
379+ if (idx < 0 ) {
380+ return idx ;
381+ }
382+
383+ active_sources [idx ] = source ;
384+ frames = MIN (frames , source_get_data_frames_available (source ));
339385 }
340386
341- /* check if there are any sources active */
342- if (num_input_buffers == 0 )
387+ if (!frames ) {
343388 return 0 ;
389+ }
344390
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 ] );
391+ /* build the active routing table for the current connections */
392+ mux_prepare_active_look_up (cd , sink , active_sources );
347393
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 ++ ;
394+ /* acquire the single sink circular buffer for the whole period */
395+ sink_bytes = frames * sink_get_frame_bytes (sink );
396+ ret = sink_get_buffer (sink , sink_bytes , & sink_buf .ptr , & sink_buf .buf_start , & size );
397+ if (ret ) {
398+ return ret ;
358399 }
359- mod -> output_buffers [0 ].size = sink_bytes ;
400+ sink_buf .buf_end = (char * )sink_buf .buf_start + size ;
401+
402+ /* acquire every active source circular buffer */
403+ for (i = 0 ; i < MUX_MAX_STREAMS ; i ++ ) {
404+ if (!active_sources [i ]) {
405+ continue ;
406+ }
407+
408+ source_bytes [i ] = frames * source_get_frame_bytes (active_sources [i ]);
409+ ret = source_get_data (active_sources [i ], source_bytes [i ], & source_bufs [i ].ptr ,
410+ & source_bufs [i ].buf_start , & size );
411+ if (ret ) {
412+ /* release the sources acquired so far and the sink */
413+ for (-- i ; i >= 0 ; i -- )
414+ if (active_sources [i ]) {
415+ source_release_data (active_sources [i ], 0 );
416+ }
417+ sink_commit_buffer (sink , 0 );
418+ return ret ;
419+ }
420+ source_bufs [i ].buf_end = (const char * )source_bufs [i ].buf_start + size ;
421+ }
422+
423+ /* produce output */
424+ cd -> mux (dev , sink , & sink_buf , active_sources , source_bufs , frames , & cd -> active_lookup );
425+
426+ /* commit the produced data and consume from every active source */
427+ sink_commit_buffer (sink , sink_bytes );
428+ for (i = 0 ; i < MUX_MAX_STREAMS ; i ++ )
429+ if (active_sources [i ]) {
430+ source_release_data (active_sources [i ], source_bytes [i ]);
431+ }
432+
360433 return 0 ;
361434}
362435
@@ -443,7 +516,7 @@ static const struct module_interface mux_interface = {
443516 .set_configuration = mux_set_config ,
444517 .get_configuration = mux_get_config ,
445518 .prepare = mux_prepare ,
446- .process_audio_stream = mux_process ,
519+ .process = mux_process ,
447520 .reset = mux_reset ,
448521 .free = mux_free ,
449522};
@@ -454,7 +527,7 @@ static const struct module_interface demux_interface = {
454527 .set_configuration = mux_set_config ,
455528 .get_configuration = mux_get_config ,
456529 .prepare = mux_prepare ,
457- .process_audio_stream = demux_process ,
530+ .process = demux_process ,
458531 .trigger = demux_trigger ,
459532 .reset = mux_reset ,
460533 .free = mux_free ,
0 commit comments