From 8355b950efff50ab9818c97474f6ab018dacfec5 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 31 May 2023 09:04:49 -0700 Subject: [PATCH 01/12] module_adapter: Extend the module interface Add the bind/unbind ops that can be optionally implemented by modules to perform module-specific actions when other modules are bound/unbound from them. These are particularly useful for modules such as the mixers, smart_amp, copier that can have multiple input/output pins. Signed-off-by: Ranjani Sridharan --- src/audio/module_adapter/module/generic.c | 18 ++++++++++++++++++ src/audio/module_adapter/module_adapter.c | 10 ++++++++++ .../sof/audio/module_adapter/module/generic.h | 2 ++ .../module_adapter/module/module_interface.h | 8 ++++++++ 4 files changed, 38 insertions(+) diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index ef29ec7c4c85..f3676521a3a5 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -486,3 +486,21 @@ int module_set_configuration(struct processing_module *mod, return ret; } + +int module_bind(struct processing_module *mod, void *data) +{ + struct module_data *md = &mod->priv; + + if (md->ops->bind) + return md->ops->bind(mod, data); + return 0; +} + +int module_unbind(struct processing_module *mod, void *data) +{ + struct module_data *md = &mod->priv; + + if (md->ops->unbind) + return md->ops->unbind(mod, data); + return 0; +} diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index 4b2e475e4c5e..750c146e00ab 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -1552,6 +1552,11 @@ int module_adapter_bind(struct comp_dev *dev, void *data) struct comp_dev *source_dev; int source_index; int src_id; + int ret; + + ret = module_bind(mod, data); + if (ret < 0) + return ret; bu = (struct ipc4_module_bind_unbind *)data; src_id = IPC4_COMP_ID(bu->primary.r.module_id, bu->primary.r.instance_id); @@ -1603,6 +1608,11 @@ int module_adapter_unbind(struct comp_dev *dev, void *data) struct comp_dev *source_dev; int source_index; int src_id; + int ret; + + ret = module_unbind(mod, data); + if (ret < 0) + return ret; bu = (struct ipc4_module_bind_unbind *)data; src_id = IPC4_COMP_ID(bu->primary.r.module_id, bu->primary.r.instance_id); diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index e6d89738e1e6..7fe39ca846e4 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -249,6 +249,8 @@ int module_set_configuration(struct processing_module *mod, enum module_cfg_fragment_position pos, size_t data_offset_size, const uint8_t *fragment, size_t fragment_size, uint8_t *response, size_t response_size); +int module_bind(struct processing_module *mod, void *data); +int module_unbind(struct processing_module *mod, void *data); struct comp_dev *module_adapter_new(const struct comp_driver *drv, const struct comp_ipc_config *config, diff --git a/src/include/sof/audio/module_adapter/module/module_interface.h b/src/include/sof/audio/module_adapter/module/module_interface.h index dec02f3cfa5a..f3d918d61357 100644 --- a/src/include/sof/audio/module_adapter/module/module_interface.h +++ b/src/include/sof/audio/module_adapter/module/module_interface.h @@ -189,6 +189,14 @@ struct module_interface { * free in .free(). This should free all memory allocated during module initialization. */ int (*free)(struct processing_module *mod); + /** + * Module specific bind procedure, called when modules are bound with each other + */ + int (*bind)(struct processing_module *mod, void *data); + /** + * Module specific unbind procedure, called when modules are disconnected from one another + */ + int (*unbind)(struct processing_module *mod, void *data); }; /* Convert first_block/last_block indicator to fragment position */ From 7e30fdce3978e218eb5dda9b507744144c31d562 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 31 May 2023 09:06:57 -0700 Subject: [PATCH 02/12] module_adapter: Extend the module interface for endpoint devices Introduce a new struct module_endpoint_ops which contains all the ops that are relevant for endpoint devices (host copier and DAI copier) and add a new field for setting the endpoint_ops. These will be needed when the copier component is converted to use the module adapter interface. Signed-off-by: Ranjani Sridharan Signed-off-by: Baofeng Tian --- .../module_adapter/module/module_interface.h | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/include/sof/audio/module_adapter/module/module_interface.h b/src/include/sof/audio/module_adapter/module/module_interface.h index f3d918d61357..0d020238a2ae 100644 --- a/src/include/sof/audio/module_adapter/module/module_interface.h +++ b/src/include/sof/audio/module_adapter/module/module_interface.h @@ -67,6 +67,79 @@ struct output_stream_buffer { uint32_t size; /* size of data in the buffer */ }; +/** + * \struct module_endpoint_ops + * \brief Ops relevant only for the endpoint devices such as the host copier or DAI copier. + * Other modules should not implement these. + */ +struct module_endpoint_ops { + /** + * Returns total data processed in number bytes. + * @param dev Component device + * @param stream_no Index of input/output stream + * @param input Selects between input (true) or output (false) stream direction + * @return total data processed if succeeded, 0 otherwise. + */ + uint64_t (*get_total_data_processed)(struct comp_dev *dev, uint32_t stream_no, bool input); + /** + * Retrieves component rendering position. + * @param dev Component device. + * @param posn Receives reported position. + */ + int (*position)(struct comp_dev *dev, struct sof_ipc_stream_posn *posn); + /** + * Configures timestamping in attached DAI. + * @param dev Component device. + * + * Mandatory for components that allocate DAI. + */ + int (*dai_ts_config)(struct comp_dev *dev); + + /** + * Starts timestamping. + * @param dev Component device. + * + * Mandatory for components that allocate DAI. + */ + int (*dai_ts_start)(struct comp_dev *dev); + + /** + * Stops timestamping. + * @param dev Component device. + * + * Mandatory for components that allocate DAI. + */ + int (*dai_ts_stop)(struct comp_dev *dev); + + /** + * Gets timestamp. + * @param dev Component device. + * @param tsd Receives timestamp data. + * + * Mandatory for components that allocate DAI. + */ + int (*dai_ts_get)(struct comp_dev *dev, struct timestamp_data *tsd); + + /** + * Fetches hardware stream parameters. + * @param dev Component device. + * @param params Receives copy of stream parameters retrieved from + * DAI hw settings. + * @param dir Stream direction (see enum sof_ipc_stream_direction). + * + * Mandatory for components that allocate DAI. + */ + int (*dai_get_hw_params)(struct comp_dev *dev, + struct sof_ipc_stream_params *params, int dir); + + /** + * Triggers device state. + * @param dev Component device. + * @param cmd Trigger command. + */ + int (*trigger)(struct comp_dev *dev, int cmd); +}; + struct processing_module; /** * \struct module_interface @@ -197,6 +270,8 @@ struct module_interface { * Module specific unbind procedure, called when modules are disconnected from one another */ int (*unbind)(struct processing_module *mod, void *data); + + const struct module_endpoint_ops *endpoint_ops; }; /* Convert first_block/last_block indicator to fragment position */ From 7806392213641d1d09b72da4103e74863009d022 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Mon, 3 Jul 2023 21:57:35 -0700 Subject: [PATCH 03/12] audio: module_adapter: Prepare to convert copier to use module interface Add the dai endpoint ops to the module adapter in preparation for converting the copier module to use the module interface. Also, modify the module_adapter ops to handle the HOST/DAI components are a special case. In the case of module_adapter_prepare(), there's no need to compute the period_bytes for the HOST/DAI because these are computed by the copier module prepare op. In the case of copy, HOST/DAI components are handled separately as well as these components deal with the DMA buffers. Signed-off-by: Ranjani Sridharan --- src/audio/module_adapter/module_adapter.c | 160 ++++++++++++++++-- .../sof/audio/module_adapter/module/generic.h | 13 ++ 2 files changed, 162 insertions(+), 11 deletions(-) diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index 750c146e00ab..ea4d90e6321d 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -256,17 +256,6 @@ int module_adapter_prepare(struct comp_dev *dev) return ret; } - /* Get period_bytes first on prepare(). At this point it is guaranteed that the stream - * parameter from sink buffer is settled, and still prior to all references to period_bytes. - */ - sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sink); - - mod->period_bytes = audio_stream_period_bytes(&sink_c->stream, dev->frames); - comp_dbg(dev, "module_adapter_prepare(): got period_bytes = %u", mod->period_bytes); - - buffer_release(sink_c); - /* * check if the component is already active. This could happen in the case of mixer when * one of the sources is already active @@ -284,8 +273,23 @@ int module_adapter_prepare(struct comp_dev *dev) return PPL_STATUS_PATH_STOP; } + /* nothing more to do for HOST/DAI type modules */ + if (dev->ipc_config.type == SOF_COMP_HOST || dev->ipc_config.type == SOF_COMP_DAI) + return 0; + mod->deep_buff_bytes = 0; + /* Get period_bytes first on prepare(). At this point it is guaranteed that the stream + * parameter from sink buffer is settled, and still prior to all references to period_bytes. + */ + sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); + sink_c = buffer_acquire(sink); + + mod->period_bytes = audio_stream_period_bytes(&sink_c->stream, dev->frames); + comp_dbg(dev, "module_adapter_prepare(): got period_bytes = %u", mod->period_bytes); + + buffer_release(sink_c); + /* * compute number of input buffers and make the source_info shared if the module is on a * different core than any of it's sources @@ -867,6 +871,10 @@ static int module_adapter_audio_stream_type_copy(struct comp_dev *dev) uint32_t num_input_buffers, num_output_buffers; int ret, i = 0; + /* handle special case of HOST/DAI type components */ + if (dev->ipc_config.type == SOF_COMP_HOST || dev->ipc_config.type == SOF_COMP_DAI) + return module_process_legacy(mod, NULL, 0, NULL, 0); + if (mod->stream_copy_single_to_single) return module_adapter_audio_stream_copy_1to1(dev); @@ -1330,6 +1338,13 @@ int module_adapter_trigger(struct comp_dev *dev, int cmd) comp_dbg(dev, "module_adapter_trigger(): cmd %d", cmd); + /* handle host/DAI gateway modules separately */ + if (dev->ipc_config.type == SOF_COMP_HOST || dev->ipc_config.type == SOF_COMP_DAI) { + struct module_data *md = &mod->priv; + + return md->ops->endpoint_ops->trigger(dev, cmd); + } + /* * If the module doesn't support pause, keep it active along with the rest of the * downstream modules @@ -1438,6 +1453,125 @@ void module_adapter_free(struct comp_dev *dev) rfree(dev); } +/* + * \brief Get DAI hw params + * \param[in] dev - component device pointer + * \param[in] params - pointer to stream params + * \param[in] dir - stream direction + * + * \return integer representing either: + * 0 - success + * value < 0 - failure. + */ +int module_adapter_get_hw_params(struct comp_dev *dev, struct sof_ipc_stream_params *params, + int dir) +{ + struct processing_module *mod = comp_get_drvdata(dev); + struct module_data *md = &mod->priv; + + if (md->ops->endpoint_ops && md->ops->endpoint_ops->dai_get_hw_params) + return md->ops->endpoint_ops->dai_get_hw_params(dev, params, dir); + + return -EOPNOTSUPP; +} + +/* + * \brief Get stream position + * \param[in] dev - component device pointer + * \param[in] posn - pointer to stream position + * + * \return integer representing either: + * 0 - success + * value < 0 - failure. + */ +int module_adapter_position(struct comp_dev *dev, struct sof_ipc_stream_posn *posn) +{ + struct processing_module *mod = comp_get_drvdata(dev); + struct module_data *md = &mod->priv; + + if (md->ops->endpoint_ops && md->ops->endpoint_ops->position) + return md->ops->endpoint_ops->position(dev, posn); + + return -EOPNOTSUPP; +} + +/* + * \brief DAI timestamp configure + * \param[in] dev - component device pointer + * + * \return integer representing either: + * 0 - success + * value < 0 - failure. + */ +int module_adapter_ts_config_op(struct comp_dev *dev) +{ + struct processing_module *mod = comp_get_drvdata(dev); + struct module_data *md = &mod->priv; + + if (md->ops->endpoint_ops && md->ops->endpoint_ops->dai_ts_config) + return md->ops->endpoint_ops->dai_ts_config(dev); + + return -EOPNOTSUPP; +} + +/* + * \brief DAI timestamp start + * \param[in] dev - component device pointer + * + * \return integer representing either: + * 0 - success + * value < 0 - failure. + */ +int module_adapter_ts_start_op(struct comp_dev *dev) +{ + struct processing_module *mod = comp_get_drvdata(dev); + struct module_data *md = &mod->priv; + + if (md->ops->endpoint_ops && md->ops->endpoint_ops->dai_ts_start) + return md->ops->endpoint_ops->dai_ts_start(dev); + + return -EOPNOTSUPP; +} + +/* + * \brief DAI timestamp stop + * \param[in] dev - component device pointer + * + * \return integer representing either: + * 0 - success + * value < 0 - failure. + */ +int module_adapter_ts_stop_op(struct comp_dev *dev) +{ + struct processing_module *mod = comp_get_drvdata(dev); + struct module_data *md = &mod->priv; + + if (md->ops->endpoint_ops && md->ops->endpoint_ops->dai_ts_stop) + return md->ops->endpoint_ops->dai_ts_stop(dev); + + return -EOPNOTSUPP; +} + +/* + * \brief Get DAI timestamp + * \param[in] dev - component device pointer + * \param[in] tsd - Timestamp data pointer + * + * \return integer representing either: + * 0 - success + * value < 0 - failure. + */ +int module_adapter_ts_get_op(struct comp_dev *dev, struct timestamp_data *tsd) +{ + struct processing_module *mod = comp_get_drvdata(dev); + struct module_data *md = &mod->priv; + + if (md->ops->endpoint_ops && md->ops->endpoint_ops->dai_ts_get) + return md->ops->endpoint_ops->dai_ts_get(dev, tsd); + + return -EOPNOTSUPP; +} + #if CONFIG_IPC_MAJOR_4 int module_set_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, bool last_block, uint32_t data_offset_size, const char *data) @@ -1645,6 +1779,10 @@ uint64_t module_adapter_get_total_data_processed(struct comp_dev *dev, uint32_t stream_no, bool input) { struct processing_module *mod = comp_get_drvdata(dev); + struct module_data *md = &mod->priv; + + if (md->ops->endpoint_ops && md->ops->endpoint_ops->get_total_data_processed) + return md->ops->endpoint_ops->get_total_data_processed(dev, stream_no, input); if (input) return mod->total_data_produced; diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index 7fe39ca846e4..4e0a5ae6988d 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -60,6 +60,12 @@ static const struct comp_driver comp_##adapter##_module = { \ .bind = module_adapter_bind,\ .unbind = module_adapter_unbind,\ .get_total_data_processed = module_adapter_get_total_data_processed,\ + .dai_get_hw_params = module_adapter_get_hw_params,\ + .position = module_adapter_position,\ + .dai_ts_config = module_adapter_ts_config_op,\ + .dai_ts_start = module_adapter_ts_start_op,\ + .dai_ts_stop = module_adapter_ts_stop_op,\ + .dai_ts_get = module_adapter_ts_get_op,\ }, \ }; \ \ @@ -271,6 +277,13 @@ int module_adapter_bind(struct comp_dev *dev, void *data); int module_adapter_unbind(struct comp_dev *dev, void *data); uint64_t module_adapter_get_total_data_processed(struct comp_dev *dev, uint32_t stream_no, bool input); +int module_adapter_get_hw_params(struct comp_dev *dev, struct sof_ipc_stream_params *params, + int dir); +int module_adapter_position(struct comp_dev *dev, struct sof_ipc_stream_posn *posn); +int module_adapter_ts_config_op(struct comp_dev *dev); +int module_adapter_ts_start_op(struct comp_dev *dev); +int module_adapter_ts_stop_op(struct comp_dev *dev); +int module_adapter_ts_get_op(struct comp_dev *dev, struct timestamp_data *tsd); static inline void module_update_buffer_position(struct input_stream_buffer *input_buffers, struct output_stream_buffer *output_buffers, From a581267274db353faf078a5e3f4708c557c5dc32 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Sun, 9 Jul 2023 10:11:15 -0700 Subject: [PATCH 04/12] audio: volume: Remove state check The state check is redundant as the state will always be >= MODULE_INITIALIZED if the module exists. Signed-off-by: Ranjani Sridharan --- src/audio/module_adapter/module/volume/volume.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/audio/module_adapter/module/volume/volume.c b/src/audio/module_adapter/module/volume/volume.c index 509ab7de0c26..8a952d3aee7d 100644 --- a/src/audio/module_adapter/module/volume/volume.c +++ b/src/audio/module_adapter/module/volume/volume.c @@ -1056,7 +1056,6 @@ static int volume_set_config(struct processing_module *mod, uint32_t config_id, const uint8_t *fragment, size_t fragment_size, uint8_t *response, size_t response_size) { - struct module_data *md = &mod->priv; struct comp_dev *dev = mod->dev; int ret; @@ -1070,8 +1069,7 @@ static int volume_set_config(struct processing_module *mod, uint32_t config_id, return ret; /* return if more fragments are expected or if the module is not prepared */ - if ((pos != MODULE_CFG_FRAGMENT_LAST && pos != MODULE_CFG_FRAGMENT_SINGLE) || - md->state < MODULE_INITIALIZED) + if (pos != MODULE_CFG_FRAGMENT_LAST && pos != MODULE_CFG_FRAGMENT_SINGLE) return 0; switch (config_id) { From 29acc88725016394607618036e6abdf875b709f1 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Sun, 9 Jul 2023 10:18:00 -0700 Subject: [PATCH 05/12] audio: module_adapter: Isolate the module state checks to IPC3 For IPC4, the component device state machine is handled by the comp_set_state() calls in the module adapter ops already. So, the module state checks are redundant. But, keep the state checks for IPC3 so as to not break the existing codec implementations for IPC3. Signed-off-by: Ranjani Sridharan --- src/audio/module_adapter/module/generic.c | 28 ++++++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index f3676521a3a5..760652982245 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -83,11 +83,12 @@ int module_init(struct processing_module *mod, struct module_interface *interfac comp_dbg(dev, "module_init() start"); +#if CONFIG_IPC_MAJOR_3 if (mod->priv.state == MODULE_INITIALIZED) return 0; if (mod->priv.state > MODULE_INITIALIZED) return -EPERM; - +#endif if (!interface) { comp_err(dev, "module_init(): could not find module interface for comp id %d", dev_comp_id(dev)); @@ -118,7 +119,9 @@ int module_init(struct processing_module *mod, struct module_interface *interfac } comp_dbg(dev, "module_init() done"); +#if CONFIG_IPC_MAJOR_3 md->state = MODULE_INITIALIZED; +#endif return ret; } @@ -202,11 +205,12 @@ int module_prepare(struct processing_module *mod, comp_dbg(dev, "module_prepare() start"); +#if CONFIG_IPC_MAJOR_3 if (mod->priv.state == MODULE_IDLE) return 0; if (mod->priv.state < MODULE_INITIALIZED) return -EPERM; - +#endif ret = md->ops->prepare(mod, sources, num_of_sources, sinks, num_of_sinks); if (ret) { comp_err(dev, "module_prepare() error %d: module specific prepare failed, comp_id %d", @@ -224,7 +228,9 @@ int module_prepare(struct processing_module *mod, md->cfg.avail = false; md->cfg.data = NULL; +#if CONFIG_IPC_MAJOR_3 md->state = MODULE_IDLE; +#endif comp_dbg(dev, "module_prepare() done"); return ret; @@ -242,6 +248,7 @@ int module_process_legacy(struct processing_module *mod, comp_dbg(dev, "module_process_legacy() start"); +#if CONFIG_IPC_MAJOR_3 if (md->state != MODULE_IDLE) { comp_err(dev, "module_process(): wrong state of comp_id %x, state %d", dev_comp_id(dev), md->state); @@ -250,7 +257,7 @@ int module_process_legacy(struct processing_module *mod, /* set state to processing */ md->state = MODULE_PROCESSING; - +#endif if (md->ops->process_audio_stream) ret = md->ops->process_audio_stream(mod, input_buffers, num_input_buffers, output_buffers, num_output_buffers); @@ -268,8 +275,10 @@ int module_process_legacy(struct processing_module *mod, comp_dbg(dev, "module_process_legacy() done"); +#if CONFIG_IPC_MAJOR_3 /* reset state to idle */ md->state = MODULE_IDLE; +#endif return 0; } @@ -285,6 +294,7 @@ int module_process_sink_src(struct processing_module *mod, comp_dbg(dev, "module_process sink src() start"); +#if CONFIG_IPC_MAJOR_3 if (md->state != MODULE_IDLE) { comp_err(dev, "module_process(): wrong state of comp_id %x, state %d", dev_comp_id(dev), md->state); @@ -293,7 +303,7 @@ int module_process_sink_src(struct processing_module *mod, /* set state to processing */ md->state = MODULE_PROCESSING; - +#endif assert(md->ops->process); ret = md->ops->process(mod, sources, num_of_sources, sinks, num_of_sinks); @@ -305,8 +315,10 @@ int module_process_sink_src(struct processing_module *mod, comp_dbg(dev, "module_process sink src() done"); +#if CONFIG_IPC_MAJOR_3 /* reset state to idle */ md->state = MODULE_IDLE; +#endif return ret; } @@ -315,9 +327,11 @@ int module_reset(struct processing_module *mod) int ret; struct module_data *md = &mod->priv; +#if CONFIG_IPC_MAJOR_3 /* if the module was never prepared, no need to reset */ if (md->state < MODULE_IDLE) return 0; +#endif ret = md->ops->reset(mod); if (ret) { @@ -333,12 +347,13 @@ int module_reset(struct processing_module *mod) rfree(md->cfg.data); md->cfg.data = NULL; +#if CONFIG_IPC_MAJOR_3 /* * reset the state to allow the module's prepare callback to be invoked again for the * subsequent triggers */ md->state = MODULE_INITIALIZED; - +#endif return 0; } @@ -376,8 +391,9 @@ int module_free(struct processing_module *mod) rfree(md->runtime_params); md->runtime_params = NULL; } +#if CONFIG_IPC_MAJOR_3 md->state = MODULE_DISABLED; - +#endif return ret; } From 6bcaf899cde497db312603408877401d24f35768 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Mon, 3 Jul 2023 21:59:33 -0700 Subject: [PATCH 06/12] audio: copier: Convert module to use module interface Define the module interface ops and the endpoint ops for the copier module to convert it to use the module interface. Signed-off-by: Ranjani Sridharan --- src/audio/copier/copier.c | 293 +++++++++++---------------------- src/audio/copier/copier_dai.c | 9 +- src/audio/copier/copier_host.c | 4 + 3 files changed, 107 insertions(+), 199 deletions(-) diff --git a/src/audio/copier/copier.c b/src/audio/copier/copier.c index cd997595352c..14b2b0d20450 100644 --- a/src/audio/copier/copier.c +++ b/src/audio/copier/copier.c @@ -44,8 +44,6 @@ #include #endif -static const struct comp_driver comp_copier; - LOG_MODULE_REGISTER(copier, CONFIG_SOF_LOG_LEVEL); /* this id aligns windows driver requirement to support windows driver */ @@ -85,9 +83,6 @@ static int copier_init(struct processing_module *mod) for (i = 0; i < IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT; i++) cd->out_fmt[i] = cd->config.out_fmt; - list_init(&dev->bsource_list); - list_init(&dev->bsink_list); - ipc_pipe = ipc_get_comp_by_ppl_id(ipc, COMP_TYPE_PIPELINE, config->pipeline_id); if (!ipc_pipe) { comp_err(dev, "pipeline %d is not existed", config->pipeline_id); @@ -144,6 +139,9 @@ static int copier_init(struct processing_module *mod) }; dev->direction_set = true; + } else { + /* set max sink count for module copier */ + mod->max_sinks = IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT; } dev->direction = cd->direction; @@ -154,43 +152,7 @@ static int copier_init(struct processing_module *mod) return ret; } -static struct comp_dev *copier_new(const struct comp_driver *drv, - const struct comp_ipc_config *config, - const void *spec) -{ - struct comp_dev *dev; - struct processing_module *mod; - struct module_data *md; - int ret; - - comp_cl_dbg(&comp_copier, "copier_new()"); - - mod = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*mod)); - if (!mod) - return NULL; - - dev = comp_alloc(drv, sizeof(*dev)); - if (!dev) - goto error_dev; - - dev->ipc_config = *config; - - comp_set_drvdata(dev, mod); - md = &mod->priv; - mod->dev = dev; - md->cfg.init_data = spec; - - ret = copier_init(mod); - if (!ret) - return dev; - - rfree(dev); -error_dev: - rfree(mod); - return NULL; -} - -static void copier_mod_free(struct processing_module *mod) +static int copier_free(struct processing_module *mod) { struct copier_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; @@ -211,27 +173,25 @@ static void copier_mod_free(struct processing_module *mod) } rfree(cd); -} -static void copier_free(struct comp_dev *dev) -{ - struct processing_module *mod = comp_get_drvdata(dev); - - copier_mod_free(mod); - - rfree(mod); - rfree(dev); + return 0; } -static int copier_mod_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) +static int copier_params(struct processing_module *mod); + +static int copier_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { struct copier_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; int ret; - comp_dbg(dev, "copier_prepare()"); + ret = copier_params(mod); + if (ret < 0) + return ret; + + comp_info(dev, "copier_prepare()"); switch (dev->ipc_config.type) { case SOF_COMP_HOST: @@ -267,28 +227,7 @@ static int copier_mod_prepare(struct processing_module *mod, return 0; } -static int copier_prepare(struct comp_dev *dev) -{ - struct processing_module *mod = comp_get_drvdata(dev); - int ret; - - /* cannot configure DAI while active */ - if (dev->state == COMP_STATE_ACTIVE) { - comp_info(dev, "copier_config_prepare(): Component is in active state."); - return 0; - } - - ret = comp_set_state(dev, COMP_TRIGGER_PREPARE); - if (ret < 0) - return ret; - - if (ret == COMP_STATUS_STATE_ALREADY_SET) - return PPL_STATUS_PATH_STOP; - - return copier_mod_prepare(mod, NULL, 0, NULL, 0); -} - -static int copier_mod_reset(struct processing_module *mod) +static int copier_reset(struct processing_module *mod) { struct copier_data *cd = module_get_private_data(mod); struct ipc4_pipeline_registers pipe_reg; @@ -322,18 +261,6 @@ static int copier_mod_reset(struct processing_module *mod) return 0; } -static int copier_reset(struct comp_dev *dev) -{ - struct processing_module *mod = comp_get_drvdata(dev); - int ret; - - ret = copier_mod_reset(mod); - - comp_set_state(dev, COMP_TRIGGER_RESET); - - return ret; -} - static int copier_comp_trigger(struct comp_dev *dev, int cmd) { struct processing_module *mod = comp_get_drvdata(dev); @@ -536,21 +463,59 @@ static int copier_copy_to_sinks(struct copier_data *cd, struct comp_dev *dev, return ret; } -static int copier_module_copy(struct copier_data *cd, struct comp_dev *dev) +static int copier_module_copy(struct processing_module *mod, + struct input_stream_buffer *input_buffers, int num_input_buffers, + struct output_stream_buffer *output_buffers, int num_output_buffers) { + struct copier_data *cd = module_get_private_data(mod); struct comp_buffer __sparse_cache *src_c; struct comp_copy_limits processed_data; - struct comp_buffer *src; - int ret; + int i; - src = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - src_c = buffer_acquire(src); + if (!num_input_buffers || !num_output_buffers) + return 0; - ret = copier_copy_to_sinks(cd, dev, src_c, &processed_data); + src_c = attr_container_of(input_buffers[0].data, struct comp_buffer __sparse_cache, + stream, __sparse_cache); - buffer_release(src_c); + processed_data.source_bytes = 0; - return ret; + /* convert format and copy to each active sink */ + for (i = 0; i < num_output_buffers; i++) { + struct comp_buffer __sparse_cache *sink_c; + struct comp_dev *sink_dev; + + sink_c = attr_container_of(output_buffers[i].data, + struct comp_buffer __sparse_cache, + stream, __sparse_cache); + sink_dev = sink_c->sink; + processed_data.sink_bytes = 0; + if (sink_dev->state == COMP_STATE_ACTIVE) { + uint32_t samples; + int sink_queue_id; + + sink_queue_id = IPC4_SINK_QUEUE_ID(sink_c->id); + if (sink_queue_id >= IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT) + return -EINVAL; + + /* update corresponding sink format in case it isn't updated */ + update_buffer_format(sink_c, &cd->out_fmt[sink_queue_id]); + + comp_get_copy_limits(src_c, sink_c, &processed_data); + + samples = processed_data.frames * + audio_stream_get_channels(output_buffers[i].data); + cd->converter[sink_queue_id](input_buffers[0].data, 0, + output_buffers[i].data, 0, samples); + + output_buffers[i].size = processed_data.sink_bytes; + cd->output_total_data_processed += processed_data.sink_bytes; + } + } + + input_buffers[0].consumed = processed_data.source_bytes; + + return 0; } static int copier_multi_endpoint_dai_copy(struct copier_data *cd, struct comp_dev *dev) @@ -612,12 +577,14 @@ static int copier_multi_endpoint_dai_copy(struct copier_data *cd, struct comp_de * from single stream (for output gateways) so such gateways work kind of like a single * gateway, i.e., produce/consume single stream. */ -static int copier_copy(struct comp_dev *dev) +static int copier_process(struct processing_module *mod, + struct input_stream_buffer *input_buffers, int num_input_buffers, + struct output_stream_buffer *output_buffers, int num_output_buffers) { - struct processing_module *mod = comp_get_drvdata(dev); struct copier_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; - comp_dbg(dev, "copier_copy()"); + comp_dbg(dev, "copier_process()"); switch (dev->ipc_config.type) { case SOF_COMP_HOST: @@ -636,10 +603,11 @@ static int copier_copy(struct comp_dev *dev) } /* module copier case */ - return copier_module_copy(cd, dev); + return copier_module_copy(mod, input_buffers, num_input_buffers, output_buffers, + num_output_buffers); } -static int copier_mod_params(struct processing_module *mod) +static int copier_params(struct processing_module *mod) { struct sof_ipc_stream_params *params = mod->stream_params; struct copier_data *cd = module_get_private_data(mod); @@ -673,17 +641,6 @@ static int copier_mod_params(struct processing_module *mod) return ret; } -/* configure the DMA params */ -static int copier_params(struct comp_dev *dev, struct sof_ipc_stream_params *params) -{ - struct processing_module *mod = comp_get_drvdata(dev); - - /* will remove once fully convert to module interface in last patch */ - mod->stream_params = params; - - return copier_mod_params(mod); -} - static int copier_set_sink_fmt(struct comp_dev *dev, const void *data, int max_data_size) { @@ -799,20 +756,6 @@ static int copier_set_configuration(struct processing_module *mod, } } -static int copier_set_large_config(struct comp_dev *dev, uint32_t param_id, - bool first_block, - bool last_block, - uint32_t data_offset, - const char *data) -{ - struct processing_module *mod = comp_get_drvdata(dev); - - comp_dbg(dev, "copier_set_large_config()"); - - return copier_set_configuration(mod, param_id, MODULE_CFG_FRAGMENT_SINGLE, - data_offset, data, data_offset, NULL, 0); -} - static inline void convert_u64_to_u32s(uint64_t val, uint32_t *val_l, uint32_t *val_h) { *val_l = (uint32_t)(val & 0xffffffff); @@ -905,17 +848,6 @@ static int copier_get_configuration(struct processing_module *mod, return -EINVAL; } -static int copier_get_large_config(struct comp_dev *dev, uint32_t param_id, - bool first_block, - bool last_block, - uint32_t *data_offset, - char *data) -{ - struct processing_module *mod = comp_get_drvdata(dev); - - return copier_get_configuration(mod, param_id, data_offset, data, 0); -} - static uint64_t copier_get_processed_data(struct comp_dev *dev, uint32_t stream_no, bool input) { struct processing_module *mod = comp_get_drvdata(dev); @@ -961,22 +893,6 @@ static uint64_t copier_get_processed_data(struct comp_dev *dev, uint32_t stream_ return ret; } -static int copier_get_attribute(struct comp_dev *dev, uint32_t type, void *value) -{ - struct processing_module *mod = comp_get_drvdata(dev); - struct copier_data *cd = module_get_private_data(mod); - - switch (type) { - case COMP_ATTR_BASE_CONFIG: - *(struct ipc4_base_module_cfg *)value = cd->config.base; - break; - default: - return -EINVAL; - } - - return 0; -} - static int copier_position(struct comp_dev *dev, struct sof_ipc_stream_posn *posn) { struct processing_module *mod = comp_get_drvdata(dev); @@ -1060,59 +976,42 @@ static int copier_get_hw_params(struct comp_dev *dev, struct sof_ipc_stream_para return dai_common_get_hw_params(dd, dev, params, dir); } -static int copier_mod_unbind(struct processing_module *mod, void *data) +static int copier_unbind(struct processing_module *mod, void *data) { struct copier_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; - struct dai_data *dd = cd->dd[0]; - if (dev->ipc_config.type == SOF_COMP_DAI) + if (dev->ipc_config.type == SOF_COMP_DAI) { + struct dai_data *dd = cd->dd[0]; + return dai_zephyr_unbind(dd, dev, data); + } return 0; } -static int copier_unbind(struct comp_dev *dev, void *data) -{ - struct processing_module *mod = comp_get_drvdata(dev); - - return copier_mod_unbind(mod, data); -} - -static const struct comp_driver comp_copier = { - .uid = SOF_RT_UUID(copier_comp_uuid), - .tctx = &copier_comp_tr, - .ops = { - .create = copier_new, - .free = copier_free, - .trigger = copier_comp_trigger, - .copy = copier_copy, - .set_large_config = copier_set_large_config, - .get_large_config = copier_get_large_config, - .params = copier_params, - .prepare = copier_prepare, - .reset = copier_reset, - .get_total_data_processed = copier_get_processed_data, - .get_attribute = copier_get_attribute, - .position = copier_position, - .dai_ts_config = copier_dai_ts_config_op, - .dai_ts_start = copier_dai_ts_start_op, - .dai_ts_stop = copier_dai_ts_stop_op, - .dai_ts_get = copier_dai_ts_get_op, - .dai_get_hw_params = copier_get_hw_params, - .unbind = copier_unbind, - }, +static struct module_endpoint_ops copier_endpoint_ops = { + .get_total_data_processed = copier_get_processed_data, + .position = copier_position, + .dai_ts_config = copier_dai_ts_config_op, + .dai_ts_start = copier_dai_ts_start_op, + .dai_ts_stop = copier_dai_ts_stop_op, + .dai_ts_get = copier_dai_ts_get_op, + .dai_get_hw_params = copier_get_hw_params, + .trigger = copier_comp_trigger }; -static SHARED_DATA struct comp_driver_info comp_copier_info = { - .drv = &comp_copier, +static struct module_interface copier_interface = { + .init = copier_init, + .prepare = copier_prepare, + .process_audio_stream = copier_process, + .reset = copier_reset, + .free = copier_free, + .set_configuration = copier_set_configuration, + .get_configuration = copier_get_configuration, + .unbind = copier_unbind, + .endpoint_ops = &copier_endpoint_ops, }; -UT_STATIC void sys_comp_copier_init(void) -{ - comp_register(platform_shared_get(&comp_copier_info, - sizeof(comp_copier_info))); -} - -DECLARE_MODULE(sys_comp_copier_init); -SOF_MODULE_INIT(copier, sys_comp_copier_init); +DECLARE_MODULE_ADAPTER(copier_interface, copier_comp_uuid, copier_comp_tr); +SOF_MODULE_INIT(copier, sys_comp_module_copier_interface_init); diff --git a/src/audio/copier/copier_dai.c b/src/audio/copier/copier_dai.c index 208f3c81a50b..dec0a7d46ad2 100644 --- a/src/audio/copier/copier_dai.c +++ b/src/audio/copier/copier_dai.c @@ -142,6 +142,7 @@ int copier_dai_create(struct comp_dev *parent_dev, struct copier_data *cd, const struct ipc4_copier_module_cfg *copier, struct pipeline *pipeline) { + struct processing_module *mod = comp_get_drvdata(parent_dev); int dai_index[IPC4_ALH_MAX_NUMBER_OF_GTW]; union ipc4_connector_node_id node_id; enum ipc4_gateway_type type; @@ -271,11 +272,15 @@ int copier_dai_create(struct comp_dev *parent_dev, struct copier_data *cd, return ret; } - if (cd->direction == SOF_IPC_STREAM_PLAYBACK) + if (cd->direction == SOF_IPC_STREAM_PLAYBACK) { pipeline->sink_comp = parent_dev; - else + } else { pipeline->source_comp = parent_dev; + /* set max sink count for capture */ + mod->max_sinks = IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT; + } + return 0; } diff --git a/src/audio/copier/copier_host.c b/src/audio/copier/copier_host.c index 78dbad237494..3e9f40139e26 100644 --- a/src/audio/copier/copier_host.c +++ b/src/audio/copier/copier_host.c @@ -48,6 +48,7 @@ int copier_host_create(struct comp_dev *parent_dev, struct copier_data *cd, const struct ipc4_copier_module_cfg *copier_cfg, int dir, struct pipeline *pipeline) { + struct processing_module *mod = comp_get_drvdata(parent_dev); struct ipc_config_host ipc_host; struct host_data *hd; int ret; @@ -100,6 +101,9 @@ int copier_host_create(struct comp_dev *parent_dev, struct copier_data *cd, ret = init_pipeline_reg(parent_dev); if (ret) goto e_conv; + + /* set max sink count for playback */ + mod->max_sinks = IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT; } else { config->frame_fmt = out_frame_fmt; pipeline->sink_comp = parent_dev; From d3055f9b83d86c22142cdad880537a708080be66 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Thu, 6 Jul 2023 18:08:49 -0700 Subject: [PATCH 07/12] ipc4: base-config: Expose ipc4_base_module_cfg_to_stream_params() It will be needed by other modules. Signed-off-by: Ranjani Sridharan --- src/audio/mixin_mixout/mixin_mixout.c | 31 ++------------------------- src/include/ipc4/base-config.h | 4 ++++ src/ipc/ipc4/helper.c | 23 ++++++++++++++++++++ 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/audio/mixin_mixout/mixin_mixout.c b/src/audio/mixin_mixout/mixin_mixout.c index 351977dbf140..bbed6fe56b2e 100644 --- a/src/audio/mixin_mixout/mixin_mixout.c +++ b/src/audio/mixin_mixout/mixin_mixout.c @@ -611,9 +611,6 @@ static int mixout_reset(struct processing_module *mod) return 0; } -static void base_module_cfg_to_stream_params(const struct ipc4_base_module_cfg *base_cfg, - struct sof_ipc_stream_params *params); - /* params are derived from base config for ipc4 path */ static int mixin_params(struct processing_module *mod) { @@ -625,7 +622,7 @@ static int mixin_params(struct processing_module *mod) comp_dbg(dev, "mixin_params()"); - base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); + ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); /* Buffers between mixins and mixouts are not used (mixin writes data directly to mixout * sink). But, anyway, let's setup these buffers properly just in case. @@ -732,30 +729,6 @@ static int mixin_prepare(struct processing_module *mod, return 0; } -static void base_module_cfg_to_stream_params(const struct ipc4_base_module_cfg *base_cfg, - struct sof_ipc_stream_params *params) -{ - enum sof_ipc_frame frame_fmt, valid_fmt; - int i; - - memset(params, 0, sizeof(struct sof_ipc_stream_params)); - params->channels = base_cfg->audio_fmt.channels_count; - params->rate = base_cfg->audio_fmt.sampling_frequency; - params->sample_container_bytes = base_cfg->audio_fmt.depth / 8; - params->sample_valid_bytes = base_cfg->audio_fmt.valid_bit_depth / 8; - params->buffer_fmt = base_cfg->audio_fmt.interleaving_style; - params->buffer.size = base_cfg->obs * 2; - - audio_stream_fmt_conversion(base_cfg->audio_fmt.depth, - base_cfg->audio_fmt.valid_bit_depth, - &frame_fmt, &valid_fmt, - base_cfg->audio_fmt.s_type); - params->frame_fmt = valid_fmt; - - for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) - params->chmap[i] = (base_cfg->audio_fmt.ch_map >> i * 4) & 0xf; -} - static int mixout_params(struct processing_module *mod) { struct sof_ipc_stream_params *params = mod->stream_params; @@ -768,7 +741,7 @@ static int mixout_params(struct processing_module *mod) comp_dbg(dev, "mixout_params()"); - base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); + ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); ret = comp_verify_params(dev, 0, params); if (ret < 0) { diff --git a/src/include/ipc4/base-config.h b/src/include/ipc4/base-config.h index 104da996e8a0..56533425753d 100644 --- a/src/include/ipc4/base-config.h +++ b/src/include/ipc4/base-config.h @@ -237,4 +237,8 @@ union ipc4_cfg_param_id_data { } f; } __attribute__((packed, aligned(4))); +struct sof_ipc_stream_params; +void ipc4_base_module_cfg_to_stream_params(const struct ipc4_base_module_cfg *base_cfg, + struct sof_ipc_stream_params *params); + #endif diff --git a/src/ipc/ipc4/helper.c b/src/ipc/ipc4/helper.c index 00f1bf4f8866..46a50d482bef 100644 --- a/src/ipc/ipc4/helper.c +++ b/src/ipc/ipc4/helper.c @@ -803,3 +803,26 @@ int ipc4_find_dma_config(struct ipc_config_dai *dai, uint8_t *data_buffer, uint3 return IPC4_SUCCESS; } +void ipc4_base_module_cfg_to_stream_params(const struct ipc4_base_module_cfg *base_cfg, + struct sof_ipc_stream_params *params) +{ + enum sof_ipc_frame frame_fmt, valid_fmt; + int i; + + memset(params, 0, sizeof(struct sof_ipc_stream_params)); + params->channels = base_cfg->audio_fmt.channels_count; + params->rate = base_cfg->audio_fmt.sampling_frequency; + params->sample_container_bytes = base_cfg->audio_fmt.depth / 8; + params->sample_valid_bytes = base_cfg->audio_fmt.valid_bit_depth / 8; + params->buffer_fmt = base_cfg->audio_fmt.interleaving_style; + params->buffer.size = base_cfg->obs * 2; + + audio_stream_fmt_conversion(base_cfg->audio_fmt.depth, + base_cfg->audio_fmt.valid_bit_depth, + &frame_fmt, &valid_fmt, + base_cfg->audio_fmt.s_type); + params->frame_fmt = valid_fmt; + + for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) + params->chmap[i] = (base_cfg->audio_fmt.ch_map >> i * 4) & 0xf; +} From 44ec642372602100047d519c0cce55d119dd29b3 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Thu, 6 Jul 2023 19:03:29 -0700 Subject: [PATCH 08/12] audio: module_adapter: Update stream params Update the pipeline params based on the base config. Signed-off-by: Ranjani Sridharan --- src/audio/module_adapter/module_adapter.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index ea4d90e6321d..d40175c675db 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -548,6 +548,10 @@ int module_adapter_params(struct comp_dev *dev, struct sof_ipc_stream_params *pa return ret; } +#if CONFIG_IPC_MAJOR_4 + ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); + ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, mod->stream_params); +#endif return 0; } From 79d82aa86c7ae014ea9fdd23984d20a900063414 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Thu, 6 Jul 2023 20:11:16 -0700 Subject: [PATCH 09/12] ipc4: Expose ipc4_update_buffer_format() It will be needed by other modules as well. Signed-off-by: Ranjani Sridharan --- src/audio/copier/copier.c | 5 +++-- src/audio/copier/copier_generic.c | 28 +++------------------------- src/include/ipc4/base-config.h | 4 ++++ src/include/ipc4/copier.h | 3 --- src/ipc/ipc4/helper.c | 23 +++++++++++++++++++++++ 5 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/audio/copier/copier.c b/src/audio/copier/copier.c index 14b2b0d20450..d5abcb8422b2 100644 --- a/src/audio/copier/copier.c +++ b/src/audio/copier/copier.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -499,7 +500,7 @@ static int copier_module_copy(struct processing_module *mod, return -EINVAL; /* update corresponding sink format in case it isn't updated */ - update_buffer_format(sink_c, &cd->out_fmt[sink_queue_id]); + ipc4_update_buffer_format(sink_c, &cd->out_fmt[sink_queue_id]); comp_get_copy_limits(src_c, sink_c, &processed_data); @@ -688,7 +689,7 @@ static int copier_set_sink_fmt(struct comp_dev *dev, const void *data, sink_id = IPC4_SINK_QUEUE_ID(sink_c->id); if (sink_id == sink_fmt->sink_id) { - update_buffer_format(sink_c, &sink_fmt->sink_fmt); + ipc4_update_buffer_format(sink_c, &sink_fmt->sink_fmt); buffer_release(sink_c); break; } diff --git a/src/audio/copier/copier_generic.c b/src/audio/copier/copier_generic.c index b9c80b05bebd..9ffbc8102f1e 100644 --- a/src/audio/copier/copier_generic.c +++ b/src/audio/copier/copier_generic.c @@ -4,6 +4,7 @@ // // Author: Andrula Song +#include #include #include @@ -57,29 +58,6 @@ int apply_attenuation(struct comp_dev *dev, struct copier_data *cd, } #endif -void update_buffer_format(struct comp_buffer __sparse_cache *buf_c, - const struct ipc4_audio_format *fmt) -{ - enum sof_ipc_frame valid_fmt, frame_fmt; - int i; - - audio_stream_set_channels(&buf_c->stream, fmt->channels_count); - audio_stream_set_rate(&buf_c->stream, fmt->sampling_frequency); - audio_stream_fmt_conversion(fmt->depth, - fmt->valid_bit_depth, - &frame_fmt, &valid_fmt, - fmt->s_type); - - audio_stream_set_frm_fmt(&buf_c->stream, frame_fmt); - audio_stream_set_valid_fmt(&buf_c->stream, valid_fmt); - audio_stream_set_buffer_fmt(&buf_c->stream, fmt->interleaving_style); - - for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) - buf_c->chmap[i] = (fmt->ch_map >> i * 4) & 0xf; - - buf_c->hw_params_configured = true; -} - void copier_update_params(struct copier_data *cd, struct comp_dev *dev, struct sof_ipc_stream_params *params) { @@ -111,7 +89,7 @@ void copier_update_params(struct copier_data *cd, struct comp_dev *dev, j = IPC4_SINK_QUEUE_ID(sink_c->id); - update_buffer_format(sink_c, &cd->out_fmt[j]); + ipc4_update_buffer_format(sink_c, &cd->out_fmt[j]); buffer_release(sink_c); } @@ -127,7 +105,7 @@ void copier_update_params(struct copier_data *cd, struct comp_dev *dev, source_c = buffer_acquire(source); in_fmt = &cd->config.base.audio_fmt; - update_buffer_format(source_c, in_fmt); + ipc4_update_buffer_format(source_c, in_fmt); buffer_release(source_c); } diff --git a/src/include/ipc4/base-config.h b/src/include/ipc4/base-config.h index 56533425753d..26eeb07bf355 100644 --- a/src/include/ipc4/base-config.h +++ b/src/include/ipc4/base-config.h @@ -25,6 +25,7 @@ #define __SOF_IPC4_BASE_CONFIG_H__ #include +#include enum ipc4_sampling_frequency { IPC4_FS_8000HZ = 8000, @@ -240,5 +241,8 @@ union ipc4_cfg_param_id_data { struct sof_ipc_stream_params; void ipc4_base_module_cfg_to_stream_params(const struct ipc4_base_module_cfg *base_cfg, struct sof_ipc_stream_params *params); +struct comp_buffer; +void ipc4_update_buffer_format(struct comp_buffer __sparse_cache *buf_c, + const struct ipc4_audio_format *fmt); #endif diff --git a/src/include/ipc4/copier.h b/src/include/ipc4/copier.h index 4f1f3da49c87..d6965f1c3c22 100644 --- a/src/include/ipc4/copier.h +++ b/src/include/ipc4/copier.h @@ -283,9 +283,6 @@ int create_endpoint_buffer(struct comp_dev *parent_dev, enum sof_ipc_stream_direction get_gateway_direction(enum ipc4_connector_node_id_type node_id_type); -void update_buffer_format(struct comp_buffer __sparse_cache *buf_c, - const struct ipc4_audio_format *fmt); - void copier_update_params(struct copier_data *cd, struct comp_dev *dev, struct sof_ipc_stream_params *params); #endif diff --git a/src/ipc/ipc4/helper.c b/src/ipc/ipc4/helper.c index 46a50d482bef..3d889a294235 100644 --- a/src/ipc/ipc4/helper.c +++ b/src/ipc/ipc4/helper.c @@ -826,3 +826,26 @@ void ipc4_base_module_cfg_to_stream_params(const struct ipc4_base_module_cfg *ba for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) params->chmap[i] = (base_cfg->audio_fmt.ch_map >> i * 4) & 0xf; } + +void ipc4_update_buffer_format(struct comp_buffer __sparse_cache *buf_c, + const struct ipc4_audio_format *fmt) +{ + enum sof_ipc_frame valid_fmt, frame_fmt; + int i; + + audio_stream_set_channels(&buf_c->stream, fmt->channels_count); + audio_stream_set_rate(&buf_c->stream, fmt->sampling_frequency); + audio_stream_fmt_conversion(fmt->depth, + fmt->valid_bit_depth, + &frame_fmt, &valid_fmt, + fmt->s_type); + + audio_stream_set_frm_fmt(&buf_c->stream, frame_fmt); + audio_stream_set_valid_fmt(&buf_c->stream, valid_fmt); + audio_stream_set_buffer_fmt(&buf_c->stream, fmt->interleaving_style); + + for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) + buf_c->chmap[i] = (fmt->ch_map >> i * 4) & 0xf; + + buf_c->hw_params_configured = true; +} From 057c46fbac4966ec976cb0476d5198566cdc7dbb Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Thu, 6 Jul 2023 18:12:11 -0700 Subject: [PATCH 10/12] audio: asrc: Fix a typo Fix the function name in the comment. Signed-off-by: Ranjani Sridharan --- src/audio/asrc/asrc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/asrc/asrc.c b/src/audio/asrc/asrc.c index 9f88d6d4b1b6..4d0c4bdbb7f6 100644 --- a/src/audio/asrc/asrc.c +++ b/src/audio/asrc/asrc.c @@ -541,7 +541,7 @@ static int asrc_params(struct comp_dev *dev, err = asrc_verify_params(dev, pcm_params); if (err < 0) { - comp_err(dev, "src_params(): pcm params verification failed."); + comp_err(dev, "asrc_params(): pcm params verification failed."); return -EINVAL; } From 746fc2b1aa2f5a7654d8b6b786af8ed8d10a20cf Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Thu, 6 Jul 2023 18:10:27 -0700 Subject: [PATCH 11/12] audio: asrc: Update stream params from base config The input stream params may not be updated by the source module. So update the stream params from the config. Also, update the source/sink ibuffer formats based on the base config audio format. Signed-off-by: Ranjani Sridharan --- src/audio/asrc/asrc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/audio/asrc/asrc.c b/src/audio/asrc/asrc.c index 4d0c4bdbb7f6..6f25e15129c5 100644 --- a/src/audio/asrc/asrc.c +++ b/src/audio/asrc/asrc.c @@ -539,6 +539,10 @@ static int asrc_params(struct comp_dev *dev, comp_info(dev, "asrc_params()"); +#if CONFIG_IPC_MAJOR_4 + ipc4_base_module_cfg_to_stream_params(&cd->ipc_config.base, pcm_params); +#endif + err = asrc_verify_params(dev, pcm_params); if (err < 0) { comp_err(dev, "asrc_params(): pcm params verification failed."); @@ -553,6 +557,12 @@ static int asrc_params(struct comp_dev *dev, source_c = buffer_acquire(sourceb); sink_c = buffer_acquire(sinkb); +#if CONFIG_IPC_MAJOR_4 + /* update the source/sink buffer formats. Sink rate will be modified below */ + ipc4_update_buffer_format(source_c, &cd->ipc_config.base.audio_fmt); + ipc4_update_buffer_format(sink_c, &cd->ipc_config.base.audio_fmt); +#endif + /* Don't change sink rate if value from IPC is 0 (auto detect) */ if (asrc_get_sink_rate(&cd->ipc_config)) audio_stream_set_rate(&sink_c->stream, asrc_get_sink_rate(&cd->ipc_config)); From d6e45830954c7da6c4599d59e1b258ea28660693 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Sun, 9 Jul 2023 17:12:31 -0700 Subject: [PATCH 12/12] audio: volume: Simplify volume_params() Use the helper functions to update the stream params and the source/sink buffer formats. Signed-off-by: Ranjani Sridharan --- .../module_adapter/module/volume/volume.c | 33 +++++++------------ 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/src/audio/module_adapter/module/volume/volume.c b/src/audio/module_adapter/module/volume/volume.c index 8a952d3aee7d..fd5501e39fd5 100644 --- a/src/audio/module_adapter/module/volume/volume.c +++ b/src/audio/module_adapter/module/volume/volume.c @@ -1118,39 +1118,28 @@ static int volume_get_config(struct processing_module *mod, static int volume_params(struct processing_module *mod) { struct sof_ipc_stream_params *params = mod->stream_params; - struct sof_ipc_stream_params vol_params; - enum sof_ipc_frame frame_fmt, valid_fmt; + struct comp_buffer __sparse_cache *sink_c, *source_c; + struct comp_buffer *sinkb, *sourceb; struct comp_dev *dev = mod->dev; - struct comp_buffer *sinkb; - struct comp_buffer __sparse_cache *sink_c; - int i, ret; comp_dbg(dev, "volume_params()"); - vol_params = *params; - vol_params.channels = mod->priv.cfg.base_cfg.audio_fmt.channels_count; - vol_params.rate = mod->priv.cfg.base_cfg.audio_fmt.sampling_frequency; - vol_params.buffer_fmt = mod->priv.cfg.base_cfg.audio_fmt.interleaving_style; - - audio_stream_fmt_conversion(mod->priv.cfg.base_cfg.audio_fmt.depth, - mod->priv.cfg.base_cfg.audio_fmt.valid_bit_depth, - &frame_fmt, &valid_fmt, - mod->priv.cfg.base_cfg.audio_fmt.s_type); - - vol_params.frame_fmt = valid_fmt; + ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); - for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) - vol_params.chmap[i] = (mod->priv.cfg.base_cfg.audio_fmt.ch_map >> i * 4) & 0xf; - - component_set_nearest_period_frames(dev, vol_params.rate); + component_set_nearest_period_frames(dev, params->rate); /* volume component will only ever have 1 sink buffer */ sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); sink_c = buffer_acquire(sinkb); - ret = buffer_set_params(sink_c, &vol_params, true); + ipc4_update_buffer_format(sink_c, &mod->priv.cfg.base_cfg.audio_fmt); buffer_release(sink_c); - return ret; + sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); + source_c = buffer_acquire(sourceb); + ipc4_update_buffer_format(source_c, &mod->priv.cfg.base_cfg.audio_fmt); + buffer_release(source_c); + + return 0; } #endif /* CONFIG_IPC_MAJOR_4 */