Skip to content

Commit

Permalink
Audio: Module adapter: Add a new simple copy function
Browse files Browse the repository at this point in the history
This patch adds a simplified version of simple copy for module
adapter clients with one source and one sink. The overhead
of discovering multiple source and sink buffers is avoided.

The module_adapter_bind() and module_adapter_unbind() functions
are changed to detect multiple sources or sinks condition
to control the used simple copy function.

Signed-off-by: Seppo Ingalsuo <[email protected]>
  • Loading branch information
singalsu committed Jun 14, 2023
1 parent d0f59a7 commit 571e207
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 0 deletions.
98 changes: 98 additions & 0 deletions src/audio/module_adapter/module_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,20 @@ int module_adapter_prepare(struct comp_dev *dev)
return -EINVAL;
}

/* Check if simple copy client has only one source and one sink buffer to use a
* simplified copy function. The multi_source_or_sink is set later to true
* if module_adapter_bind() indicates multiple sources.
*/
if (mod->simple_copy && mod->num_input_buffers == 1 && mod->num_output_buffers == 1) {
mod->source = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list);
mod->sink = sink;
mod->multi_source_or_sink = false;
} else {
mod->source = NULL;
mod->sink = NULL;
mod->multi_source_or_sink = true;
}

/* allocate memory for input buffers */
if (mod->num_input_buffers) {
mod->input_buffers =
Expand Down Expand Up @@ -825,6 +839,56 @@ static int module_adapter_simple_copy(struct comp_dev *dev)
return ret;
}

static int module_adapter_simple_copy_1to1(struct processing_module *mod)
{
struct comp_buffer __sparse_cache *source_c;
struct comp_buffer __sparse_cache *sink_c;
struct comp_dev *dev = mod->dev;
uint32_t frames;
int ret;

source_c = buffer_acquire(mod->source);
sink_c = buffer_acquire(mod->sink);
frames = audio_stream_avail_frames_aligned(&source_c->stream, &sink_c->stream);
mod->input_buffers[0].size = frames;
mod->input_buffers[0].consumed = 0;
mod->input_buffers[0].data = &source_c->stream;
mod->output_buffers[0].size = 0;
mod->output_buffers[0].data = &sink_c->stream;
if (!mod->skip_src_buffer_invalidate) /* TODO: add mod->is_multi_core && */
buffer_stream_invalidate(source_c,
frames * audio_stream_frame_bytes(&source_c->stream));

ret = module_process(mod, mod->input_buffers, 1, mod->output_buffers, 1);
if (ret) {
if (ret != -ENOSPC && ret != -ENODATA) {
comp_err(dev, "module_adapter_simple_copy_1to1(), process failed: %d", ret);
goto out;
}

ret = 0;
}

/* consume from input buffer */
mod->total_data_consumed += mod->input_buffers[0].consumed;
if (mod->input_buffers[0].consumed)
audio_stream_consume(&source_c->stream, mod->input_buffers[0].consumed);

/* produce data into all active output buffers */
mod->total_data_produced += mod->output_buffers[0].size;
if (!mod->skip_sink_buffer_writeback) /* TODO: add mod->is_multi_core && */
buffer_stream_writeback(sink_c, mod->output_buffers[0].size);

if (mod->output_buffers[0].size)
audio_stream_produce(&sink_c->stream, mod->output_buffers[0].size);

out:
/* release all buffers */
buffer_release(sink_c);
buffer_release(source_c);
return ret;
}

int module_adapter_copy(struct comp_dev *dev)
{
struct processing_module *mod = comp_get_drvdata(dev);
Expand All @@ -838,6 +902,9 @@ int module_adapter_copy(struct comp_dev *dev)

comp_dbg(dev, "module_adapter_copy(): start");

if (!mod->multi_source_or_sink)
return module_adapter_simple_copy_1to1(mod);

if (mod->simple_copy)
return module_adapter_simple_copy(dev);

Expand Down Expand Up @@ -1275,6 +1342,25 @@ int module_adapter_get_attribute(struct comp_dev *dev, uint32_t type, void *valu
return 0;
}

static bool module_adapter_multi_sink_source_check(struct comp_dev *dev)
{
struct list_item *blist;
int num_sources = 0;
int num_sinks = 0;

list_for_item(blist, &dev->bsource_list)
num_sources++;

list_for_item(blist, &dev->bsink_list)
num_sinks++;

comp_dbg(dev, "num_sources=%d num_sinks=%d", num_sources, num_sinks);
if (num_sources > 1 || num_sinks > 1)
return true;
else
return false;
}

int module_adapter_bind(struct comp_dev *dev, void *data)
{
struct module_source_info __sparse_cache *mod_source_info;
Expand Down Expand Up @@ -1319,6 +1405,12 @@ int module_adapter_bind(struct comp_dev *dev, void *data)
/* set the source dev pointer */
mod_source_info->sources[source_index] = source_dev;

/* Disable 1 source 1 sink simple copy mode if multiple source buffers */
if (module_adapter_multi_sink_source_check(dev)) {
comp_dbg(dev, "module_adapter_bind(), multi_sink_or_source = true");
mod->multi_source_or_sink = true;
}

module_source_info_release(mod_source_info);

return 0;
Expand Down Expand Up @@ -1353,6 +1445,12 @@ int module_adapter_unbind(struct comp_dev *dev, void *data)
if (source_index >= 0)
mod_source_info->sources[source_index] = NULL;

/* Re-enable 1 source 1 sink simple copy mode if single source buffer */
if (mod->simple_copy && !module_adapter_multi_sink_source_check(dev)) {
comp_dbg(dev, "module_adapter_bind(), multi_sink_or_source = false");
mod->multi_source_or_sink = false;
}

module_source_info_release(mod_source_info);

return 0;
Expand Down
9 changes: 9 additions & 0 deletions src/include/sof/audio/module_adapter/module/generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@ struct processing_module {
struct output_stream_buffer *output_buffers;
uint32_t num_input_buffers; /**< number of input buffers */
uint32_t num_output_buffers; /**< number of output buffers */

struct comp_buffer *source;
struct comp_buffer *sink;

/*
* flag set by a module that produces period_bytes every copy. It can be used by modules
* that support 1:1, 1:N, N:1 sources:sinks configuration.
Expand All @@ -208,6 +212,11 @@ struct processing_module {
*/
bool skip_src_buffer_invalidate;

/* False for module with one sink and one source to simplify copy operations. True if
* multiple source or sink buffers.
*/
bool multi_source_or_sink;

/* table containing the list of connected sources */
struct module_source_info *source_info;

Expand Down

0 comments on commit 571e207

Please sign in to comment.