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 18, 2023
1 parent 33ef5f6 commit b029051
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 6 deletions.
44 changes: 42 additions & 2 deletions src/audio/drc/drc.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,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 @@ -202,15 +209,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()");

#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;
}

comp_info(mod->dev, "drc_set_config()");
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 All @@ -235,6 +267,11 @@ static void drc_set_alignment(struct audio_stream *source,
audio_stream_init_alignment_constants(1, 1, sink);
}

static bool drc_get_config_enabled(struct drc_comp_data *cd)
{
return cd->config && cd->config->params.enabled;
}

static int drc_process(struct processing_module *mod,
struct input_stream_buffer *input_buffers,
int num_input_buffers,
Expand All @@ -261,6 +298,9 @@ static int drc_process(struct processing_module *mod,
}
}

/* Control pass-though in processing function with switch control */
cd->enabled = drc_get_config_enabled(cd) && cd->enable_switch;

cd->drc_func(mod, source, sink, frames);

/* calc new free and available */
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 @@ -543,7 +543,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 @@ -689,7 +689,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 @@ -737,7 +737,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
10 changes: 9 additions & 1 deletion src/include/sof/audio/drc/drc.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,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 @@ -70,8 +76,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

0 comments on commit b029051

Please sign in to comment.