[Sound-open-firmware] [PATCH 4/4] IIR EQ: Avoid issue with non-defined number of channels in configuration v2
Seppo Ingalsuo
seppo.ingalsuo at linux.intel.com
Wed Jun 28 12:32:05 CEST 2017
Initialize EQ for max number of channels in configuration or switch
commands to avoid not set number of channels. A return value of -ENOMEM is
propagated in init functions and returned if allocation for memory fails.
Some trace output is added into EQ setup and some comments cleaned and
added.
Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo at linux.intel.com>
---
src/audio/eq_iir.c | 55 +++++++++++++++++++++++++++++++++-----------------
src/audio/eq_iir.h | 2 +-
src/include/uapi/ipc.h | 6 ++++++
3 files changed, 44 insertions(+), 19 deletions(-)
diff --git a/src/audio/eq_iir.c b/src/audio/eq_iir.c
index 8d12895..0f43198 100644
--- a/src/audio/eq_iir.c
+++ b/src/audio/eq_iir.c
@@ -205,7 +205,7 @@ static int eq_iir_setup(struct iir_state_df2t iir[],
/* Allocate all IIR channels data in a big chunk and clear it */
iir_delay = rmalloc(RZONE_RUNTIME, RFLAGS_NONE, size_sum);
if (iir_delay == NULL)
- return -EINVAL;
+ return -ENOMEM;
memset(iir_delay, 0, size_sum);
@@ -226,7 +226,7 @@ static int eq_iir_switch_response(struct iir_state_df2t iir[],
struct eq_iir_configuration *config, struct eq_iir_update *update,
int nch)
{
- int i;
+ int i, ret;
/* Copy assign response from update and re-initilize EQ */
if (config == NULL)
@@ -237,9 +237,9 @@ static int eq_iir_switch_response(struct iir_state_df2t iir[],
config->assign_response[i] = update->assign_response[i];
}
- eq_iir_setup(iir, config, nch);
+ ret = eq_iir_setup(iir, config, nch);
- return 0;
+ return ret;
}
/*
@@ -312,19 +312,26 @@ static int eq_iir_cmd(struct comp_dev *dev, int cmd, void *data)
{
trace_eq_iir("ECm");
struct comp_data *cd = comp_get_drvdata(dev);
- struct comp_buffer *source = list_first_item(&dev->bsource_list,
- struct comp_buffer, sink_list);
struct sof_ipc_eq_iir_switch *assign;
struct sof_ipc_eq_iir_blob *blob;
+ struct eq_iir_update *iir_update;
int i;
+ int ret = 0;
size_t bs;
+
switch (cmd) {
case COMP_CMD_EQ_IIR_SWITCH:
trace_eq_iir("EFx");
assign = (struct sof_ipc_eq_iir_switch *) data;
- eq_iir_switch_response(cd->iir, cd->config,
- (struct eq_iir_update *) assign->data,
- source->params.pcm->channels);
+ iir_update = (struct eq_iir_update *) assign->data;
+ ret = eq_iir_switch_response(cd->iir, cd->config,
+ iir_update, PLATFORM_MAX_CHANNELS);
+
+ /* Print trace information */
+ tracev_value(iir_update->stream_max_channels);
+ for (i = 0; i < iir_update->stream_max_channels; i++)
+ tracev_value(iir_update->assign_response[i]);
+
break;
case COMP_CMD_EQ_IIR_CONFIG:
trace_eq_iir("EFc");
@@ -333,7 +340,8 @@ static int eq_iir_cmd(struct comp_dev *dev, int cmd, void *data)
/* Copy new config, need to decode data to know the size */
blob = (struct sof_ipc_eq_iir_blob *) data;
- bs = blob->comp.hdr.size - sizeof(struct sof_ipc_hdr);
+ bs = blob->comp.hdr.size - sizeof(struct sof_ipc_hdr)
+ - sizeof(struct sof_ipc_host_buffer);
if (bs > EQ_IIR_MAX_BLOB_SIZE)
return -EINVAL;
@@ -343,7 +351,16 @@ static int eq_iir_cmd(struct comp_dev *dev, int cmd, void *data)
return -EINVAL;
memcpy(cd->config, blob->data, bs);
- eq_iir_setup(cd->iir, cd->config, source->params.pcm->channels);
+ /* Initialize all channels, the actual number of channels may
+ * not be set yet. */
+ ret = eq_iir_setup(cd->iir, cd->config, PLATFORM_MAX_CHANNELS);
+
+ /* Print trace information */
+ tracev_value(cd->config->stream_max_channels);
+ tracev_value(cd->config->number_of_responses_defined);
+ for (i = 0; i < cd->config->stream_max_channels; i++)
+ tracev_value(cd->config->assign_response[i]);
+
break;
case COMP_CMD_MUTE:
trace_eq_iir("EFm");
@@ -386,7 +403,7 @@ static int eq_iir_cmd(struct comp_dev *dev, int cmd, void *data)
break;
}
- return 0;
+ return ret;
}
/* copy and process stream data from source to sink buffers */
@@ -409,9 +426,6 @@ static int eq_iir_copy(struct comp_dev *dev)
/* Check that source has enough frames available and that sink has
* enough frames free.
*/
- //frames = source->params.period_frames;
- //need_source = frames * source->params.frame_size;
- //need_sink = frames * sink->params.frame_size;
frames = source->params.pcm->period_count;
need_source = frames * source->params.pcm->frame_size;
need_sink = frames * sink->params.pcm->frame_size;
@@ -427,19 +441,24 @@ static int eq_iir_prepare(struct comp_dev *dev)
{
struct comp_data *cd = comp_get_drvdata(dev);
struct comp_buffer *source;
+ int ret;
trace_eq_iir("EPp");
cd->eq_iir_func = eq_iir_s32_default;
- /* Initialize EQ */
+ /* Initialize EQ. Note that if EQ has not received command to
+ * configure the response the EQ prepare returns an error that
+ * interrupts pipeline prepare for downstream.
+ */
if (cd->config == NULL)
return -EINVAL;
source = list_first_item(&dev->bsource_list, struct comp_buffer,
sink_list);
- if (eq_iir_setup(cd->iir, cd->config, source->params.pcm->channels) < 0)
- return -EINVAL;
+ ret = eq_iir_setup(cd->iir, cd->config, source->params.pcm->channels);
+ if (ret < 0)
+ return ret;
//dev->preload = PLAT_INT_PERIODS;
dev->state = COMP_STATE_PREPARE;
diff --git a/src/audio/eq_iir.h b/src/audio/eq_iir.h
index 2634986..42d95c1 100644
--- a/src/audio/eq_iir.h
+++ b/src/audio/eq_iir.h
@@ -64,7 +64,7 @@
* {0, 0, 0, 0, 1073741824, 0, 16484}
*/
-#define EQ_IIR_MAX_BLOB_SIZE 1024
+#define EQ_IIR_MAX_BLOB_SIZE 1024 /* In bytes or size_t */
#define NHEADER_EQ_IIR_BLOB 2 /* Blob is two words plus asssigns plus coef */
diff --git a/src/include/uapi/ipc.h b/src/include/uapi/ipc.h
index db7a8bb..ea9d1c6 100644
--- a/src/include/uapi/ipc.h
+++ b/src/include/uapi/ipc.h
@@ -517,6 +517,12 @@ struct sof_ipc_comp_eq_fir {
struct sof_ipc_pcm_comp pcm;
} __attribute__((packed));
+/* IIR equalizer component */
+struct sof_ipc_comp_eq_iir {
+ struct sof_ipc_comp comp;
+ struct sof_ipc_pcm_comp pcm;
+} __attribute__((packed));
+
/* IPC to pass configuration blobs to equalizers and re-assign responses */
struct sof_ipc_eq_fir_blob {
struct sof_ipc_comp comp;
--
2.11.0
More information about the Sound-open-firmware
mailing list