[Sound-open-firmware] [PATCH] comp: buffer: add support for non period aligned buffers
Add support for non period aligned buffers to the buffer free/avail calculation.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/include/reef/audio/buffer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/include/reef/audio/buffer.h b/src/include/reef/audio/buffer.h index 54978a8..83fcd57 100644 --- a/src/include/reef/audio/buffer.h +++ b/src/include/reef/audio/buffer.h @@ -93,7 +93,7 @@ static inline void comp_update_buffer_produce(struct comp_buffer *buffer,
/* check for pointer wrap */ if (buffer->w_ptr >= buffer->end_addr) - buffer->w_ptr = buffer->addr; + buffer->w_ptr = buffer->addr + (buffer->w_ptr - buffer->end_addr);
/* calculate available bytes */ if (buffer->r_ptr < buffer->w_ptr) @@ -127,7 +127,7 @@ static inline void comp_update_buffer_consume(struct comp_buffer *buffer,
/* check for pointer wrap */ if (buffer->r_ptr >= buffer->end_addr) - buffer->r_ptr = buffer->addr; + buffer->r_ptr = buffer->addr + (buffer->r_ptr - buffer->end_addr);
/* calculate available bytes */ if (buffer->r_ptr < buffer->w_ptr)
Add new APIs to allow components to easily resize, reset and clear buffers. Update host, mixer and volume to use them.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/audio/host.c | 10 ++++------ src/audio/mixer.c | 14 ++++++++++++++ src/audio/volume.c | 14 ++++++++++++-- src/include/reef/audio/buffer.h | 25 +++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 8 deletions(-)
diff --git a/src/audio/host.c b/src/audio/host.c index e71e95f..3c8ed96 100644 --- a/src/audio/host.c +++ b/src/audio/host.c @@ -412,11 +412,10 @@ static int host_params(struct comp_dev *dev)
/* resize the buffer if space is available to align with period size */ buffer_size = hd->period_count * hd->period_bytes; - if (buffer_size <= hd->dma_buffer->alloc_size) - hd->dma_buffer->size = buffer_size; - else { + err = buffer_set_size(hd->dma_buffer, buffer_size); + if (err < 0) { trace_host_error("eSz"); - return -EINVAL; + return err; }
/* component buffer size must be divisor of host buffer size */ @@ -432,8 +431,7 @@ static int host_params(struct comp_dev *dev) if (err < 0) return err;
- hd->dma_buffer->r_ptr = hd->dma_buffer->addr; - hd->dma_buffer->w_ptr = hd->dma_buffer->addr; + buffer_reset_pos(hd->dma_buffer);
/* set up DMA configuration */ config->src_width = sizeof(uint32_t); diff --git a/src/audio/mixer.c b/src/audio/mixer.c index 932c3ad..3f1f1ed 100644 --- a/src/audio/mixer.c +++ b/src/audio/mixer.c @@ -124,6 +124,9 @@ static void mixer_free(struct comp_dev *dev) static int mixer_params(struct comp_dev *dev) { struct mixer_data *md = comp_get_drvdata(dev); + struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev); + struct comp_buffer *sink; + int ret;
trace_mixer("par");
@@ -141,6 +144,17 @@ static int mixer_params(struct comp_dev *dev) return -EINVAL; }
+ sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); + + /* set downstream buffer size */ + ret = buffer_set_size(sink, md->period_bytes * config->periods_sink); + if (ret < 0) { + trace_mixer_error("mx3"); + return ret; + } + + buffer_reset_pos(sink); + return 0; }
diff --git a/src/audio/volume.c b/src/audio/volume.c index c88f9d2..13bd752 100644 --- a/src/audio/volume.c +++ b/src/audio/volume.c @@ -505,8 +505,8 @@ static int volume_prepare(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); struct comp_buffer *sinkb, *sourceb; - struct sof_ipc_comp_config *sconfig; - int i; + struct sof_ipc_comp_config *sconfig, *config = COMP_GET_CONFIG(dev); + int i, ret;
trace_volume("pre");
@@ -556,6 +556,16 @@ static int volume_prepare(struct comp_dev *dev)
dev->frame_bytes = cd->sink_period_bytes;
+ /* set downstream buffer size */ + ret = buffer_set_size(sinkb, cd->sink_period_bytes * + config->periods_sink); + if (ret < 0) { + trace_volume_error("vp0"); + return ret; + } + + buffer_reset_pos(sinkb); + /* validate */ if (cd->sink_period_bytes == 0) { trace_volume_error("vp1"); diff --git a/src/include/reef/audio/buffer.h b/src/include/reef/audio/buffer.h index 83fcd57..483fa35 100644 --- a/src/include/reef/audio/buffer.h +++ b/src/include/reef/audio/buffer.h @@ -162,4 +162,29 @@ static inline uint32_t comp_buffer_get_copy_bytes(struct comp_dev *dev, return copy_bytes; }
+static inline void buffer_reset_pos(struct comp_buffer *buffer) +{ + buffer->r_ptr = buffer->addr; + buffer->w_ptr = buffer->addr; + buffer->free = buffer->size; + buffer->avail = 0; +} + +static inline void buffer_clear(struct comp_buffer *buffer) +{ + memset(buffer->addr, 0, buffer->size); +} + +/* set the runtime size of a buffer in bytes and improve the data cache */ +/* performance by only using minimum space needed for runtime params */ +static inline int buffer_set_size(struct comp_buffer *buffer, uint32_t size) +{ + if (size > buffer->alloc_size) + return -ENOMEM; + + buffer->end_addr = buffer->addr + size; + buffer->size = size; + return 0; +} + #endif
Buffer pointers were being updated twice. Fix.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/audio/mixer.c | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/src/audio/mixer.c b/src/audio/mixer.c index 3f1f1ed..a4dea4d 100644 --- a/src/audio/mixer.c +++ b/src/audio/mixer.c @@ -73,13 +73,6 @@ static void mix_n(struct comp_dev *dev, struct comp_buffer *sink, dest[i] = (val[0] >> (num_sources >> 1)); dest[i + 1] = (val[1] >> (num_sources >> 1)); } - - /* update R/W pointers */ - sink->w_ptr = dest + count; - for (j = 0; j < num_sources; j++) { - src = sources[j]->r_ptr; - sources[j]->r_ptr = src + count; - } }
static struct comp_dev *mixer_new(struct sof_ipc_comp *comp)
Make sure R/W positions are in trace. Clarify comment for buffer size.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/include/reef/audio/buffer.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/include/reef/audio/buffer.h b/src/include/reef/audio/buffer.h index 483fa35..e708ee2 100644 --- a/src/include/reef/audio/buffer.h +++ b/src/include/reef/audio/buffer.h @@ -52,7 +52,7 @@ struct comp_buffer {
/* runtime data */ uint32_t connected; /* connected in path */ - uint32_t size; /* size of buffer in bytes */ + uint32_t size; /* runtime buffer size in bytes (period multiple) */ uint32_t alloc_size; /* allocated size in bytes */ uint32_t avail; /* available bytes for reading */ uint32_t free; /* free bytes for writing */ @@ -109,6 +109,7 @@ static inline void comp_update_buffer_produce(struct comp_buffer *buffer, tracev_buffer("pro"); tracev_value((buffer->avail << 16) | buffer->free); tracev_value((buffer->ipc_buffer.comp.id << 16) | buffer->size); + tracev_value((buffer->r_ptr - buffer->addr) << 16 | (buffer->w_ptr - buffer->addr)); }
/* called by a component after consuming data from this buffer */ @@ -143,6 +144,7 @@ static inline void comp_update_buffer_consume(struct comp_buffer *buffer, tracev_buffer("con"); tracev_value((buffer->avail << 16) | buffer->free); tracev_value((buffer->ipc_buffer.comp.id << 16) | buffer->size); + tracev_value((buffer->r_ptr - buffer->addr) << 16 | (buffer->w_ptr - buffer->addr)); }
/* get the max number of bytes that can be copied between sink and source */
participants (1)
-
Liam Girdwood