[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