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