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. 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 #