mirror of https://github.com/thesofproject/sof.git
audio: mixer: Improve handling of inactive input streams
The old code does not deal correctly with input streams going away without everything stopping. This commit ensures only active streams are considered as mixer input, and the other streams are ignored (considered zeroed out). Signed-off-by: Paul Olaru <paul.olaru@nxp.com>
This commit is contained in:
parent
362a0781f2
commit
908876cc5f
|
@ -82,11 +82,12 @@ static int mixer_process(struct processing_module *mod,
|
|||
struct mixer_data *md = module_get_private_data(mod);
|
||||
struct comp_dev *dev = mod->dev;
|
||||
const struct audio_stream __sparse_cache *sources_stream[PLATFORM_MAX_STREAMS];
|
||||
int32_t i = 0;
|
||||
int32_t i = 0, j = 0;
|
||||
uint32_t frames = INT32_MAX;
|
||||
/* Redundant, but helps the compiler */
|
||||
uint32_t source_bytes = 0;
|
||||
uint32_t sink_bytes;
|
||||
int active_input_buffers = 0;
|
||||
|
||||
comp_dbg(dev, "mixer_process() %d", num_input_buffers);
|
||||
|
||||
|
@ -105,10 +106,11 @@ static int mixer_process(struct processing_module *mod,
|
|||
if (avail_frames == 0)
|
||||
continue;
|
||||
|
||||
active_input_buffers++;
|
||||
frames = MIN(frames, avail_frames);
|
||||
}
|
||||
|
||||
if (!num_input_buffers || (frames == 0 && md->sources_inactive)) {
|
||||
if (!active_input_buffers) {
|
||||
/*
|
||||
* Generate silence when sources are inactive. When
|
||||
* sources change to active, additionally keep
|
||||
|
@ -119,33 +121,37 @@ static int mixer_process(struct processing_module *mod,
|
|||
if (!audio_stream_set_zero(mod->output_buffers[0].data, sink_bytes))
|
||||
mod->output_buffers[0].size = sink_bytes;
|
||||
|
||||
md->sources_inactive = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Every source has the same format, so calculate bytes based on the first one */
|
||||
source_bytes = frames * audio_stream_frame_bytes(mod->input_buffers[0].data);
|
||||
|
||||
if (md->sources_inactive) {
|
||||
md->sources_inactive = false;
|
||||
comp_dbg(dev, "mixer_copy exit sources_inactive state");
|
||||
}
|
||||
|
||||
sink_bytes = frames * audio_stream_frame_bytes(mod->output_buffers[0].data);
|
||||
|
||||
comp_dbg(dev, "mixer_process(), source_bytes = 0x%x, sink_bytes = 0x%x",
|
||||
source_bytes, sink_bytes);
|
||||
|
||||
/* mix streams */
|
||||
for (i = 0; i < num_input_buffers; i++)
|
||||
sources_stream[i] = mod->input_buffers[i].data;
|
||||
for (i = 0; i < num_input_buffers; i++) {
|
||||
uint32_t avail_frames;
|
||||
|
||||
md->mix_func(dev, mod->output_buffers[0].data, sources_stream, num_input_buffers, frames);
|
||||
avail_frames = audio_stream_avail_frames_aligned(mod->input_buffers[i].data,
|
||||
mod->output_buffers[0].data);
|
||||
|
||||
/* if one source is inactive, skip it */
|
||||
if (avail_frames == 0)
|
||||
continue;
|
||||
|
||||
sources_stream[j++] = mod->input_buffers[i].data;
|
||||
}
|
||||
|
||||
if (j)
|
||||
md->mix_func(dev, mod->output_buffers[0].data, sources_stream, j, frames);
|
||||
mod->output_buffers[0].size = sink_bytes;
|
||||
|
||||
/* update source buffer consumed bytes */
|
||||
for (i = 0; i < num_input_buffers; i++)
|
||||
for (i = 0; i < j; i++)
|
||||
mod->input_buffers[i].consumed = source_bytes;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -32,8 +32,6 @@ void sys_comp_module_mixer_interface_init(void);
|
|||
|
||||
/* mixer component private data */
|
||||
struct mixer_data {
|
||||
bool sources_inactive;
|
||||
|
||||
void (*mix_func)(struct comp_dev *dev, struct audio_stream __sparse_cache *sink,
|
||||
const struct audio_stream __sparse_cache **sources, uint32_t count,
|
||||
uint32_t frames);
|
||||
|
|
Loading…
Reference in New Issue