diff --git a/src/audio/multiband_drc/multiband_drc.c b/src/audio/multiband_drc/multiband_drc.c index e10b63d28d9a..9a0ba60b5755 100644 --- a/src/audio/multiband_drc/multiband_drc.c +++ b/src/audio/multiband_drc/multiband_drc.c @@ -128,8 +128,34 @@ static int multiband_drc_init_coef(struct processing_module *mod, int16_t nch, u comp_info(dev, "multiband_drc_init_coef(), initializing %i-way crossover", config->num_bands); + /* Combine memory allocations for crossover, emphasis, and deemphasis filter coefficients + * into a single contiguous block to improve memory efficiency. + * thereby reduces heap fragmentation, improves data locality for better cache + * performance, and reduces overhead from separate memory allocations. + */ + size_t total_coefficients_size = sizeof(struct sof_eq_iir_biquad) * + num_bands * nch * 3; + + struct sof_eq_iir_biquad *coefficients_block = + rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, + total_coefficients_size); + + if (!coefficients_block) { + comp_err(dev, "multiband_drc_init_coef(), failed to allocate memory for coefficients"); + return -ENOMEM; + } + + /* Assign pointers to respective positions within the allocated memory block. + * crossover starts at the beginning of the block, + * emphasis follows after the crossover coefficients, + * deemphasis is situated after the emphasis coefficients. + * This ensures all filter coefficients are stored contiguously. + */ + crossover = coefficients_block; + emphasis = coefficients_block + num_bands * nch; + deemphasis = emphasis + num_bands * nch; + /* Crossover: collect the coef array and assign it to every channel */ - crossover = config->crossover_coef; for (ch = 0; ch < nch; ch++) { ret = crossover_init_coef_ch(crossover, &state->crossover[ch], config->num_bands); @@ -137,6 +163,7 @@ static int multiband_drc_init_coef(struct processing_module *mod, int16_t nch, u if (ret < 0) { comp_err(dev, "multiband_drc_init_coef(), could not assign coeffs to ch %d", ch); + rfree(coefficients_block); goto err; } } @@ -144,13 +171,13 @@ static int multiband_drc_init_coef(struct processing_module *mod, int16_t nch, u comp_info(dev, "multiband_drc_init_coef(), initializing emphasis_eq"); /* Emphasis: collect the coef array and assign it to every channel */ - emphasis = config->emp_coef; for (ch = 0; ch < nch; ch++) { ret = multiband_drc_eq_init_coef_ch(emphasis, &state->emphasis[ch]); /* Free all previously allocated blocks in case of an error */ if (ret < 0) { comp_err(dev, "multiband_drc_init_coef(), could not assign coeffs to ch %d", ch); + rfree(coefficients_block); goto err; } } @@ -158,13 +185,13 @@ static int multiband_drc_init_coef(struct processing_module *mod, int16_t nch, u comp_info(dev, "multiband_drc_init_coef(), initializing deemphasis_eq"); /* Deemphasis: collect the coef array and assign it to every channel */ - deemphasis = config->deemp_coef; for (ch = 0; ch < nch; ch++) { ret = multiband_drc_eq_init_coef_ch(deemphasis, &state->deemphasis[ch]); /* Free all previously allocated blocks in case of an error */ if (ret < 0) { comp_err(dev, "multiband_drc_init_coef(), could not assign coeffs to ch %d", ch); + rfree(coefficients_block); goto err; } } @@ -177,6 +204,7 @@ static int multiband_drc_init_coef(struct processing_module *mod, int16_t nch, u if (ret < 0) { comp_err(dev, "multiband_drc_init_coef(), could not init pre delay buffers"); + rfree(coefficients_block); goto err; } @@ -191,6 +219,10 @@ static int multiband_drc_init_coef(struct processing_module *mod, int16_t nch, u return 0; err: + /* Free allocated memory block on error */ + if (coefficients_block) + rfree(coefficients_block); + multiband_drc_reset_state(state); return ret; } @@ -220,7 +252,6 @@ static int multiband_drc_init(struct processing_module *mod) struct module_data *md = &mod->priv; struct comp_dev *dev = mod->dev; struct module_config *cfg = &md->cfg; - struct multiband_drc_comp_data *cd; size_t bs = cfg->size; int ret; @@ -235,9 +266,13 @@ static int multiband_drc_init(struct processing_module *mod) return -EINVAL; } - cd = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*cd)); - if (!cd) + /* Memory allocation for multiband_drc_comp_data */ + struct multiband_drc_comp_data *cd = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, + SOF_MEM_CAPS_RAM, sizeof(*cd)); + if (!cd) { + comp_err(dev, "multiband_drc_init(), allocation for multiband_drc_comp_data failed"); return -ENOMEM; + } md->private = cd; cd->multiband_drc_func = NULL;