From d2a8682818e43b43efca0747549b09b5986818c5 Mon Sep 17 00:00:00 2001 From: Baofeng Tian Date: Wed, 29 Nov 2023 16:52:58 +0800 Subject: [PATCH] Audio: multiband drc: split out ipc3 and ipc4 specific code Split out ipc3 and ipc4 specific code from mulitband_drc.c. Signed-off-by: Baofeng Tian --- src/audio/CMakeLists.txt | 2 + src/audio/multiband_drc/CMakeLists.txt | 6 + src/audio/multiband_drc/multiband_drc.c | 138 +------------------ src/audio/multiband_drc/multiband_drc.h | 8 ++ src/audio/multiband_drc/multiband_drc_ipc3.c | 102 ++++++++++++++ src/audio/multiband_drc/multiband_drc_ipc4.c | 106 ++++++++++++++ zephyr/CMakeLists.txt | 9 ++ 7 files changed, 237 insertions(+), 134 deletions(-) create mode 100644 src/audio/multiband_drc/multiband_drc_ipc3.c create mode 100644 src/audio/multiband_drc/multiband_drc_ipc4.c diff --git a/src/audio/CMakeLists.txt b/src/audio/CMakeLists.txt index 101edc2a838e..747d1c7735aa 100644 --- a/src/audio/CMakeLists.txt +++ b/src/audio/CMakeLists.txt @@ -178,12 +178,14 @@ if(CONFIG_IPC_MAJOR_3) set(eq-iir_sources eq_iir/eq_iir_ipc3.c eq_iir/eq_iir_generic.c) set(eq-fir_sources eq_fir/eq_fir_ipc3.c) set(tdfb_sources tdfb/tdfb_ipc3.c) + set(tdfb_sources multiband_drc/multiband_drc_ipc3.c) elseif(CONFIG_IPC_MAJOR_4) set(volume_sources volume/volume.c volume/volume_generic.c volume/volume_ipc4.c) set(src_sources src/src.c src/src_ipc4.c src/src_generic.c) set(eq-iir_sources eq_iir/eq_iir_ipc4.c eq_iir/eq_iir_generic.c) set(eq-fir_sources eq_fir/eq_fir_ipc4.c) set(tdfb_sources tdfb/tdfb_ipc4.c) + set(tdfb_sources multiband_drc/multiband_drc_ipc4.c) endif() set(mixer_sources ${mixer_src}) set(asrc_sources asrc/asrc.c asrc/asrc_farrow.c asrc/asrc_farrow_generic.c) diff --git a/src/audio/multiband_drc/CMakeLists.txt b/src/audio/multiband_drc/CMakeLists.txt index 202b9d6eecb6..3579af97f97b 100644 --- a/src/audio/multiband_drc/CMakeLists.txt +++ b/src/audio/multiband_drc/CMakeLists.txt @@ -1,2 +1,8 @@ add_local_sources(sof multiband_drc.c) add_local_sources(sof multiband_drc_generic.c) + +if(CONFIG_IPC_MAJOR_3) + add_local_sources(sof multiband_drc_ipc3.c) +elseif(CONFIG_IPC_MAJOR_4) + add_local_sources(sof multiband_drc_ipc4.c) +endif() diff --git a/src/audio/multiband_drc/multiband_drc.c b/src/audio/multiband_drc/multiband_drc.c index 81f5feb18f09..1da34ef25d7a 100644 --- a/src/audio/multiband_drc/multiband_drc.c +++ b/src/audio/multiband_drc/multiband_drc.c @@ -241,16 +241,12 @@ static int multiband_drc_init(struct processing_module *mod) md->private = cd; cd->multiband_drc_func = NULL; cd->crossover_split = NULL; -#if CONFIG_IPC_MAJOR_4 /* Initialize to enabled is a workaround for IPC4 kernel version 6.6 and * before where the processing is never enabled via switch control. New * kernel sends the IPC4 switch control and sets this to desired state * before prepare. */ - cd->process_enabled = true; -#else - cd->process_enabled = false; -#endif + multiband_drc_process_enable(&cd->process_enabled); /* Handler for configuration data */ cd->model_handler = comp_data_blob_handler_new(dev); @@ -288,118 +284,29 @@ static int multiband_drc_free(struct processing_module *mod) return 0; } -#if CONFIG_IPC_MAJOR_3 -static int multiband_drc_cmd_set_value(struct processing_module *mod, - struct sof_ipc_ctrl_data *cdata) -{ - struct comp_dev *dev = mod->dev; - struct multiband_drc_comp_data *cd = module_get_private_data(mod); - - switch (cdata->cmd) { - case SOF_CTRL_CMD_SWITCH: - comp_dbg(dev, "multiband_drc_multiband_drc_cmd_set_value(), SOF_CTRL_CMD_SWITCH"); - if (cdata->num_elems == 1) { - cd->process_enabled = cdata->chanv[0].value; - comp_info(dev, "multiband_drc_cmd_set_value(), process_enabled = %d", - cd->process_enabled); - return 0; - } - } - - comp_err(mod->dev, "cmd_set_value() error: invalid cdata->cmd"); - return -EINVAL; -} -#endif - static int multiband_drc_set_config(struct processing_module *mod, uint32_t param_id, enum module_cfg_fragment_position pos, uint32_t data_offset_size, const uint8_t *fragment, size_t fragment_size, uint8_t *response, size_t response_size) { - struct multiband_drc_comp_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; comp_dbg(dev, "multiband_drc_set_config()"); -#if CONFIG_IPC_MAJOR_4 - struct sof_ipc4_control_msg_payload *ctl = (struct sof_ipc4_control_msg_payload *)fragment; - - switch (param_id) { - case SOF_IPC4_SWITCH_CONTROL_PARAM_ID: - comp_dbg(dev, "SOF_IPC4_SWITCH_CONTROL_PARAM_ID id = %d, num_elems = %d", - ctl->id, ctl->num_elems); - - if (ctl->id == 0 && ctl->num_elems == 1) { - cd->process_enabled = ctl->chanv[0].value; - comp_info(dev, "process_enabled = %d", cd->process_enabled); - } else { - comp_err(dev, "Illegal control id = %d, num_elems = %d", - ctl->id, ctl->num_elems); - return -EINVAL; - } - - return 0; - - case SOF_IPC4_ENUM_CONTROL_PARAM_ID: - comp_err(dev, "multiband_drc_set_config(), illegal control."); - return -EINVAL; - } - -#elif CONFIG_IPC_MAJOR_3 - struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; - - if (cdata->cmd != SOF_CTRL_CMD_BINARY) - return multiband_drc_cmd_set_value(mod, cdata); -#endif - - comp_dbg(mod->dev, "multiband_drc_set_config(), SOF_CTRL_CMD_BINARY"); - return comp_data_blob_set(cd->model_handler, pos, data_offset_size, fragment, - fragment_size); + return multiband_drc_set_ipc_config(mod, param_id, + fragment, pos, data_offset_size, fragment_size); } -#if CONFIG_IPC_MAJOR_3 -static int multiband_drc_cmd_get_value(struct processing_module *mod, - struct sof_ipc_ctrl_data *cdata) -{ - struct comp_dev *dev = mod->dev; - struct multiband_drc_comp_data *cd = module_get_private_data(mod); - int j; - - switch (cdata->cmd) { - case SOF_CTRL_CMD_SWITCH: - comp_dbg(dev, "multiband_drc_cmd_get_value(), SOF_CTRL_CMD_SWITCH"); - for (j = 0; j < cdata->num_elems; j++) - cdata->chanv[j].value = cd->process_enabled; - if (cdata->num_elems == 1) - return 0; - - comp_warn(dev, "multiband_drc_cmd_get_value() warn: num_elems should be 1, got %d", - cdata->num_elems); - return 0; - } - - comp_err(dev, "tdfb_cmd_get_value() error: invalid cdata->cmd"); - return -EINVAL; -} -#endif - static int multiband_drc_get_config(struct processing_module *mod, uint32_t config_id, uint32_t *data_offset_size, uint8_t *fragment, size_t fragment_size) { - struct multiband_drc_comp_data *cd = module_get_private_data(mod); struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; comp_dbg(mod->dev, "multiband_drc_get_config()"); -#if CONFIG_IPC_MAJOR_3 - if (cdata->cmd != SOF_CTRL_CMD_BINARY) - return multiband_drc_cmd_get_value(mod, cdata); -#endif - - comp_dbg(mod->dev, "multiband_drc_get_config(), SOF_CTRL_CMD_BINARY"); - return comp_data_blob_get_cmd(cd->model_handler, cdata, fragment_size); + return multiband_drc_get_ipc_config(mod, cdata, fragment_size); } static void multiband_drc_set_alignment(struct audio_stream *source, @@ -442,41 +349,6 @@ static int multiband_drc_process(struct processing_module *mod, return 0; } -#if CONFIG_IPC_MAJOR_4 -static int multiband_drc_params(struct processing_module *mod) -{ - struct sof_ipc_stream_params *params = mod->stream_params; - struct sof_ipc_stream_params comp_params; - struct comp_dev *dev = mod->dev; - struct comp_buffer *sinkb; - enum sof_ipc_frame valid_fmt, frame_fmt; - int i, ret; - - comp_dbg(dev, "multiband_drc_params()"); - - comp_params = *params; - comp_params.channels = mod->priv.cfg.base_cfg.audio_fmt.channels_count; - comp_params.rate = mod->priv.cfg.base_cfg.audio_fmt.sampling_frequency; - comp_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); - - comp_params.frame_fmt = frame_fmt; - - for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) - comp_params.chmap[i] = (mod->priv.cfg.base_cfg.audio_fmt.ch_map >> i * 4) & 0xf; - - component_set_nearest_period_frames(dev, comp_params.rate); - sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - ret = buffer_set_params(sinkb, &comp_params, true); - - return ret; -} -#endif /* CONFIG_IPC_MAJOR_4 */ - static int multiband_drc_prepare(struct processing_module *mod, struct sof_source **sources, int num_of_sources, struct sof_sink **sinks, int num_of_sinks) @@ -490,11 +362,9 @@ static int multiband_drc_prepare(struct processing_module *mod, comp_info(dev, "multiband_drc_prepare()"); -#if CONFIG_IPC_MAJOR_4 ret = multiband_drc_params(mod); if (ret < 0) return ret; -#endif /* DRC component will only ever have 1 source and 1 sink buffer */ sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); diff --git a/src/audio/multiband_drc/multiband_drc.h b/src/audio/multiband_drc/multiband_drc.h index 07286f315f3d..146b7c53887a 100644 --- a/src/audio/multiband_drc/multiband_drc.h +++ b/src/audio/multiband_drc/multiband_drc.h @@ -92,6 +92,14 @@ static inline void multiband_drc_iir_reset_state_ch(struct iir_state_df2t *iir) iir->delay = NULL; } +void multiband_drc_process_enable(bool *process_enabled); +int multiband_drc_set_ipc_config(struct processing_module *mod, uint32_t param_id, + const uint8_t *fragment, enum module_cfg_fragment_position pos, + uint32_t data_offset_size, size_t fragment_size); +int multiband_drc_get_ipc_config(struct processing_module *mod, struct sof_ipc_ctrl_data *cdata, + size_t fragment_size); +int multiband_drc_params(struct processing_module *mod); + #ifdef UNIT_TEST void sys_comp_module_multiband_drc_interface_init(void); #endif diff --git a/src/audio/multiband_drc/multiband_drc_ipc3.c b/src/audio/multiband_drc/multiband_drc_ipc3.c new file mode 100644 index 000000000000..fdc9de9e5ba9 --- /dev/null +++ b/src/audio/multiband_drc/multiband_drc_ipc3.c @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2020 Google LLC. All rights reserved. +// +// Author: Pin-chih Lin + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "multiband_drc.h" + +LOG_MODULE_DECLARE(multiband_drc, CONFIG_SOF_LOG_LEVEL); + +void multiband_drc_process_enable(bool *process_enabled) +{ + *process_enabled = false; +} + +static int multiband_drc_cmd_set_value(struct processing_module *mod, + struct sof_ipc_ctrl_data *cdata) +{ + struct comp_dev *dev = mod->dev; + struct multiband_drc_comp_data *cd = module_get_private_data(mod); + + switch (cdata->cmd) { + case SOF_CTRL_CMD_SWITCH: + comp_dbg(dev, "multiband_drc_multiband_drc_cmd_set_value(), SOF_CTRL_CMD_SWITCH"); + if (cdata->num_elems == 1) { + cd->process_enabled = cdata->chanv[0].value; + comp_info(dev, "multiband_drc_cmd_set_value(), process_enabled = %d", + cd->process_enabled); + return 0; + } + } + + comp_err(mod->dev, "cmd_set_value() error: invalid cdata->cmd"); + return -EINVAL; +} + +int multiband_drc_set_ipc_config(struct processing_module *mod, uint32_t param_id, + const uint8_t *fragment, enum module_cfg_fragment_position pos, + uint32_t data_offset_size, size_t fragment_size) +{ + struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; + struct multiband_drc_comp_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; + + if (cdata->cmd != SOF_CTRL_CMD_BINARY) + return multiband_drc_cmd_set_value(mod, cdata); + + comp_dbg(dev, "multiband_drc_set_config(), SOF_CTRL_CMD_BINARY"); + return comp_data_blob_set(cd->model_handler, pos, data_offset_size, fragment, + fragment_size); +} + +static int multiband_drc_cmd_get_value(struct processing_module *mod, + struct sof_ipc_ctrl_data *cdata) +{ + struct comp_dev *dev = mod->dev; + struct multiband_drc_comp_data *cd = module_get_private_data(mod); + int j; + + switch (cdata->cmd) { + case SOF_CTRL_CMD_SWITCH: + comp_dbg(dev, "multiband_drc_cmd_get_value(), SOF_CTRL_CMD_SWITCH"); + for (j = 0; j < cdata->num_elems; j++) + cdata->chanv[j].value = cd->process_enabled; + if (cdata->num_elems == 1) + return 0; + + comp_warn(dev, "multiband_drc_cmd_get_value() warn: num_elems should be 1, got %d", + cdata->num_elems); + return 0; + } + + comp_err(dev, "tdfb_cmd_get_value() error: invalid cdata->cmd"); + return -EINVAL; +} + +int multiband_drc_get_ipc_config(struct processing_module *mod, struct sof_ipc_ctrl_data *cdata, + size_t fragment_size) +{ + struct multiband_drc_comp_data *cd = module_get_private_data(mod); + + if (cdata->cmd != SOF_CTRL_CMD_BINARY) + return multiband_drc_cmd_get_value(mod, cdata); + + comp_dbg(mod->dev, "multiband_drc_get_ipc_config(), SOF_CTRL_CMD_BINARY"); + return comp_data_blob_get_cmd(cd->model_handler, cdata, fragment_size); +} + +int multiband_drc_params(struct processing_module *mod) +{ + return 0; +} + diff --git a/src/audio/multiband_drc/multiband_drc_ipc4.c b/src/audio/multiband_drc/multiband_drc_ipc4.c new file mode 100644 index 000000000000..e2471d6f2a8e --- /dev/null +++ b/src/audio/multiband_drc/multiband_drc_ipc4.c @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2020 Google LLC. All rights reserved. +// +// Author: Pin-chih Lin + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "multiband_drc.h" + +LOG_MODULE_DECLARE(multiband_drc, CONFIG_SOF_LOG_LEVEL); + +void multiband_drc_process_enable(bool *process_enabled) +{ + *process_enabled = true; +} + +int multiband_drc_set_ipc_config(struct processing_module *mod, uint32_t param_id, + const uint8_t *fragment, enum module_cfg_fragment_position pos, + uint32_t data_offset_size, size_t fragment_size) +{ + struct sof_ipc4_control_msg_payload *ctl = (struct sof_ipc4_control_msg_payload *)fragment; + struct multiband_drc_comp_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; + + switch (param_id) { + case SOF_IPC4_SWITCH_CONTROL_PARAM_ID: + comp_dbg(dev, "SOF_IPC4_SWITCH_CONTROL_PARAM_ID id = %d, num_elems = %d", + ctl->id, ctl->num_elems); + + if (ctl->id == 0 && ctl->num_elems == 1) { + cd->process_enabled = ctl->chanv[0].value; + comp_info(dev, "process_enabled = %d", cd->process_enabled); + } else { + comp_err(dev, "Illegal control id = %d, num_elems = %d", + ctl->id, ctl->num_elems); + return -EINVAL; + } + + return 0; + + case SOF_IPC4_ENUM_CONTROL_PARAM_ID: + comp_err(dev, "multiband_drc_set_ipc_config(), illegal control."); + return -EINVAL; + } + + comp_dbg(mod->dev, "multiband_drc_set_ipc_config(), SOF_CTRL_CMD_BINARY"); + return comp_data_blob_set(cd->model_handler, pos, data_offset_size, fragment, + fragment_size); +} + +int multiband_drc_get_ipc_config(struct processing_module *mod, struct sof_ipc_ctrl_data *cdata, + size_t fragment_size) +{ + struct multiband_drc_comp_data *cd = module_get_private_data(mod); + + comp_dbg(mod->dev, "multiband_drc_get_ipc_config(), SOF_CTRL_CMD_BINARY"); + + return comp_data_blob_get_cmd(cd->model_handler, cdata, fragment_size); +} + +int multiband_drc_params(struct processing_module *mod) +{ + struct sof_ipc_stream_params *params = mod->stream_params; + struct sof_ipc_stream_params comp_params; + struct comp_dev *dev = mod->dev; + struct comp_buffer *sinkb; + enum sof_ipc_frame valid_fmt, frame_fmt; + int i, ret; + + comp_dbg(dev, "multiband_drc_params()"); + + comp_params = *params; + comp_params.channels = mod->priv.cfg.base_cfg.audio_fmt.channels_count; + comp_params.rate = mod->priv.cfg.base_cfg.audio_fmt.sampling_frequency; + comp_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); + + comp_params.frame_fmt = frame_fmt; + + for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) + comp_params.chmap[i] = (mod->priv.cfg.base_cfg.audio_fmt.ch_map >> i * 4) & 0xf; + + component_set_nearest_period_frames(dev, comp_params.rate); + sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); + ret = buffer_set_params(sinkb, &comp_params, true); + + return ret; +} + diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index f9e1f3c40e00..6c55764a3165 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -690,10 +690,19 @@ zephyr_library_sources_ifdef(CONFIG_COMP_DRC ${SOF_AUDIO_PATH}/drc/drc_math_hifi3.c ) +if(CONFIG_IPC_MAJOR_3) zephyr_library_sources_ifdef(CONFIG_COMP_MULTIBAND_DRC ${SOF_AUDIO_PATH}/multiband_drc/multiband_drc.c ${SOF_AUDIO_PATH}/multiband_drc/multiband_drc_generic.c + ${SOF_AUDIO_PATH}/multiband_drc/multiband_drc_ipc3.c ) +elseif(CONFIG_IPC_MAJOR_4) +zephyr_library_sources_ifdef(CONFIG_COMP_MULTIBAND_DRC + ${SOF_AUDIO_PATH}/multiband_drc/multiband_drc.c + ${SOF_AUDIO_PATH}/multiband_drc/multiband_drc_generic.c + ${SOF_AUDIO_PATH}/multiband_drc/multiband_drc_ipc4.c +) +endif() zephyr_library_sources_ifdef(CONFIG_COMP_GOOGLE_RTC_AUDIO_PROCESSING ${SOF_AUDIO_PATH}/google/google_rtc_audio_processing.c