[Sound-open-firmware] [PATCH] component: fix comp_update_buffer() when buffer full

Keyon Jie yang.jie at linux.intel.com
Tue Jan 10 10:06:25 CET 2017


It will treat full buffer as empty one at current
comp_update_buffer(), as w_ptr is equal to r_ptr,
this will make us missing those datas or at least
the buffer->avail/free are not correct.

Here spit comp_update_buffer() into consuming one
and producing one, for consuming, 'r_ptr == w_ptr'
update means buffer is becoming empty, and for
producing, 'w_ptr == r_ptr' means buffer is becoming
full.

Signed-off-by: Keyon Jie <yang.jie at linux.intel.com>
---
 src/audio/dai.c                    |  8 +++++---
 src/audio/host.c                   |  4 ++--
 src/audio/mixer.c                  |  4 ++--
 src/audio/volume.c                 |  4 ++--
 src/include/reef/audio/component.h | 18 ++++++++++++++++--
 5 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/src/audio/dai.c b/src/audio/dai.c
index 64e4761..ab0164c 100644
--- a/src/audio/dai.c
+++ b/src/audio/dai.c
@@ -98,6 +98,8 @@ static void dai_dma_cb(void *data, uint32_t type, struct dma_sg_elem *next)
 			*dd->dai_pos = dd->dai_pos_blks +
 				dma_buffer->r_ptr - dma_buffer->addr;
 
+		/* recalc available buffer space */
+		comp_update_buffer_consume(dma_buffer);
 	} else {
 		dma_buffer = list_first_item(&dev->bsink_list,
 			struct comp_buffer, source_list);
@@ -119,10 +121,10 @@ static void dai_dma_cb(void *data, uint32_t type, struct dma_sg_elem *next)
 		if (dd->dai_pos)
 			*dd->dai_pos = dd->dai_pos_blks +
 				dma_buffer->w_ptr - dma_buffer->addr;
-	}
 
-	/* recalc available buffer space */
-	comp_update_buffer(dma_buffer);
+		/* recalc available buffer space */
+		comp_update_buffer_produce(dma_buffer);
+	}
 
 	/* notify pipeline that DAI needs it's buffer filled */
 //	if (dev->state == COMP_STATE_RUNNING)
diff --git a/src/audio/host.c b/src/audio/host.c
index fe43cf8..217ad4f 100644
--- a/src/audio/host.c
+++ b/src/audio/host.c
@@ -130,7 +130,7 @@ static void host_dma_cb_playback(struct comp_dev *dev,
 #endif
 
 	/* recalc available buffer space */
-	comp_update_buffer(hd->dma_buffer);
+	comp_update_buffer_consume(hd->dma_buffer);
 
 	/* new local period, update host buffer position blks */
 	hd->host_pos_blks += local_elem->size;
@@ -236,7 +236,7 @@ static void host_dma_cb_capture(struct comp_dev *dev,
 		*hd->host_pos = hd->host_pos_blks;
 
 	/* recalc available buffer space */
-	comp_update_buffer(hd->dma_buffer);
+	comp_update_buffer_produce(hd->dma_buffer);
 
 	/* send IPC message to driver if needed */
 	hd->host_period_pos += local_elem->size;
diff --git a/src/audio/mixer.c b/src/audio/mixer.c
index b996dae..3a8d12f 100644
--- a/src/audio/mixer.c
+++ b/src/audio/mixer.c
@@ -230,13 +230,13 @@ static int mixer_copy(struct comp_dev *dev)
 	for(; i > 0; i--) {
 		if (sources[i-1]->r_ptr >= sources[i-1]->end_addr)
 			sources[i-1]->r_ptr = sources[i-1]->addr;
-		comp_update_buffer(sources[i-1]);
+		comp_update_buffer_consume(sources[i-1]);
 	}
 	if (sink->w_ptr >= sink->end_addr)
 		sink->w_ptr = sink->addr;
 
 	/* calc new free and available */
-	comp_update_buffer(sink);
+	comp_update_buffer_produce(sink);
 
 	/* number of frames sent downstream */
 	return cframes;
diff --git a/src/audio/volume.c b/src/audio/volume.c
index e2badb8..75a48f9 100644
--- a/src/audio/volume.c
+++ b/src/audio/volume.c
@@ -460,8 +460,8 @@ static int volume_copy(struct comp_dev *dev)
 		sink->w_ptr = sink->addr;
 
 	/* calc new free and available */
-	comp_update_buffer(sink);
-	comp_update_buffer(source);
+	comp_update_buffer_produce(sink);
+	comp_update_buffer_consume(source);
 
 	/* number of frames sent downstream */
 	return cframes;
diff --git a/src/include/reef/audio/component.h b/src/include/reef/audio/component.h
index fbd29e4..e521753 100644
--- a/src/include/reef/audio/component.h
+++ b/src/include/reef/audio/component.h
@@ -311,10 +311,24 @@ void sys_comp_mux_init(void);
 void sys_comp_switch_init(void);
 void sys_comp_volume_init(void);
 
-static inline void comp_update_buffer(struct comp_buffer *buffer)
+static inline void comp_update_buffer_produce(struct comp_buffer *buffer)
 {
-	if (buffer->r_ptr <= buffer->w_ptr)
+	if (buffer->r_ptr < buffer->w_ptr)
 		buffer->avail = buffer->w_ptr - buffer->r_ptr;
+	else if (buffer->r_ptr == buffer->w_ptr)
+		buffer->avail = buffer->end_addr - buffer->addr; /* full */
+	else
+		buffer->avail = buffer->end_addr - buffer->r_ptr +
+			buffer->w_ptr - buffer->addr;
+	buffer->free = buffer->desc.size - buffer->avail;
+}
+
+static inline void comp_update_buffer_consume(struct comp_buffer *buffer)
+{
+	if (buffer->r_ptr < buffer->w_ptr)
+		buffer->avail = buffer->w_ptr - buffer->r_ptr;
+	else if (buffer->r_ptr == buffer->w_ptr)
+		buffer->avail = 0; /* empty */
 	else
 		buffer->avail = buffer->end_addr - buffer->r_ptr +
 			buffer->w_ptr - buffer->addr;
-- 
2.7.4



More information about the Sound-open-firmware mailing list