Skip to content

Commit b5919ce

Browse files
Audio: MDRC: Restructure MDRC for effective memory allocation
This check-in attempts to decrease memory allocation overhead, enhance cache efficiency through data locality, and lessen heap fragmentation. Within the MDRC component, combine memory allocations for the crossover, emphasis, and deemphasis filter coefficients into a single block. By streamlining memory management, the update lowers the possibility of memory leaks. Signed-off-by: Shriram Shastry <malladi.sastry@intel.com>
1 parent 2f3f877 commit b5919ce

2 files changed

Lines changed: 99 additions & 48 deletions

File tree

src/audio/multiband_drc/multiband_drc.c

Lines changed: 85 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <sof/ut.h>
2929
#include <user/eq.h>
3030
#include <user/trace.h>
31+
#include <stdbool.h>
3132
#include <errno.h>
3233
#include <stddef.h>
3334
#include <stdint.h>
@@ -94,17 +95,45 @@ static int multiband_drc_eq_init_coef_ch(struct sof_eq_iir_biquad *coef,
9495
return 0;
9596
}
9697

97-
static int multiband_drc_init_coef(struct processing_module *mod, int16_t nch, uint32_t rate)
98+
/**
99+
* @Description Initialize coefficients for multiband DRC processing.
100+
*
101+
* Allocates and initializes filter coefficients for the multiband DRC module. Memory
102+
* for the crossover, emphasis, and de-emphasis filter coefficients is allocated within
103+
* a contiguous block if not previously done. The function checks for configuration
104+
* validity and adheres to predefined channel and band count limits.
105+
*
106+
* The memory layout for the coefficients_block is as follows:
107+
* @code
108+
* +-----------------------------------+
109+
* | coefficients_block |
110+
* +-----------------------------------+
111+
* | crossover_coef | num_bands * nch * sizeof(struct sof_eq_iir_biquad)
112+
* +-----------------------------------+ <-- offset for emp_coef (crossover_coef + num_bands * nch)
113+
* | emp_coef | num_bands * nch * sizeof(struct sof_eq_iir_biquad)
114+
* +-----------------------------------+ <-- offset for deemp_coef (emp_coef + num_bands * nch)
115+
* | deemp_coef | num_bands * nch * sizeof(struct sof_eq_iir_biquad)
116+
* +-----------------------------------+
117+
* @endcode
118+
*
119+
* @parameters mod Pointer to the processing module containing multiband DRC data.
120+
* @parameters nch Number of channels to process, up to PLATFORM_MAX_CHANNELS.
121+
* @parameters rate Sampling rate, not used in current implementation.
122+
*
123+
* @return 0 on success or a negative error code on failure (e.g., invalid configuration,
124+
* memory allocation failure).
125+
*/
126+
127+
static int multiband_drc_init_coef(struct processing_module *mod,
128+
int16_t nch, uint32_t rate)
98129
{
99130
struct comp_dev *dev = mod->dev;
100131
struct multiband_drc_comp_data *cd = module_get_private_data(mod);
101-
struct sof_eq_iir_biquad *crossover;
102-
struct sof_eq_iir_biquad *emphasis;
103-
struct sof_eq_iir_biquad *deemphasis;
104132
struct sof_multiband_drc_config *config = cd->config;
105133
struct multiband_drc_state *state = &cd->state;
106134
uint32_t sample_bytes = get_sample_bytes(cd->source_format);
107135
int i, ch, ret, num_bands;
136+
bool alloc_success = false;
108137

109138
if (!config) {
110139
comp_err(dev, "multiband_drc_init_coef(), no config is set");
@@ -113,75 +142,65 @@ static int multiband_drc_init_coef(struct processing_module *mod, int16_t nch, u
113142

114143
num_bands = config->num_bands;
115144

116-
/* Sanity checks */
117-
if (nch > PLATFORM_MAX_CHANNELS) {
118-
comp_err(dev,
119-
"multiband_drc_init_coef(), invalid channels count(%i)", nch);
120-
return -EINVAL;
121-
}
122-
if (config->num_bands > SOF_MULTIBAND_DRC_MAX_BANDS) {
123-
comp_err(dev, "multiband_drc_init_coef(), invalid bands count(%i)",
124-
config->num_bands);
145+
if (nch > PLATFORM_MAX_CHANNELS || num_bands > SOF_MULTIBAND_DRC_MAX_BANDS) {
146+
comp_err(dev, "Invalid ch count(%i) or band count(%i)", nch, num_bands);
125147
return -EINVAL;
126148
}
127149

128150
comp_info(dev, "multiband_drc_init_coef(), initializing %i-way crossover",
129-
config->num_bands);
151+
num_bands);
152+
153+
/* Allocation for coefficients_block */
154+
if (!cd->coefficients_block) {
155+
cd->coefficients_block = rballoc(0, SOF_MEM_CAPS_RAM,
156+
sizeof(struct multiband_drc_coefficients));
157+
if (!cd->coefficients_block) {
158+
comp_err(dev, "Failed to allocate coeff block multiband_drc_init_coef()");
159+
return -ENOMEM;
160+
}
161+
alloc_success = true; /* Allocation was successful */
162+
}
163+
struct multiband_drc_coefficients *coefficients_block = cd->coefficients_block;
164+
165+
/* Crossover, Emphasis, and Deemphasis EQ initialization for each channel */
166+
struct sof_eq_iir_biquad *crossover, *emphasis, *deemphasis;
130167

131-
/* Crossover: collect the coef array and assign it to every channel */
132-
crossover = config->crossover_coef;
133168
for (ch = 0; ch < nch; ch++) {
134-
ret = crossover_init_coef_ch(crossover, &state->crossover[ch],
135-
config->num_bands);
136-
/* Free all previously allocated blocks in case of an error */
169+
crossover = coefficients_block->crossover + ch * num_bands;
170+
emphasis = coefficients_block->emphasis + ch * num_bands;
171+
deemphasis = coefficients_block->deemphasis + ch * num_bands;
172+
173+
ret = crossover_init_coef_ch(crossover, &state->crossover[ch], num_bands);
137174
if (ret < 0) {
138-
comp_err(dev,
139-
"multiband_drc_init_coef(), could not assign coeffs to ch %d", ch);
175+
comp_err(dev, "Can't assign xover coeffs to ch %d", ch);
140176
goto err;
141177
}
142-
}
143178

144-
comp_info(dev, "multiband_drc_init_coef(), initializing emphasis_eq");
145-
146-
/* Emphasis: collect the coef array and assign it to every channel */
147-
emphasis = config->emp_coef;
148-
for (ch = 0; ch < nch; ch++) {
149179
ret = multiband_drc_eq_init_coef_ch(emphasis, &state->emphasis[ch]);
150-
/* Free all previously allocated blocks in case of an error */
151180
if (ret < 0) {
152-
comp_err(dev, "multiband_drc_init_coef(), could not assign coeffs to ch %d",
153-
ch);
181+
comp_err(dev, "Can't assign emp coeffs to ch %d", ch);
154182
goto err;
155183
}
156-
}
157-
158-
comp_info(dev, "multiband_drc_init_coef(), initializing deemphasis_eq");
159184

160-
/* Deemphasis: collect the coef array and assign it to every channel */
161-
deemphasis = config->deemp_coef;
162-
for (ch = 0; ch < nch; ch++) {
163185
ret = multiband_drc_eq_init_coef_ch(deemphasis, &state->deemphasis[ch]);
164-
/* Free all previously allocated blocks in case of an error */
165186
if (ret < 0) {
166-
comp_err(dev, "multiband_drc_init_coef(), could not assign coeffs to ch %d",
167-
ch);
187+
comp_err(dev, "Can't assign deemp coeffs to ch %d", ch);
168188
goto err;
169189
}
170190
}
171191

172-
/* Allocate all DRC pre-delay buffers and set delay time with band number */
192+
/* Initialize DRC state for each band */
173193
for (i = 0; i < num_bands; i++) {
174194
comp_info(dev, "multiband_drc_init_coef(), initializing drc band %d", i);
175195

176-
ret = drc_init_pre_delay_buffers(&state->drc[i], (size_t)sample_bytes, (int)nch);
196+
ret = drc_init_pre_delay_buffers(&state->drc[i], sample_bytes, nch);
177197
if (ret < 0) {
178-
comp_err(dev,
179-
"multiband_drc_init_coef(), could not init pre delay buffers");
198+
comp_err(dev, "multiband_drc_init_coef(), could not init pre delay buffers");
180199
goto err;
181200
}
182201

183202
ret = drc_set_pre_delay_time(&state->drc[i],
184-
cd->config->drc_coef[i].pre_delay_time, rate);
203+
config->drc_coef[i].pre_delay_time, rate);
185204
if (ret < 0) {
186205
comp_err(dev, "multiband_drc_init_coef(), could not set pre delay time");
187206
goto err;
@@ -191,6 +210,10 @@ static int multiband_drc_init_coef(struct processing_module *mod, int16_t nch, u
191210
return 0;
192211

193212
err:
213+
if (alloc_success && ret < 0) {
214+
rfree(cd->coefficients_block);
215+
cd->coefficients_block = NULL;
216+
}
194217
multiband_drc_reset_state(state);
195218
return ret;
196219
}
@@ -220,7 +243,6 @@ static int multiband_drc_init(struct processing_module *mod)
220243
struct module_data *md = &mod->priv;
221244
struct comp_dev *dev = mod->dev;
222245
struct module_config *cfg = &md->cfg;
223-
struct multiband_drc_comp_data *cd;
224246
size_t bs = cfg->size;
225247
int ret;
226248

@@ -235,9 +257,13 @@ static int multiband_drc_init(struct processing_module *mod)
235257
return -EINVAL;
236258
}
237259

238-
cd = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*cd));
239-
if (!cd)
260+
/* Memory allocation for multiband_drc_comp_data */
261+
struct multiband_drc_comp_data *cd = rzalloc(SOF_MEM_ZONE_RUNTIME, 0,
262+
SOF_MEM_CAPS_RAM, sizeof(*cd));
263+
if (!cd) {
264+
comp_err(dev, "multiband_drc_init(), allocation for multiband_drc_comp_data failed");
240265
return -ENOMEM;
266+
}
241267

242268
md->private = cd;
243269
cd->multiband_drc_func = NULL;
@@ -279,7 +305,18 @@ static int multiband_drc_free(struct processing_module *mod)
279305

280306
comp_info(mod->dev, "multiband_drc_free()");
281307

282-
comp_data_blob_handler_free(cd->model_handler);
308+
if (cd) {
309+
struct multiband_drc_state *state = &cd->state;
310+
311+
/* Free emphasis/deemphasis IIR filter states for all channels */
312+
for (int i = 0; i < PLATFORM_MAX_CHANNELS; i++) {
313+
multiband_drc_iir_reset_state_ch(&state->emphasis[i]);
314+
multiband_drc_iir_reset_state_ch(&state->deemphasis[i]);
315+
}
316+
317+
/* Freeing other resources as part of the component data */
318+
comp_data_blob_handler_free(cd->model_handler);
319+
}
283320

284321
rfree(cd);
285322
return 0;

src/audio/multiband_drc/multiband_drc.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@
2121
/**
2222
* Stores the state of the sub-components in Multiband DRC
2323
*/
24+
struct multiband_drc_coefficients {
25+
struct sof_eq_iir_biquad crossover[SOF_MULTIBAND_DRC_MAX_BANDS * PLATFORM_MAX_CHANNELS];
26+
struct sof_eq_iir_biquad emphasis[SOF_MULTIBAND_DRC_MAX_BANDS * PLATFORM_MAX_CHANNELS];
27+
struct sof_eq_iir_biquad deemphasis[SOF_MULTIBAND_DRC_MAX_BANDS * PLATFORM_MAX_CHANNELS];
28+
} __packed;
29+
2430
struct multiband_drc_state {
2531
struct iir_state_df2t emphasis[PLATFORM_MAX_CHANNELS];
2632
struct crossover_state crossover[PLATFORM_MAX_CHANNELS];
@@ -38,6 +44,14 @@ struct multiband_drc_comp_data {
3844
struct multiband_drc_state state; /**< compressor state */
3945
struct comp_data_blob_handler *model_handler;
4046
struct sof_multiband_drc_config *config; /**< pointer to setup blob */
47+
/**
48+
* Pointer to the coefficients of the filters used in multiband DRC processing
49+
* which includes crossover, emphasis, and deemphasis filters. These coefficients
50+
* are used by the processing functions and are allocated during the initialization
51+
* phase. This allows efficient access to filter parameters required for audio
52+
* processing across all channels and bands.
53+
*/
54+
struct multiband_drc_coefficients *coefficients_block; /**< Filter coefficients */
4155
bool config_ready; /**< set when fully received */
4256
enum sof_ipc_frame source_format; /**< source frame format */
4357
bool process_enabled; /**< true if component is enabled */

0 commit comments

Comments
 (0)