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
193212err :
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 ;
0 commit comments