add 16bit<==>24bit volume copy function and mapping, for 24 bits ssp output/input.
Signed-off-by: Keyon Jie yang.jie@linux.intel.com --- src/audio/volume.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+)
diff --git a/src/audio/volume.c b/src/audio/volume.c index f5528cd..5299edd 100644 --- a/src/audio/volume.c +++ b/src/audio/volume.c @@ -172,12 +172,55 @@ static void vol_s16_to_s16(struct comp_dev *dev, struct comp_buffer *sink, sink->w_ptr = dest; }
+/* copy and scale volume from 16 bit source buffer to 24 bit on 32 bit boundary dest buffer */ +static void vol_s16_to_s24(struct comp_dev *dev, struct comp_buffer *sink, + struct comp_buffer *source, uint32_t frames) +{ + struct comp_data *cd = comp_get_drvdata(dev); + int16_t *src = (int16_t*) source->r_ptr; + int32_t val, i, *dest = (int32_t*) sink->w_ptr; + + /* buffer sizes are always divisible by period frames */ + for (i = 0; i < frames * source->params.channels; i++) { + val = (int32_t)*src; + *dest = (val * cd->volume[i % source->params.channels]) >> 8; + dest++; + src++; + } + + source->r_ptr = src; + sink->w_ptr = dest; +} + +/* copy and scale volume from 16 bit source buffer to 24 bit on 32 bit boundary dest buffer */ +static void vol_s24_to_s16(struct comp_dev *dev, struct comp_buffer *sink, + struct comp_buffer *source, uint32_t frames) +{ + struct comp_data *cd = comp_get_drvdata(dev); + int32_t val, i, *src = (int32_t*) source->r_ptr; + int16_t *dest = (int16_t*) sink->w_ptr; + + /* buffer sizes are always divisible by period frames */ + for (i = 0; i < frames * source->params.channels; i++) { + val = (int32_t)*src; + *dest = (int16_t)(((val >> 8) * + cd->volume[i % source->params.channels]) >> 16); + dest++; + src++; + } + + source->r_ptr = src; + sink->w_ptr = dest; +} + /* map of source and sink buffer formats to volume function */ static const struct comp_func_map func_map[] = { {STREAM_FORMAT_S16_LE, STREAM_FORMAT_S16_LE, vol_s16_to_s16}, {STREAM_FORMAT_S16_LE, STREAM_FORMAT_S32_LE, vol_s16_to_s32}, {STREAM_FORMAT_S32_LE, STREAM_FORMAT_S16_LE, vol_s32_to_s16}, {STREAM_FORMAT_S32_LE, STREAM_FORMAT_S32_LE, vol_s32_to_s32}, + {STREAM_FORMAT_S16_LE, STREAM_FORMAT_S24_4LE, vol_s16_to_s24}, + {STREAM_FORMAT_S24_4LE, STREAM_FORMAT_S16_LE, vol_s24_to_s16}, };
static void vol_update(struct comp_data *cd, uint32_t chan)