From a8bd16ab7a5bd5083d19c605b8679b80fc3dd3bb Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Thu, 9 Nov 2023 19:45:18 +0200 Subject: [PATCH 1/2] Audio: DRC: Add processing enable switch control This patch adds to DRC component in IPC4 mode a control to switch processing on/off. The control is useful for DRC pipeline that is used for both headphone (unprocessed) and speaker (processed). It also allows the user to switch off DRC processing if desired. If a blob has enable set to false the processing cannot be enabled with the switch control. If the blob enables processing, the user space can control processing on or off. Signed-off-by: Seppo Ingalsuo --- src/audio/drc/drc.c | 39 +++++++++++++++++++++++++++++++++++-- src/audio/drc/drc.h | 10 +++++++++- src/audio/drc/drc_generic.c | 6 +++--- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/audio/drc/drc.c b/src/audio/drc/drc.c index f27e5096576e..9eff93d79019 100644 --- a/src/audio/drc/drc.c +++ b/src/audio/drc/drc.c @@ -184,6 +184,13 @@ static int drc_init(struct processing_module *mod) } drc_reset_state(&cd->state); + + /* Initialize DRC to enabled. If defined by topology, a control may set + * enabled to false before prepare() or during streaming with the switch + * control from user space. + */ + cd->enabled = true; + cd->enable_switch = true; return 0; cd_fail: @@ -203,15 +210,40 @@ static int drc_free(struct processing_module *mod) return 0; } -static int drc_set_config(struct processing_module *mod, uint32_t config_id, +static int 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 drc_comp_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; + + comp_dbg(dev, "drc_set_config()"); - comp_info(mod->dev, "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: + if (ctl->id == SOF_DRC_CTRL_INDEX_ENABLE_SWITCH && + ctl->num_elems == SOF_DRC_NUM_ELEMS_ENABLE_SWITCH) { + cd->enable_switch = ctl->chanv[0].value; + comp_info(dev, "drc_set_config(), enable_switch = %d", cd->enable_switch); + } else { + comp_err(dev, "Illegal switch 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, "drc_set_config(), illegal control."); + return -EINVAL; + } +#endif + + comp_info(dev, "drc_set_config(), bytes control"); return comp_data_blob_set(cd->model_handler, pos, data_offset_size, fragment, fragment_size); } @@ -262,6 +294,9 @@ static int drc_process(struct processing_module *mod, } } + /* Control pass-though in processing function with switch control */ + cd->enabled = cd->config && cd->config->params.enabled && cd->enable_switch; + cd->drc_func(mod, source, sink, frames); /* calc new free and available */ diff --git a/src/audio/drc/drc.h b/src/audio/drc/drc.h index 667dd1ada0df..01236243359a 100644 --- a/src/audio/drc/drc.h +++ b/src/audio/drc/drc.h @@ -33,6 +33,12 @@ struct comp_dev; #define DRC_DIVISION_FRAMES 32 #define DRC_DIVISION_FRAMES_MASK (DRC_DIVISION_FRAMES - 1) +/* First switch control instance is zero (SOF_IPC4_SWITCH_CONTROL_PARAM_ID), and the + * control is common for all channels. + */ +#define SOF_DRC_CTRL_INDEX_ENABLE_SWITCH 0 +#define SOF_DRC_NUM_ELEMS_ENABLE_SWITCH 1 + /* Stores the state of DRC */ struct drc_state { /* The detector_average is the target gain obtained by looking at the @@ -71,8 +77,10 @@ struct drc_comp_data { struct comp_data_blob_handler *model_handler; struct sof_drc_config *config; /**< pointer to setup blob */ bool config_ready; /**< set when fully received */ + bool enabled; /**< control processing via blob and switch */ + bool enable_switch; /**< enable switch state */ enum sof_ipc_frame source_format; /**< source frame format */ - drc_func drc_func; /**< processing function */ + drc_func drc_func; /**< processing function */ }; struct drc_proc_fnmap { diff --git a/src/audio/drc/drc_generic.c b/src/audio/drc/drc_generic.c index 1d60f6686e09..1ad0c50734a1 100644 --- a/src/audio/drc/drc_generic.c +++ b/src/audio/drc/drc_generic.c @@ -544,7 +544,7 @@ static void drc_s16_default(struct processing_module *mod, int fragment_samples; int fragment; - if (!p->enabled) { + if (!cd->enabled) { /* Delay the input sample only and don't do other processing. This is used when the * DRC is disabled. We want to do this to match the processing delay of other bands * in multi-band DRC kernel case. @@ -690,7 +690,7 @@ static void drc_s24_default(struct processing_module *mod, int fragment_samples; int fragment; - if (!p->enabled) { + if (!cd->enabled) { /* Delay the input sample only and don't do other processing. This is used when the * DRC is disabled. We want to do this to match the processing delay of other bands * in multi-band DRC kernel case. Note: use 32 bit delay function. @@ -738,7 +738,7 @@ static void drc_s32_default(struct processing_module *mod, int fragment_samples; int fragment; - if (!p->enabled) { + if (!cd->enabled) { /* Delay the input sample only and don't do other processing. This is used when the * DRC is disabled. We want to do this to match the processing delay of other bands * in multi-band DRC kernel case. From b79eb20c29bf86433e68e7593b34fde7e856ed5c Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Fri, 10 Nov 2023 11:00:54 +0200 Subject: [PATCH 2/2] Tools: Topology2: Add switch control to topologies with DRC The mixer control for switch is added to widget definition of drc.conf. In cavs-mixin-mixout-efx-hda.conf the existing control name is changed to have "bytes" similarly as multiband-drc has. The switch control is added for the widget to implement the switch. The controls definitions files in benchmark topologies are replaced to new format from current .conf generator script. The bytes control is same as before, and the mixer control for switch is added. Signed-off-by: Seppo Ingalsuo --- .../topology2/cavs-mixin-mixout-efx-hda.conf | 9 +++++++-- .../bench/drc_control_bytes_capture.conf | 10 ---------- .../bench/drc_control_bytes_playback.conf | 10 ---------- .../include/bench/drc_controls_capture.conf | 19 ++++++++++++++++++ .../include/bench/drc_controls_playback.conf | 19 ++++++++++++++++++ .../topology2/include/bench/drc_s16.conf | 4 ++-- .../topology2/include/bench/drc_s24.conf | 4 ++-- .../topology2/include/bench/drc_s32.conf | 4 ++-- .../topology2/include/components/drc.conf | 20 +++++++++++++++++++ 9 files changed, 71 insertions(+), 28 deletions(-) delete mode 100644 tools/topology/topology2/include/bench/drc_control_bytes_capture.conf delete mode 100644 tools/topology/topology2/include/bench/drc_control_bytes_playback.conf create mode 100644 tools/topology/topology2/include/bench/drc_controls_capture.conf create mode 100644 tools/topology/topology2/include/bench/drc_controls_playback.conf diff --git a/tools/topology/topology2/cavs-mixin-mixout-efx-hda.conf b/tools/topology/topology2/cavs-mixin-mixout-efx-hda.conf index 2ce8e2fa2cbd..4a31d27dd740 100644 --- a/tools/topology/topology2/cavs-mixin-mixout-efx-hda.conf +++ b/tools/topology/topology2/cavs-mixin-mixout-efx-hda.conf @@ -56,8 +56,13 @@ Object.Pipeline { } } Object.Widget.drc.1 { - Object.Control.bytes."1" { - name 'Post Mixer $ANALOG_PLAYBACK_PCM DRC' + Object.Control { + bytes."1" { + name 'Post Mixer $ANALOG_PLAYBACK_PCM DRC bytes' + } + mixer."1" { + name 'Post Mixer $ANALOG_PLAYBACK_PCM DRC switch' + } } } } diff --git a/tools/topology/topology2/include/bench/drc_control_bytes_capture.conf b/tools/topology/topology2/include/bench/drc_control_bytes_capture.conf deleted file mode 100644 index f688576394ac..000000000000 --- a/tools/topology/topology2/include/bench/drc_control_bytes_capture.conf +++ /dev/null @@ -1,10 +0,0 @@ - # Created initially with script "./bench_comp_generate.sh drc" - # may need edits to modify controls - Object.Control.bytes."1" { - name '$ANALOG_CAPTURE_PCM DRC bytes' - IncludeByKey.BENCH_DRC_PARAMS { - "default" "include/components/drc/default.conf" - "enabled" "include/components/drc/enabled.conf" - "passthrough" "include/components/drc/passthrough.conf" - } - } diff --git a/tools/topology/topology2/include/bench/drc_control_bytes_playback.conf b/tools/topology/topology2/include/bench/drc_control_bytes_playback.conf deleted file mode 100644 index ce7438e91410..000000000000 --- a/tools/topology/topology2/include/bench/drc_control_bytes_playback.conf +++ /dev/null @@ -1,10 +0,0 @@ - # Created initially with script "./bench_comp_generate.sh drc" - # may need edits to modify controls - Object.Control.bytes."1" { - name '$ANALOG_PLAYBACK_PCM DRC bytes' - IncludeByKey.BENCH_DRC_PARAMS { - "default" "include/components/drc/default.conf" - "enabled" "include/components/drc/enabled.conf" - "passthrough" "include/components/drc/passthrough.conf" - } - } diff --git a/tools/topology/topology2/include/bench/drc_controls_capture.conf b/tools/topology/topology2/include/bench/drc_controls_capture.conf new file mode 100644 index 000000000000..c586f940b578 --- /dev/null +++ b/tools/topology/topology2/include/bench/drc_controls_capture.conf @@ -0,0 +1,19 @@ + # Created initially with script "./bench_comp_generate.sh drc" + # may need edits to modify controls + Object.Control { + # Un-comment the supported controls in DRC + bytes."1" { + name '$ANALOG_CAPTURE_PCM DRC bytes' + IncludeByKey.BENCH_DRC_PARAMS { + "default" "include/components/drc/default.conf" + "enabled" "include/components/drc/enabled.conf" + "passthrough" "include/components/drc/passthrough.conf" + } + } + mixer."1" { + name '$ANALOG_CAPTURE_PCM DRC switch' + } + #enum."1" { + # name '$ANALOG_CAPTURE_PCM DRC enum' + #} + } diff --git a/tools/topology/topology2/include/bench/drc_controls_playback.conf b/tools/topology/topology2/include/bench/drc_controls_playback.conf new file mode 100644 index 000000000000..36217ab08965 --- /dev/null +++ b/tools/topology/topology2/include/bench/drc_controls_playback.conf @@ -0,0 +1,19 @@ + # Created initially with script "./bench_comp_generate.sh drc" + # may need edits to modify controls + Object.Control { + # Un-comment the supported controls in DRC + bytes."1" { + name '$ANALOG_PLAYBACK_PCM DRC bytes' + IncludeByKey.BENCH_DRC_PARAMS { + "default" "include/components/drc/default.conf" + "enabled" "include/components/drc/enabled.conf" + "passthrough" "include/components/drc/passthrough.conf" + } + } + mixer."1" { + name '$ANALOG_PLAYBACK_PCM DRC switch' + } + #enum."1" { + # name '$ANALOG_PLAYBACK_PCM DRC enum' + #} + } diff --git a/tools/topology/topology2/include/bench/drc_s16.conf b/tools/topology/topology2/include/bench/drc_s16.conf index 7d02416c1eac..a91888928d25 100644 --- a/tools/topology/topology2/include/bench/drc_s16.conf +++ b/tools/topology/topology2/include/bench/drc_s16.conf @@ -2,12 +2,12 @@ Object.Widget.drc.1 { index 1 - + } Object.Widget.drc.2 { index 3 - + } diff --git a/tools/topology/topology2/include/bench/drc_s24.conf b/tools/topology/topology2/include/bench/drc_s24.conf index c0d9689a7908..4eb39eef9ad6 100644 --- a/tools/topology/topology2/include/bench/drc_s24.conf +++ b/tools/topology/topology2/include/bench/drc_s24.conf @@ -2,12 +2,12 @@ Object.Widget.drc.1 { index 1 - + } Object.Widget.drc.2 { index 3 - + } diff --git a/tools/topology/topology2/include/bench/drc_s32.conf b/tools/topology/topology2/include/bench/drc_s32.conf index 0ca828c30ec4..beda0c0b210e 100644 --- a/tools/topology/topology2/include/bench/drc_s32.conf +++ b/tools/topology/topology2/include/bench/drc_s32.conf @@ -2,12 +2,12 @@ Object.Widget.drc.1 { index 1 - + } Object.Widget.drc.2 { index 3 - + } diff --git a/tools/topology/topology2/include/components/drc.conf b/tools/topology/topology2/include/components/drc.conf index 055074d3d132..2db857f421a4 100644 --- a/tools/topology/topology2/include/components/drc.conf +++ b/tools/topology/topology2/include/components/drc.conf @@ -53,6 +53,26 @@ Class.Widget."drc" { unique "instance" } + # + # drc widget switch control + # + Object.Control { + mixer."1" { + Object.Base.channel.1 { + name "fc" + shift 0 + } + Object.Base.ops.1 { + name "ctl" + info "volsw" + #259 binds the mixer control to switch get/put handlers + get 259 + put 259 + } + max 1 + } + } + # # Default attributes for drc #