[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