Skip to content

Commit

Permalink
Audio: DRC: Add processing enable switch control
Browse files Browse the repository at this point in the history
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 <seppo.ingalsuo@linux.intel.com>
  • Loading branch information
singalsu committed Dec 20, 2023
1 parent 486ccfe commit a8bd16a
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 6 deletions.
39 changes: 37 additions & 2 deletions src/audio/drc/drc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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);
}
Expand Down Expand Up @@ -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 */
Expand Down
10 changes: 9 additions & 1 deletion src/audio/drc/drc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down
6 changes: 3 additions & 3 deletions src/audio/drc/drc_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit a8bd16a

Please sign in to comment.