Skip to content

Commit 6d8a397

Browse files
committed
EQ IIR: Change initialization and simplify dcache invalididate function
This patch changes equalizer initialization to store the allocated delay lines buffers address in a single pointer and size component data. This simplifies the dcache invalidate code avoids knowledge of filter internals that may change for future intrinsic optimized version. The EQ reconfigure and responses switching is by this patch changed to happen in prepare() to avoid doing unnecessary allocation and free operations in typical component life cycle. Prior to to prepare sent configuration is just stored but not initialized into equalizers. On-the-fly response switching can be enabled later with some work for the component. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent 318176f commit 6d8a397

1 file changed

Lines changed: 53 additions & 66 deletions

File tree

src/audio/eq_iir.c

Lines changed: 53 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,11 @@
5959

6060
/* IIR component private data */
6161
struct comp_data {
62+
struct iir_state_df2t iir[PLATFORM_MAX_CHANNELS];
6263
struct sof_eq_iir_config *config;
6364
uint32_t period_bytes;
64-
struct iir_state_df2t iir[PLATFORM_MAX_CHANNELS];
65+
int64_t *iir_delay;
66+
size_t iir_delay_size;
6567
void (*eq_iir_func)(struct comp_dev *dev,
6668
struct comp_buffer *source,
6769
struct comp_buffer *sink,
@@ -119,28 +121,24 @@ static void eq_iir_free_parameters(struct sof_eq_iir_config **config)
119121
*config = NULL;
120122
}
121123

122-
static void eq_iir_free_delaylines(struct iir_state_df2t *iir)
124+
static void eq_iir_free_delaylines(struct comp_data *cd)
123125
{
126+
struct iir_state_df2t *iir = cd->iir;
124127
int i = 0;
125-
int64_t *delay = NULL;
126128

127-
/* 1st active EQ delay line data is at beginning of the single
128-
* allocated buffer
129+
/* Free the common buffer for all EQs and point then
130+
* each IIR channel delay line to NULL.
129131
*/
130-
for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) {
131-
if (iir[i].delay && !delay)
132-
delay = iir[i].delay;
133-
134-
/* Point all delays to NULL to avoid duplicated free later */
132+
rfree(cd->iir_delay);
133+
cd->iir_delay_size = 0;
134+
for (i = 0; i < PLATFORM_MAX_CHANNELS; i++)
135135
iir[i].delay = NULL;
136-
}
137-
138-
rfree(delay); /* Check for null is done in rfree() */
139136
}
140137

141-
static int eq_iir_setup(struct iir_state_df2t iir[],
142-
struct sof_eq_iir_config *config, int nch)
138+
static int eq_iir_setup(struct comp_data *cd, int nch)
143139
{
140+
struct iir_state_df2t *iir = cd->iir;
141+
struct sof_eq_iir_config *config = cd->config;
144142
struct sof_eq_iir_header_df2t *lookup[SOF_EQ_IIR_MAX_RESPONSES];
145143
struct sof_eq_iir_header_df2t *eq;
146144
int64_t *iir_delay;
@@ -152,7 +150,7 @@ static int eq_iir_setup(struct iir_state_df2t iir[],
152150
int resp;
153151

154152
/* Free existing IIR channels data if it was allocated */
155-
eq_iir_free_delaylines(iir);
153+
eq_iir_free_delaylines(cd);
156154

157155
trace_eq("fse");
158156
trace_value(config->channels_in_config);
@@ -223,17 +221,19 @@ static int eq_iir_setup(struct iir_state_df2t iir[],
223221
/* If all channels were set to bypass there's no need to
224222
* allocate delay. Just return with success.
225223
*/
224+
cd->iir_delay = NULL;
225+
cd->iir_delay_size = size_sum;
226226
if (!size_sum)
227227
return 0;
228-
229228
/* Allocate all IIR channels data in a big chunk and clear it */
230-
iir_delay = rzalloc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM, size_sum);
231-
if (!iir_delay)
229+
cd->iir_delay = rzalloc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM, size_sum);
230+
if (!cd->iir_delay)
232231
return -ENOMEM;
233232

234-
memset(iir_delay, 0, size_sum);
233+
memset(cd->iir_delay, 0, size_sum);
235234

236235
/* Initialize 2nd phase to set EQ delay lines pointers */
236+
iir_delay = cd->iir_delay;
237237
for (i = 0; i < nch; i++) {
238238
resp = assign_response[i];
239239
if (resp >= 0)
@@ -242,20 +242,19 @@ static int eq_iir_setup(struct iir_state_df2t iir[],
242242
return 0;
243243
}
244244

245-
static int eq_iir_switch_response(struct iir_state_df2t iir[],
246-
struct sof_eq_iir_config *config,
247-
uint32_t ch, int32_t response)
245+
static int eq_iir_switch_store(struct iir_state_df2t iir[],
246+
struct sof_eq_iir_config *config,
247+
uint32_t ch, int32_t response)
248248
{
249-
int ret;
250-
251-
/* Copy assign response from update and re-initialize EQ */
252-
if (!config || ch >= PLATFORM_MAX_CHANNELS)
249+
/* Copy assign response from update. The EQ is initialized later
250+
* when all channels have been updated.
251+
*/
252+
if (!config || ch >= config->channels_in_config)
253253
return -EINVAL;
254254

255255
config->data[ch] = response;
256-
ret = eq_iir_setup(iir, config, PLATFORM_MAX_CHANNELS);
257256

258-
return ret;
257+
return 0;
259258
}
260259

261260
/*
@@ -284,8 +283,9 @@ static struct comp_dev *eq_iir_new(struct sof_ipc_comp *comp)
284283
}
285284

286285
comp_set_drvdata(dev, cd);
287-
288286
cd->eq_iir_func = eq_iir_passthrough;
287+
cd->iir_delay = NULL;
288+
cd->iir_delay_size = 0;
289289
cd->config = NULL;
290290
for (i = 0; i < PLATFORM_MAX_CHANNELS; i++)
291291
iir_reset_df2t(&cd->iir[i]);
@@ -300,7 +300,7 @@ static void eq_iir_free(struct comp_dev *dev)
300300

301301
trace_eq("fre");
302302

303-
eq_iir_free_delaylines(cd->iir);
303+
eq_iir_free_delaylines(cd);
304304
eq_iir_free_parameters(&cd->config);
305305

306306
rfree(cd);
@@ -396,10 +396,10 @@ static int iir_cmd_set_data(struct comp_dev *dev,
396396
for (i = 0; i < (int)cdata->num_elems; i++) {
397397
tracev_value(compv[i].index);
398398
tracev_value(compv[i].svalue);
399-
ret = eq_iir_switch_response(cd->iir,
400-
cd->config,
401-
compv[i].index,
402-
compv[i].svalue);
399+
ret = eq_iir_switch_store(cd->iir,
400+
cd->config,
401+
compv[i].index,
402+
compv[i].svalue);
403403
if (ret < 0) {
404404
trace_eq_error("esw");
405405
return -EINVAL;
@@ -433,19 +433,11 @@ static int iir_cmd_set_data(struct comp_dev *dev,
433433
if (!cd->config)
434434
return -EINVAL;
435435

436+
/* Just copy the configurate. The EQ will be initialized in
437+
* prepare().
438+
*/
436439
memcpy(cd->config, cdata->data->data, bs);
437440

438-
/* Initialize all channels, the actual number of channels may
439-
* not be set yet.
440-
*/
441-
ret = eq_iir_setup(cd->iir, cd->config, PLATFORM_MAX_CHANNELS);
442-
if (ret == 0) {
443-
cd->eq_iir_func = eq_iir_s32_default;
444-
trace_eq("iok");
445-
} else {
446-
cd->eq_iir_func = eq_iir_passthrough;
447-
trace_eq_error("eis");
448-
}
449441
break;
450442
default:
451443
trace_eq_error("esd");
@@ -471,6 +463,12 @@ static int eq_iir_cmd(struct comp_dev *dev, int cmd, void *data)
471463
case COMP_CMD_GET_DATA:
472464
ret = iir_cmd_get_data(dev, cdata);
473465
break;
466+
case COMP_CMD_SET_VALUE:
467+
trace_eq("isv");
468+
break;
469+
case COMP_CMD_GET_VALUE:
470+
trace_eq("igv");
471+
break;
474472
default:
475473
trace_eq_error("ecm");
476474
ret = -EINVAL;
@@ -535,7 +533,7 @@ static int eq_iir_prepare(struct comp_dev *dev)
535533
/* Initialize EQ */
536534
cd->eq_iir_func = eq_iir_passthrough;
537535
if (cd->config) {
538-
ret = eq_iir_setup(cd->iir, cd->config, dev->params.channels);
536+
ret = eq_iir_setup(cd, dev->params.channels);
539537
if (ret < 0) {
540538
comp_set_state(dev, COMP_TRIGGER_RESET);
541539
return ret;
@@ -553,7 +551,7 @@ static int eq_iir_reset(struct comp_dev *dev)
553551

554552
trace_eq("res");
555553

556-
eq_iir_free_delaylines(cd->iir);
554+
eq_iir_free_delaylines(cd);
557555
eq_iir_free_parameters(&cd->config);
558556

559557
cd->eq_iir_func = eq_iir_s32_default;
@@ -566,25 +564,19 @@ static int eq_iir_reset(struct comp_dev *dev)
566564

567565
static void eq_iir_cache(struct comp_dev *dev, int cmd)
568566
{
569-
struct comp_data *cd;
570-
int i;
567+
struct comp_data *cd = comp_get_drvdata(dev);
571568

572569
switch (cmd) {
573570
case COMP_CACHE_WRITEBACK_INV:
574571
trace_eq("wtb");
575572

576-
cd = comp_get_drvdata(dev);
577-
578573
if (cd->config)
579574
dcache_writeback_invalidate_region(cd->config,
580575
cd->config->size);
581576

582-
for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) {
583-
if (cd->iir[i].delay)
584-
dcache_writeback_invalidate_region
585-
(cd->iir[i].delay,
586-
2 * cd->iir[i].biquads * sizeof(int64_t));
587-
}
577+
if (cd->iir_delay)
578+
dcache_writeback_invalidate_region(cd->iir_delay,
579+
cd->iir_delay_size);
588580

589581
dcache_writeback_invalidate_region(cd, sizeof(*cd));
590582
dcache_writeback_invalidate_region(dev, sizeof(*dev));
@@ -594,16 +586,11 @@ static void eq_iir_cache(struct comp_dev *dev, int cmd)
594586
trace_eq("inv");
595587

596588
dcache_invalidate_region(dev, sizeof(*dev));
597-
598-
cd = comp_get_drvdata(dev);
599589
dcache_invalidate_region(cd, sizeof(*cd));
600590

601-
for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) {
602-
if (cd->iir[i].delay)
603-
dcache_invalidate_region
604-
(cd->iir[i].delay,
605-
2 * cd->iir[i].biquads * sizeof(int64_t));
606-
}
591+
if (cd->iir_delay)
592+
dcache_invalidate_region(cd->iir_delay,
593+
cd->iir_delay_size);
607594

608595
if (cd->config)
609596
dcache_invalidate_region(cd->config,

0 commit comments

Comments
 (0)