[Sound-open-firmware] [PATCH] volume: fix copy size incorrect issue
The copy sizes for src and sink may be different, here add fix to handle it.
Signed-off-by: Keyon Jie yang.jie@linux.intel.com --- src/audio/volume.c | 38 +++++++++++++++++++++++++++++--------- src/include/reef/audio/buffer.h | 19 +++++++++++++++++++ 2 files changed, 48 insertions(+), 9 deletions(-)
diff --git a/src/audio/volume.c b/src/audio/volume.c index 415a853..9cf766b 100644 --- a/src/audio/volume.c +++ b/src/audio/volume.c @@ -535,13 +535,27 @@ static int volume_cmd(struct comp_dev *dev, int cmd, void *data) } }
+static uint32_t get_frame_bytes(enum sof_ipc_frame frame_fmt, uint32_t chan) +{ + switch (frame_fmt) { + case SOF_IPC_FRAME_S16_LE: + return 2 * chan; + case SOF_IPC_FRAME_S24_4LE: + case SOF_IPC_FRAME_S32_LE: + return 4 * chan; + default: + return 0; + } +} + /* copy and process stream data from source to sink buffers */ static int volume_copy(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); struct comp_buffer *sink; struct comp_buffer *source; - uint32_t copy_bytes; + uint32_t copy_src_bytes, copy_sink_bytes; + uint32_t copy_frames, src_frame_bytes, sink_frame_bytes;
tracev_volume("cpy");
@@ -549,16 +563,22 @@ static int volume_copy(struct comp_dev *dev) source = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list);
+ src_frame_bytes = get_frame_bytes(cd->source_format, dev->params.channels); + sink_frame_bytes = get_frame_bytes(cd->sink_format, dev->params.channels); + /* get max number of bytes that can be copied */ - copy_bytes = comp_buffer_get_copy_bytes(dev, source, sink); + copy_frames = comp_buffer_get_copy_frames(source, src_frame_bytes, + sink, sink_frame_bytes); + copy_src_bytes = copy_frames * src_frame_bytes; + copy_sink_bytes = copy_frames * sink_frame_bytes;
/* Run volume if buffers have enough room */ - if (copy_bytes < cd->source_period_bytes) { - comp_underrun(dev, source, copy_bytes, cd->source_period_bytes); + if (copy_src_bytes < cd->source_period_bytes) { + comp_underrun(dev, source, copy_src_bytes, cd->source_period_bytes); return 0; } - if (copy_bytes < cd->sink_period_bytes) { - comp_overrun(dev, sink, copy_bytes, cd->sink_period_bytes); + if (copy_sink_bytes < cd->sink_period_bytes) { + comp_overrun(dev, sink, copy_sink_bytes, cd->sink_period_bytes); return 0; }
@@ -566,10 +586,10 @@ static int volume_copy(struct comp_dev *dev) cd->scale_vol(dev, sink, source, dev->frames);
/* calc new free and available */ - comp_update_buffer_produce(sink, cd->sink_period_bytes); - comp_update_buffer_consume(source, cd->source_period_bytes); + comp_update_buffer_produce(sink, copy_sink_bytes); + comp_update_buffer_consume(source, copy_src_bytes);
- return dev->frames; + return copy_frames; }
/* diff --git a/src/include/reef/audio/buffer.h b/src/include/reef/audio/buffer.h index d1d0869..45aa3ce 100644 --- a/src/include/reef/audio/buffer.h +++ b/src/include/reef/audio/buffer.h @@ -164,6 +164,25 @@ static inline uint32_t comp_buffer_get_copy_bytes(struct comp_dev *dev, return copy_bytes; }
+/* get the max number of frames that can be copied between sink and source */ +static inline uint32_t comp_buffer_get_copy_frames + (struct comp_buffer *source, uint32_t source_frame_bytes, + struct comp_buffer *sink, uint32_t sink_frame_bytes) +{ + uint32_t copy_frames, src_avail_frames, sink_free_frames; + + src_avail_frames = source->avail / source_frame_bytes; + sink_free_frames = sink->free / sink_frame_bytes; + + /* Check that source has enough frames available and sink + * has enough free frames. + */ + copy_frames = src_avail_frames > sink_free_frames ? + sink_free_frames : src_avail_frames; + + return copy_frames; +} + static inline void buffer_reset_pos(struct comp_buffer *buffer) { buffer->r_ptr = buffer->addr;
On Thu, 2017-11-16 at 23:04 +0800, Keyon Jie wrote:
The copy sizes for src and sink may be different, here add fix to handle it.
Signed-off-by: Keyon Jie yang.jie@linux.intel.com
src/audio/volume.c | 38 +++++++++++++++++++++++++++++--------- src/include/reef/audio/buffer.h | 19 +++++++++++++++++++ 2 files changed, 48 insertions(+), 9 deletions(-)
diff --git a/src/audio/volume.c b/src/audio/volume.c index 415a853..9cf766b 100644 --- a/src/audio/volume.c +++ b/src/audio/volume.c @@ -535,13 +535,27 @@ static int volume_cmd(struct comp_dev *dev, int cmd, void *data) } }
I will merge parts of this into the xrun branch since we both have patches that do a similar thing and impact volume copy.
Thanks
Liam
participants (2)
-
Keyon Jie
-
Liam Girdwood