[Sound-open-firmware] [PATCH 2/2] host: fix the increment offset in the callback
Keyon Jie
yang.jie at linux.intel.com
Thu Dec 29 10:29:01 CET 2016
When the host buffer is not 1ms aligned and splitting happens,
the increment is not period size, this wrong pointer will make
pcm data missed/clipped and sound noisy.
Changing to use the actual size last dma copy consumed,
local_elem->size, to fix the issue.
Signed-off-by: Keyon Jie <yang.jie at linux.intel.com>
---
src/audio/host.c | 120 +++++++++++++++++++++++++++----------------------------
1 file changed, 60 insertions(+), 60 deletions(-)
diff --git a/src/audio/host.c b/src/audio/host.c
index f339bc2..fe43cf8 100644
--- a/src/audio/host.c
+++ b/src/audio/host.c
@@ -117,6 +117,37 @@ static void host_dma_cb_playback(struct comp_dev *dev,
trace_host("Cpp");
+ /* update buffer positions */
+ dma_buffer = hd->dma_buffer;
+
+ dma_buffer->w_ptr += local_elem->size;
+
+ if (dma_buffer->w_ptr >= dma_buffer->end_addr)
+ dma_buffer->w_ptr = dma_buffer->addr;
+
+#if 0
+ trace_value((uint32_t)(hd->dma_buffer->w_ptr - hd->dma_buffer->addr));
+#endif
+
+ /* recalc available buffer space */
+ comp_update_buffer(hd->dma_buffer);
+
+ /* new local period, update host buffer position blks */
+ hd->host_pos_blks += local_elem->size;
+
+ /* buffer overlap ? */
+ if (hd->host_pos_blks >= hd->host_size)
+ hd->host_pos_blks = 0;
+ if (hd->host_pos)
+ *hd->host_pos = hd->host_pos_blks;
+
+ /* send IPC message to driver if needed */
+ hd->host_period_pos += local_elem->size;
+ if (hd->host_period_pos >= hd->host_period_bytes) {
+ hd->host_period_pos = 0;
+ ipc_stream_send_notification(dev, &hd->cp);
+ }
+
/* are we dealing with a split transfer */
if (hd->split_remaining) {
@@ -161,36 +192,6 @@ static void host_dma_cb_playback(struct comp_dev *dev,
}
}
- /* update buffer positions */
- dma_buffer = hd->dma_buffer;
-
- dma_buffer->w_ptr += hd->period->size;
-
- if (dma_buffer->w_ptr >= dma_buffer->end_addr)
- dma_buffer->w_ptr = dma_buffer->addr;
-#if 0
- trace_value((uint32_t)(hd->dma_buffer->w_ptr - hd->dma_buffer->addr));
-#endif
-
- /* new local period, update host buffer position blks */
- hd->host_pos_blks += hd->period->size;
-
- /* buffer overlap ? */
- if (hd->host_pos_blks >= hd->host_size)
- hd->host_pos_blks = 0;
- if (hd->host_pos)
- *hd->host_pos = hd->host_pos_blks;
-
- /* recalc available buffer space */
- comp_update_buffer(hd->dma_buffer);
-
- /* send IPC message to driver if needed */
- hd->host_period_pos += hd->period->size;
- if (hd->host_period_pos >= hd->host_period_bytes) {
- hd->host_period_pos = 0;
- ipc_stream_send_notification(dev, &hd->cp);
- }
-
/* let any waiters know we have completed */
wait_completed(&hd->complete);
}
@@ -215,6 +216,35 @@ static void host_dma_cb_capture(struct comp_dev *dev,
trace_host("Cpc");
+ /* update buffer positions */
+ dma_buffer = hd->dma_buffer;
+ hd->dma_buffer->r_ptr += local_elem->size;
+
+ if (dma_buffer->r_ptr >= dma_buffer->end_addr)
+ dma_buffer->r_ptr = dma_buffer->addr;
+#if 0
+ trace_value((uint32_t)(hd->dma_buffer->r_ptr - hd->dma_buffer->addr));
+#endif
+
+ /* new local period, update host buffer position blks */
+ hd->host_pos_blks += local_elem->size;
+
+ /* buffer overlap ? */
+ if (hd->host_pos_blks >= hd->host_size)
+ hd->host_pos_blks = 0;
+ if (hd->host_pos)
+ *hd->host_pos = hd->host_pos_blks;
+
+ /* recalc available buffer space */
+ comp_update_buffer(hd->dma_buffer);
+
+ /* send IPC message to driver if needed */
+ hd->host_period_pos += local_elem->size;
+ if (hd->host_period_pos >= hd->host_period_bytes) {
+ hd->host_period_pos = 0;
+ ipc_stream_send_notification(dev, &hd->cp);
+ }
+
/* are we dealing with a split transfer */
if (hd->split_remaining) {
@@ -259,36 +289,6 @@ static void host_dma_cb_capture(struct comp_dev *dev,
}
}
- /* update buffer positions */
- dma_buffer = hd->dma_buffer;
- hd->dma_buffer->r_ptr += hd->period->size;
-
- if (dma_buffer->r_ptr >= dma_buffer->end_addr)
- dma_buffer->r_ptr = dma_buffer->addr;
-#if 0
- trace_value((uint32_t)(hd->dma_buffer->r_ptr - hd->dma_buffer->addr));
-#endif
-
-
- /* new local period, update host buffer position blks */
- hd->host_pos_blks += hd->period->size;
-
- /* buffer overlap ? */
- if (hd->host_pos_blks >= hd->host_size)
- hd->host_pos_blks = 0;
- if (hd->host_pos)
- *hd->host_pos = hd->host_pos_blks;
-
- /* recalc available buffer space */
- comp_update_buffer(hd->dma_buffer);
-
- /* send IPC message to driver if needed */
- hd->host_period_pos += hd->period->size;
- if (hd->host_period_pos >= hd->host_period_bytes) {
- hd->host_period_pos = 0;
- ipc_stream_send_notification(dev, &hd->cp);
- }
-
/* let any waiters know we have completed */
wait_completed(&hd->complete);
}
--
2.5.0
More information about the Sound-open-firmware
mailing list