[Sound-open-firmware] [PATCH 2/2] comp: buffer size: Add resize support for SRC, EQ and DAI

Liam Girdwood liam.r.girdwood at linux.intel.com
Thu Sep 7 16:35:07 CEST 2017


Make SRC, EQ and DAI use the new buffer size and reset position API
calls rather than manually resetting and sizing the buffer.

Signed-off-by: Liam Girdwood <liam.r.girdwood at linux.intel.com>
---
 src/audio/dai.c    | 24 +++++++++++-------------
 src/audio/eq_fir.c | 16 ++++++++++++++--
 src/audio/eq_iir.c | 16 ++++++++++++++--
 src/audio/src.c    | 21 +++++++++++++++++----
 4 files changed, 56 insertions(+), 21 deletions(-)

diff --git a/src/audio/dai.c b/src/audio/dai.c
index 30d3ae9..358ad2d 100644
--- a/src/audio/dai.c
+++ b/src/audio/dai.c
@@ -206,7 +206,7 @@ static int dai_playback_params(struct comp_dev *dev)
 	struct dma_sg_elem *elem;
 	struct comp_buffer *dma_buffer;
 	struct list_item *elist, *tlist;
-	int i;
+	int i, err;
 	uint32_t buffer_size;
 
 	/* set up DMA configuration */
@@ -223,15 +223,14 @@ static int dai_playback_params(struct comp_dev *dev)
 	buffer_size = source_config->periods_sink * dd->period_bytes;
 
 	/* resize the buffer if space is available to align with period size */
-	if (buffer_size == 0 || buffer_size > dma_buffer->alloc_size) {
+	err = buffer_set_size(dma_buffer, buffer_size);
+	if (err < 0) {
 		trace_dai_error("ep1");
 		trace_value(source_config->periods_sink);
 		trace_value(dd->period_bytes);
 		trace_value(buffer_size);
 		trace_value(dma_buffer->alloc_size);
-		return -EINVAL;
-	} else {
-		dma_buffer->size = buffer_size;
+		return err;
 	}
 
 	if (list_is_empty(&config->elem_list)) {
@@ -253,7 +252,7 @@ static int dai_playback_params(struct comp_dev *dev)
 	}
 
 	/* set write pointer to start of buffer */
-	dma_buffer->w_ptr = dma_buffer->addr;
+	buffer_reset_pos(dma_buffer);
 
 	return 0;
 
@@ -275,7 +274,7 @@ static int dai_capture_params(struct comp_dev *dev)
 	struct dma_sg_elem *elem;
 	struct comp_buffer *dma_buffer;
 	struct list_item *elist, *tlist;
-	int i;
+	int i, err;
 	uint32_t buffer_size;
 
 	/* set up DMA configuration */
@@ -292,15 +291,14 @@ static int dai_capture_params(struct comp_dev *dev)
 	buffer_size = sink_config->periods_source * dd->period_bytes;
 
 	/* resize the buffer if space is available to align with period size */
-	if (buffer_size == 0 || buffer_size > dma_buffer->alloc_size) {
+	err = buffer_set_size(dma_buffer, buffer_size);
+	if (err < 0) {
 		trace_dai_error("ec1");
 		trace_value(sink_config->periods_sink);
 		trace_value(dd->period_bytes);
 		trace_value(buffer_size);
 		trace_value(dma_buffer->alloc_size);
-		return -EINVAL;
-	} else {
-		dma_buffer->size = buffer_size;
+		return err;
 	}
 
 	if (list_is_empty(&config->elem_list)) {
@@ -319,8 +317,8 @@ static int dai_capture_params(struct comp_dev *dev)
 		}
 	}
 
-	/* set write pointer to start of buffer */
-	dma_buffer->r_ptr = dma_buffer->addr;
+	/* set read pointer to start of buffer */
+	buffer_reset_pos(dma_buffer);
 
 	return 0;
 
diff --git a/src/audio/eq_fir.c b/src/audio/eq_fir.c
index 98cd43e..ef3b7d2 100644
--- a/src/audio/eq_fir.c
+++ b/src/audio/eq_fir.c
@@ -110,10 +110,10 @@ static void eq_fir_s32_default(struct comp_dev *dev,
 				/* Check both source and destination for wrap */
 				if (x > (int32_t *) source->end_addr)
 					x = (int32_t *)
-					((size_t) x - source->alloc_size);
+					((size_t) x - source->size);
 				if (snk > (int32_t *) sink->end_addr)
 					y = (int32_t *)
-					((size_t) y - sink->alloc_size);
+					((size_t) y - sink->size);
 			}
 		}
 
@@ -286,12 +286,24 @@ static int eq_fir_params(struct comp_dev *dev)
 {
 	struct comp_data *cd = comp_get_drvdata(dev);
 	struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev);
+	struct comp_buffer *sink;
+	int err;
 
 	trace_src("par");
 
 	/* calculate period size based on config */
 	cd->period_bytes = dev->frames * dev->frame_bytes;
 
+	/* configure downstream buffer */
+	sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list);
+	err = buffer_set_size(sink, cd->period_bytes * config->periods_sink);
+	if (err < 0) {
+		trace_src_error("eSz");
+		return err;
+	}
+
+	buffer_reset_pos(sink);
+
 	/* EQ supports only S32_LE PCM format */
 	if (config->frame_fmt != SOF_IPC_FRAME_S32_LE)
 		return -EINVAL;
diff --git a/src/audio/eq_iir.c b/src/audio/eq_iir.c
index f75be71..66a613c 100644
--- a/src/audio/eq_iir.c
+++ b/src/audio/eq_iir.c
@@ -110,10 +110,10 @@ static void eq_iir_s32_default(struct comp_dev *dev,
 				/* Check both source and destination for wrap */
 				if (x > (int32_t *) source->end_addr)
 					x = (int32_t *)
-					((size_t) x - source->alloc_size);
+					((size_t) x - source->size);
 				if (snk > (int32_t *) sink->end_addr)
 					y = (int32_t *)
-					((size_t) y - sink->alloc_size);
+					((size_t) y - sink->size);
 			}
 		}
 
@@ -290,12 +290,24 @@ static int eq_iir_params(struct comp_dev *dev)
 {
 	struct comp_data *cd = comp_get_drvdata(dev);
 	struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev);
+	struct comp_buffer *sink;
+	int err;
 
 	trace_eq_iir("par");
 
 	/* calculate period size based on config */
 	cd->period_bytes = dev->frames * dev->frame_bytes;
 
+	/* configure downstream buffer */
+	sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list);
+	err = buffer_set_size(sink, cd->period_bytes * config->periods_sink);
+	if (err < 0) {
+		trace_eq_iir_error("eSz");
+		return err;
+	}
+
+	buffer_reset_pos(sink);
+
 	/* EQ supports only S32_LE PCM format */
 	if (config->frame_fmt != SOF_IPC_FRAME_S32_LE)
 		return -EINVAL;
diff --git a/src/audio/src.c b/src/audio/src.c
index ac2fbb5..54c798e 100644
--- a/src/audio/src.c
+++ b/src/audio/src.c
@@ -60,6 +60,7 @@ struct comp_data {
 	int scratch_length;
 	uint32_t sink_rate;
 	uint32_t source_rate;
+	uint32_t period_bytes;	/* sink period */
 	void (*src_func)(struct comp_dev *dev,
 		struct comp_buffer *source,
 		struct comp_buffer *sink,
@@ -150,7 +151,7 @@ static void src_2s_s32_default(struct comp_dev *dev,
 
 	s1.times = n_times1;
 	s1.x_end_addr = source->end_addr;
-	s1.x_size = source->alloc_size;
+	s1.x_size = source->size;
 	s1.x_inc = nch;
 	s1.y_end_addr = &cd->delay_lines[cd->scratch_length];
 	s1.y_size = STAGE_BUF_SIZE * sizeof(int32_t);
@@ -161,7 +162,7 @@ static void src_2s_s32_default(struct comp_dev *dev,
 	s2.x_size = STAGE_BUF_SIZE * sizeof(int32_t);
 	s2.x_inc = 1;
 	s2.y_end_addr = sink->end_addr;
-	s2.y_size = sink->alloc_size;
+	s2.y_size = sink->size;
 	s2.y_inc = nch;
 
 	s1.x_rptr = src + nch - 1;
@@ -219,10 +220,10 @@ static void src_1s_s32_default(struct comp_dev *dev,
 
 	s1.times = n_times;
 	s1.x_end_addr = source->end_addr;
-	s1.x_size = source->alloc_size;
+	s1.x_size = source->size;
 	s1.x_inc = nch;
 	s1.y_end_addr = sink->end_addr;
-	s1.y_size = sink->alloc_size;
+	s1.y_size = sink->size;
 	s1.y_inc = nch;
 	s1.x_rptr = src + nch - 1;
 	s1.y_wptr = dest + nch - 1;
@@ -307,6 +308,7 @@ static int src_params(struct comp_dev *dev)
 	struct sof_ipc_comp_src *src = COMP_GET_IPC(dev, sof_ipc_comp_src);
 	struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev);
 	struct comp_data *cd = comp_get_drvdata(dev);
+	struct comp_buffer *sink;
 	struct src_alloc need;
 	size_t delay_lines_size;
 	uint32_t source_rate, sink_rate;
@@ -401,6 +403,17 @@ static int src_params(struct comp_dev *dev)
 	/* Need to compute this */
 	dev->frame_bytes =
 		dev->params.sample_container_bytes * dev->params.channels;
+	cd->period_bytes = dev->frames * dev->frame_bytes;
+
+	/* configure downstream buffer */
+	sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list);
+	err = buffer_set_size(sink, cd->period_bytes * config->periods_sink);
+	if (err < 0) {
+		trace_src_error("eSz");
+		return err;
+	}
+
+	buffer_reset_pos(sink);
 
 	return 0;
 }
-- 
2.11.0



More information about the Sound-open-firmware mailing list