[Sound-open-firmware] [PATCH] volume: support 8-channel feature.
add the 8-channel feature for the capture function on apl-gpmrb.
Signed-off-by: Wu Zhigang zhigang.wu@linux.intel.com Reviewed-by: Keyon Jie yang.jie@linux.intel.com
--- Test with: apl-gpmrb with tdf8532 codec
linux topic/sof-dev: 1e0f50565669815dd7daa19021b3b04a90487431 sof master: b0affc18c3068225e766190aa81cad1ddb082457 soft master: 2cc3ad2a9287e8354ae9f7dc5161d7f4d4539949
Pass the regression test already: Minnowboard Turbo UP^2 CNL-RVP --- src/audio/volume.c | 359 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 359 insertions(+)
diff --git a/src/audio/volume.c b/src/audio/volume.c index d0b690b..7c2044a 100644 --- a/src/audio/volume.c +++ b/src/audio/volume.c @@ -515,6 +515,356 @@ static void vol_s24_to_s24_4ch(struct comp_dev *dev, struct comp_buffer *sink, } }
+/* volume scaling functions for 8-channel input */ + +/* copy and scale volume from 16 bit source buffer to 32 bit dest buffer */ +static void vol_s16_to_s32_8ch(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 *dest = (int32_t *)sink->w_ptr; + int32_t i; + + /* buffer sizes are always divisible by period frames */ + /* Samples are Q1.15 --> Q1.31 and volume is Q1.16 */ + for (i = 0; i < frames * 8; i += 8) { + dest[i] = (int32_t)src[i] * cd->volume[0]; + dest[i + 1] = (int32_t)src[i + 1] * cd->volume[1]; + dest[i + 2] = (int32_t)src[i + 2] * cd->volume[2]; + dest[i + 3] = (int32_t)src[i + 3] * cd->volume[3]; + dest[i + 4] = (int32_t)src[i + 4] * cd->volume[4]; + dest[i + 5] = (int32_t)src[i + 5] * cd->volume[5]; + dest[i + 6] = (int32_t)src[i + 6] * cd->volume[6]; + dest[i + 7] = (int32_t)src[i + 7] * cd->volume[7]; + } +} + +/* copy and scale volume from 32 bit source buffer to 16 bit dest buffer */ +static void vol_s32_to_s16_8ch(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 *src = (int32_t *)source->r_ptr; + int16_t *dest = (int16_t *)sink->w_ptr; + int32_t i; + + /* buffer sizes are always divisible by period frames */ + /* Samples are Q1.31 --> Q1.15 and volume is Q1.16 */ + for (i = 0; i < frames * 8; i += 8) { + dest[i] = (int16_t)q_multsr_sat_32x32(src[i], cd->volume[0], + Q_SHIFT_BITS_64(31, 16, + 15)); + dest[i + 1] = (int16_t)q_multsr_sat_32x32(src[i + 1], + cd->volume[1], + Q_SHIFT_BITS_64(31, + 16, + 15)); + dest[i + 2] = (int16_t)q_multsr_sat_32x32(src[i + 2], + cd->volume[2], + Q_SHIFT_BITS_64(31, + 16, + 15)); + dest[i + 3] = (int16_t)q_multsr_sat_32x32(src[i + 3], + cd->volume[3], + Q_SHIFT_BITS_64(31, + 16, + 15)); + dest[i + 4] = (int16_t)q_multsr_sat_32x32(src[i + 4], + cd->volume[4], + Q_SHIFT_BITS_64(31, + 16, + 15)); + dest[i + 5] = (int16_t)q_multsr_sat_32x32(src[i + 5], + cd->volume[5], + Q_SHIFT_BITS_64(31, + 16, + 15)); + dest[i + 6] = (int16_t)q_multsr_sat_32x32(src[i + 6], + cd->volume[6], + Q_SHIFT_BITS_64(31, + 16, + 15)); + dest[i + 7] = (int16_t)q_multsr_sat_32x32(src[i + 7], + cd->volume[7], + Q_SHIFT_BITS_64(31, + 16, + 15)); + } +} + +/* copy and scale volume from 32 bit source buffer to 32 bit dest buffer */ +static void vol_s32_to_s32_8ch(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 *src = (int32_t *)source->r_ptr; + int32_t *dest = (int32_t *)sink->w_ptr; + int32_t i; + + /* buffer sizes are always divisible by period frames */ + /* Samples are Q1.31 --> Q1.31 and volume is Q1.16 */ + for (i = 0; i < frames * 8; i += 8) { + dest[i] = q_multsr_sat_32x32(src[i], cd->volume[0], + Q_SHIFT_BITS_64(31, 16, 31)); + dest[i + 1] = q_multsr_sat_32x32(src[i + 1], cd->volume[1], + Q_SHIFT_BITS_64(31, 16, 31)); + dest[i + 2] = q_multsr_sat_32x32(src[i + 2], cd->volume[2], + Q_SHIFT_BITS_64(31, 16, 31)); + dest[i + 3] = q_multsr_sat_32x32(src[i + 3], cd->volume[3], + Q_SHIFT_BITS_64(31, 16, 31)); + dest[i + 4] = q_multsr_sat_32x32(src[i + 4], cd->volume[4], + Q_SHIFT_BITS_64(31, 16, 31)); + dest[i + 5] = q_multsr_sat_32x32(src[i + 5], cd->volume[5], + Q_SHIFT_BITS_64(31, 16, 31)); + dest[i + 6] = q_multsr_sat_32x32(src[i + 6], cd->volume[6], + Q_SHIFT_BITS_64(31, 16, 31)); + dest[i + 7] = q_multsr_sat_32x32(src[i + 7], cd->volume[7], + Q_SHIFT_BITS_64(31, 16, 31)); + } +} + +/* copy and scale volume from 16 bit source buffer to 16 bit dest buffer */ +static void vol_s16_to_s16_8ch(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; + int16_t *dest = (int16_t *)sink->w_ptr; + int32_t i; + + /* buffer sizes are always divisible by period frames */ + /* Samples are Q1.15 --> Q1.15 and volume is Q1.16 */ + for (i = 0; i < frames * 8; i += 8) { + dest[i] = q_multsr_sat_16x16(src[i], cd->volume[0], + Q_SHIFT_BITS_32(15, 16, 15)); + dest[i + 1] = q_multsr_sat_16x16(src[i + 1], cd->volume[1], + Q_SHIFT_BITS_32(15, 16, 15)); + dest[i + 2] = q_multsr_sat_16x16(src[i + 2], cd->volume[2], + Q_SHIFT_BITS_32(15, 16, 15)); + dest[i + 3] = q_multsr_sat_16x16(src[i + 3], cd->volume[3], + Q_SHIFT_BITS_32(15, 16, 15)); + dest[i + 4] = q_multsr_sat_16x16(src[i + 4], cd->volume[4], + Q_SHIFT_BITS_32(15, 16, 15)); + dest[i + 5] = q_multsr_sat_16x16(src[i + 5], cd->volume[5], + Q_SHIFT_BITS_32(15, 16, 15)); + dest[i + 6] = q_multsr_sat_16x16(src[i + 6], cd->volume[6], + Q_SHIFT_BITS_32(15, 16, 15)); + dest[i + 7] = q_multsr_sat_16x16(src[i + 7], cd->volume[7], + Q_SHIFT_BITS_32(15, 16, 15)); + } +} + +/* copy and scale volume from 16 bit source buffer to 24 bit + * on 32 bit boundary buffer + */ +static void vol_s16_to_s24_8ch(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 *dest = (int32_t *)sink->w_ptr; + int32_t i; + + /* buffer sizes are always divisible by period frames */ + /* Samples are Q1.15 and volume is Q1.16 */ + for (i = 0; i < frames * 8; i += 8) { + dest[i] = q_multsr_sat_32x32(src[i], cd->volume[0], + Q_SHIFT_BITS_64(15, 16, 23)); + dest[i + 1] = q_multsr_sat_32x32(src[i + 1], cd->volume[1], + Q_SHIFT_BITS_64(15, 16, 23)); + dest[i + 2] = q_multsr_sat_32x32(src[i + 2], cd->volume[2], + Q_SHIFT_BITS_64(15, 16, 23)); + dest[i + 3] = q_multsr_sat_32x32(src[i + 3], cd->volume[3], + Q_SHIFT_BITS_64(15, 16, 23)); + dest[i + 4] = q_multsr_sat_32x32(src[i + 4], cd->volume[4], + Q_SHIFT_BITS_64(15, 16, 23)); + dest[i + 5] = q_multsr_sat_32x32(src[i + 5], cd->volume[5], + Q_SHIFT_BITS_64(15, 16, 23)); + dest[i + 6] = q_multsr_sat_32x32(src[i + 6], cd->volume[6], + Q_SHIFT_BITS_64(15, 16, 23)); + dest[i + 7] = q_multsr_sat_32x32(src[i + 7], cd->volume[7], + Q_SHIFT_BITS_64(15, 16, 23)); + } +} + +/* copy and scale volume from 16 bit source buffer to 24 bit + * on 32 bit boundary dest buffer + */ +static void vol_s24_to_s16_8ch(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 *src = (int32_t *)source->r_ptr; + int16_t *dest = (int16_t *)sink->w_ptr; + int32_t i, sample; + + /* buffer sizes are always divisible by period frames */ + /* Samples are Q1.23 --> Q1.15 and volume is Q1.16 */ + for (i = 0; i < frames * 8; i += 8) { + sample = sign_extend_s24(src[i]); + dest[i] = (int16_t)q_multsr_sat_32x32(sample, cd->volume[0], + Q_SHIFT_BITS_64(23, 16, + 15)); + sample = sign_extend_s24(src[i + 1]); + dest[i + 1] = (int16_t)q_multsr_sat_32x32(sample, + cd->volume[1], + Q_SHIFT_BITS_64(23, + 16, + 15)); + sample = sign_extend_s24(src[i + 2]); + dest[i + 2] = (int16_t)q_multsr_sat_32x32(sample, + cd->volume[2], + Q_SHIFT_BITS_64(23, + 16, + 15)); + sample = sign_extend_s24(src[i + 3]); + dest[i + 3] = (int16_t)q_multsr_sat_32x32(sample, + cd->volume[3], + Q_SHIFT_BITS_64(23, + 16, + 15)); + sample = sign_extend_s24(src[i + 4]); + dest[i + 4] = (int16_t)q_multsr_sat_32x32(sample, + cd->volume[4], + Q_SHIFT_BITS_64(23, + 16, + 15)); + sample = sign_extend_s24(src[i + 5]); + dest[i + 5] = (int16_t)q_multsr_sat_32x32(sample, + cd->volume[5], + Q_SHIFT_BITS_64(23, + 16, + 15)); + sample = sign_extend_s24(src[i + 6]); + dest[i + 6] = (int16_t)q_multsr_sat_32x32(sample, + cd->volume[6], + Q_SHIFT_BITS_64(23, + 16, + 15)); + sample = sign_extend_s24(src[i + 7]); + dest[i + 7] = (int16_t)q_multsr_sat_32x32(sample, + cd->volume[7], + Q_SHIFT_BITS_64(23, + 16, + 15)); + } +} + +/* copy and scale volume from 32 bit source buffer to 24 bit + * on 32 bit boundary dest buffer + */ +static void vol_s32_to_s24_8ch(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 *src = (int32_t *)source->r_ptr; + int32_t *dest = (int32_t *)sink->w_ptr; + int32_t i; + + /* buffer sizes are always divisible by period frames */ + /* Samples are Q1.31 --> Q1.23 and volume is Q1.16 */ + for (i = 0; i < frames * 8; i += 8) { + dest[i] = q_multsr_sat_32x32(src[i], cd->volume[0], + Q_SHIFT_BITS_64(31, 16, 23)); + dest[i + 1] = q_multsr_sat_32x32(src[i + 1], cd->volume[1], + Q_SHIFT_BITS_64(31, 16, 23)); + dest[i + 2] = q_multsr_sat_32x32(src[i + 2], cd->volume[2], + Q_SHIFT_BITS_64(31, 16, 23)); + dest[i + 3] = q_multsr_sat_32x32(src[i + 3], cd->volume[3], + Q_SHIFT_BITS_64(31, 16, 23)); + dest[i + 4] = q_multsr_sat_32x32(src[i + 4], cd->volume[4], + Q_SHIFT_BITS_64(31, 16, 23)); + dest[i + 5] = q_multsr_sat_32x32(src[i + 5], cd->volume[5], + Q_SHIFT_BITS_64(31, 16, 23)); + dest[i + 6] = q_multsr_sat_32x32(src[i + 6], cd->volume[6], + Q_SHIFT_BITS_64(31, 16, 23)); + dest[i + 7] = q_multsr_sat_32x32(src[i + 7], cd->volume[7], + Q_SHIFT_BITS_64(31, 16, 23)); + } +} + +/* copy and scale volume from 16 bit source buffer to 24 bit + * on 32 bit boundary dest buffer + */ +static void vol_s24_to_s32_8ch(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 *src = (int32_t *)source->r_ptr; + int32_t *dest = (int32_t *)sink->w_ptr; + int32_t i; + + /* buffer sizes are always divisible by period frames */ + /* Samples are Q1.23 --> Q1.31 and volume is Q1.16 */ + for (i = 0; i < frames * 8; i += 8) { + dest[i] = q_multsr_sat_32x32(sign_extend_s24(src[i]), + cd->volume[0], + Q_SHIFT_BITS_64(23, 16, 31)); + dest[i + 1] = q_multsr_sat_32x32(sign_extend_s24(src[i + 1]), + cd->volume[1], + Q_SHIFT_BITS_64(23, 16, 31)); + dest[i + 2] = q_multsr_sat_32x32(sign_extend_s24(src[i + 2]), + cd->volume[2], + Q_SHIFT_BITS_64(23, 16, 31)); + dest[i + 3] = q_multsr_sat_32x32(sign_extend_s24(src[i + 3]), + cd->volume[3], + Q_SHIFT_BITS_64(23, 16, 31)); + dest[i + 4] = q_multsr_sat_32x32(sign_extend_s24(src[i + 4]), + cd->volume[4], + Q_SHIFT_BITS_64(23, 16, 31)); + dest[i + 5] = q_multsr_sat_32x32(sign_extend_s24(src[i + 5]), + cd->volume[5], + Q_SHIFT_BITS_64(23, 16, 31)); + dest[i + 6] = q_multsr_sat_32x32(sign_extend_s24(src[i + 6]), + cd->volume[6], + Q_SHIFT_BITS_64(23, 16, 31)); + dest[i + 7] = q_multsr_sat_32x32(sign_extend_s24(src[i + 7]), + cd->volume[7], + Q_SHIFT_BITS_64(23, 16, 31)); + } +} + +/* Copy and scale volume from 24 bit source buffer to 24 bit on 32 bit boundary + * dest buffer. + */ +static void vol_s24_to_s24_8ch(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 i, *src = (int32_t *)source->r_ptr; + int32_t *dest = (int32_t *)sink->w_ptr; + + /* buffer sizes are always divisible by period frames */ + /* Samples are Q1.23 --> Q1.23 and volume is Q1.16 */ + for (i = 0; i < frames * 8; i += 8) { + dest[i] = q_multsr_sat_32x32(sign_extend_s24(src[i]), + cd->volume[0], + Q_SHIFT_BITS_64(23, 16, 23)); + dest[i + 1] = q_multsr_sat_32x32(sign_extend_s24(src[i + 1]), + cd->volume[1], + Q_SHIFT_BITS_64(23, 16, 23)); + dest[i + 2] = q_multsr_sat_32x32(sign_extend_s24(src[i + 2]), + cd->volume[2], + Q_SHIFT_BITS_64(23, 16, 23)); + dest[i + 3] = q_multsr_sat_32x32(sign_extend_s24(src[i + 3]), + cd->volume[3], + Q_SHIFT_BITS_64(23, 16, 23)); + dest[i + 4] = q_multsr_sat_32x32(sign_extend_s24(src[i + 4]), + cd->volume[4], + Q_SHIFT_BITS_64(23, 16, 23)); + dest[i + 5] = q_multsr_sat_32x32(sign_extend_s24(src[i + 5]), + cd->volume[5], + Q_SHIFT_BITS_64(23, 16, 23)); + dest[i + 6] = q_multsr_sat_32x32(sign_extend_s24(src[i + 6]), + cd->volume[6], + Q_SHIFT_BITS_64(23, 16, 23)); + dest[i + 7] = q_multsr_sat_32x32(sign_extend_s24(src[i + 7]), + cd->volume[7], + Q_SHIFT_BITS_64(23, 16, 23)); + } +} + /* map of source and sink buffer formats to volume function */ static const struct comp_func_map func_map[] = { {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, 2, vol_s16_to_s16_2ch}, @@ -535,6 +885,15 @@ static const struct comp_func_map func_map[] = { {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, 4, vol_s32_to_s24_4ch}, {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, 4, vol_s24_to_s32_4ch}, {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S24_4LE, 4, vol_s24_to_s24_4ch}, + {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, 8, vol_s16_to_s16_8ch}, + {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, 8, vol_s16_to_s32_8ch}, + {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, 8, vol_s32_to_s16_8ch}, + {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, 8, vol_s32_to_s32_8ch}, + {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S24_4LE, 8, vol_s16_to_s24_8ch}, + {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S16_LE, 8, vol_s24_to_s16_8ch}, + {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, 8, vol_s32_to_s24_8ch}, + {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, 8, vol_s24_to_s32_8ch}, + {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S24_4LE, 8, vol_s24_to_s24_8ch}, };
/* synchronise host mmap() volume with real value */
On Wed, 2018-06-13 at 13:47 +0800, Wu Zhigang wrote:
add the 8-channel feature for the capture function on apl-gpmrb.
Zhigang, Seppo and I ran into issues even with the 4-ch volume functions when compiling with xt-xcc on BYT. I forgot the details but i think we were exceeding the data section. Have you tried xt-xcc with this patch?
Could we possibly define these under #if defined(CONFIG_APOLLOLAKE)? to maybe avoid that situation?
Signed-off-by: Wu Zhigang zhigang.wu@linux.intel.com Reviewed-by: Keyon Jie yang.jie@linux.intel.com
Test with: apl-gpmrb with tdf8532 codec
linux topic/sof-dev: 1e0f50565669815dd7daa19021b3b04a90487431 sof master: b0affc18c3068225e766190aa81cad1ddb082457 soft master: 2cc3ad2a9287e8354ae9f7dc5161d7f4d4539949
Pass the regression test already: Minnowboard Turbo UP^2 CNL-RVP
src/audio/volume.c | 359 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 359 insertions(+)
diff --git a/src/audio/volume.c b/src/audio/volume.c index d0b690b..7c2044a 100644 --- a/src/audio/volume.c +++ b/src/audio/volume.c @@ -515,6 +515,356 @@ static void vol_s24_to_s24_4ch(struct comp_dev *dev, struct comp_buffer *sink, } }
+/* volume scaling functions for 8-channel input */
+/* copy and scale volume from 16 bit source buffer to 32 bit dest buffer */ +static void vol_s16_to_s32_8ch(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 *dest = (int32_t *)sink->w_ptr;
- int32_t i;
- /* buffer sizes are always divisible by period frames */
- /* Samples are Q1.15 --> Q1.31 and volume is Q1.16 */
- for (i = 0; i < frames * 8; i += 8) {
dest[i] = (int32_t)src[i] * cd->volume[0];
dest[i + 1] = (int32_t)src[i + 1] * cd->volume[1];
dest[i + 2] = (int32_t)src[i + 2] * cd->volume[2];
dest[i + 3] = (int32_t)src[i + 3] * cd->volume[3];
dest[i + 4] = (int32_t)src[i + 4] * cd->volume[4];
dest[i + 5] = (int32_t)src[i + 5] * cd->volume[5];
dest[i + 6] = (int32_t)src[i + 6] * cd->volume[6];
dest[i + 7] = (int32_t)src[i + 7] * cd->volume[7];
- }
+}
+/* copy and scale volume from 32 bit source buffer to 16 bit dest buffer */ +static void vol_s32_to_s16_8ch(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 *src = (int32_t *)source->r_ptr;
- int16_t *dest = (int16_t *)sink->w_ptr;
- int32_t i;
- /* buffer sizes are always divisible by period frames */
- /* Samples are Q1.31 --> Q1.15 and volume is Q1.16 */
- for (i = 0; i < frames * 8; i += 8) {
dest[i] = (int16_t)q_multsr_sat_32x32(src[i], cd-
volume[0],
Q_SHIFT_BITS_6
4(31, 16,
15));
dest[i + 1] = (int16_t)q_multsr_sat_32x32(src[i +
1],
cd-
volume[1],
Q_SHIFT_BI
TS_64(31,
16,
15));
dest[i + 2] = (int16_t)q_multsr_sat_32x32(src[i +
2],
cd-
volume[2],
Q_SHIFT_BI
TS_64(31,
16,
15));
dest[i + 3] = (int16_t)q_multsr_sat_32x32(src[i +
3],
cd-
volume[3],
Q_SHIFT_BI
TS_64(31,
16,
15));
dest[i + 4] = (int16_t)q_multsr_sat_32x32(src[i +
4],
cd-
volume[4],
Q_SHIFT_BI
TS_64(31,
16,
15));
dest[i + 5] = (int16_t)q_multsr_sat_32x32(src[i +
5],
cd-
volume[5],
Q_SHIFT_BI
TS_64(31,
16,
15));
dest[i + 6] = (int16_t)q_multsr_sat_32x32(src[i +
6],
cd-
volume[6],
Q_SHIFT_BI
TS_64(31,
16,
15));
dest[i + 7] = (int16_t)q_multsr_sat_32x32(src[i +
7],
cd-
volume[7],
Q_SHIFT_BI
TS_64(31,
16,
15));
- }
+}
+/* copy and scale volume from 32 bit source buffer to 32 bit dest buffer */ +static void vol_s32_to_s32_8ch(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 *src = (int32_t *)source->r_ptr;
- int32_t *dest = (int32_t *)sink->w_ptr;
- int32_t i;
- /* buffer sizes are always divisible by period frames */
- /* Samples are Q1.31 --> Q1.31 and volume is Q1.16 */
- for (i = 0; i < frames * 8; i += 8) {
dest[i] = q_multsr_sat_32x32(src[i], cd->volume[0],
Q_SHIFT_BITS_64(31, 16,
31));
dest[i + 1] = q_multsr_sat_32x32(src[i + 1], cd-
volume[1],
Q_SHIFT_BITS_64(31,
16, 31));
dest[i + 2] = q_multsr_sat_32x32(src[i + 2], cd-
volume[2],
Q_SHIFT_BITS_64(31,
16, 31));
dest[i + 3] = q_multsr_sat_32x32(src[i + 3], cd-
volume[3],
Q_SHIFT_BITS_64(31,
16, 31));
dest[i + 4] = q_multsr_sat_32x32(src[i + 4], cd-
volume[4],
Q_SHIFT_BITS_64(31,
16, 31));
dest[i + 5] = q_multsr_sat_32x32(src[i + 5], cd-
volume[5],
Q_SHIFT_BITS_64(31,
16, 31));
dest[i + 6] = q_multsr_sat_32x32(src[i + 6], cd-
volume[6],
Q_SHIFT_BITS_64(31,
16, 31));
dest[i + 7] = q_multsr_sat_32x32(src[i + 7], cd-
volume[7],
Q_SHIFT_BITS_64(31,
16, 31));
- }
+}
+/* copy and scale volume from 16 bit source buffer to 16 bit dest buffer */ +static void vol_s16_to_s16_8ch(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;
- int16_t *dest = (int16_t *)sink->w_ptr;
- int32_t i;
- /* buffer sizes are always divisible by period frames */
- /* Samples are Q1.15 --> Q1.15 and volume is Q1.16 */
- for (i = 0; i < frames * 8; i += 8) {
dest[i] = q_multsr_sat_16x16(src[i], cd->volume[0],
Q_SHIFT_BITS_32(15, 16,
15));
dest[i + 1] = q_multsr_sat_16x16(src[i + 1], cd-
volume[1],
Q_SHIFT_BITS_32(15,
16, 15));
dest[i + 2] = q_multsr_sat_16x16(src[i + 2], cd-
volume[2],
Q_SHIFT_BITS_32(15,
16, 15));
dest[i + 3] = q_multsr_sat_16x16(src[i + 3], cd-
volume[3],
Q_SHIFT_BITS_32(15,
16, 15));
dest[i + 4] = q_multsr_sat_16x16(src[i + 4], cd-
volume[4],
Q_SHIFT_BITS_32(15,
16, 15));
dest[i + 5] = q_multsr_sat_16x16(src[i + 5], cd-
volume[5],
Q_SHIFT_BITS_32(15,
16, 15));
dest[i + 6] = q_multsr_sat_16x16(src[i + 6], cd-
volume[6],
Q_SHIFT_BITS_32(15,
16, 15));
dest[i + 7] = q_multsr_sat_16x16(src[i + 7], cd-
volume[7],
Q_SHIFT_BITS_32(15,
16, 15));
- }
+}
+/* copy and scale volume from 16 bit source buffer to 24 bit
- on 32 bit boundary buffer
- */
+static void vol_s16_to_s24_8ch(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 *dest = (int32_t *)sink->w_ptr;
- int32_t i;
- /* buffer sizes are always divisible by period frames */
- /* Samples are Q1.15 and volume is Q1.16 */
- for (i = 0; i < frames * 8; i += 8) {
dest[i] = q_multsr_sat_32x32(src[i], cd->volume[0],
Q_SHIFT_BITS_64(15, 16,
23));
dest[i + 1] = q_multsr_sat_32x32(src[i + 1], cd-
volume[1],
Q_SHIFT_BITS_64(15,
16, 23));
dest[i + 2] = q_multsr_sat_32x32(src[i + 2], cd-
volume[2],
Q_SHIFT_BITS_64(15,
16, 23));
dest[i + 3] = q_multsr_sat_32x32(src[i + 3], cd-
volume[3],
Q_SHIFT_BITS_64(15,
16, 23));
dest[i + 4] = q_multsr_sat_32x32(src[i + 4], cd-
volume[4],
Q_SHIFT_BITS_64(15,
16, 23));
dest[i + 5] = q_multsr_sat_32x32(src[i + 5], cd-
volume[5],
Q_SHIFT_BITS_64(15,
16, 23));
dest[i + 6] = q_multsr_sat_32x32(src[i + 6], cd-
volume[6],
Q_SHIFT_BITS_64(15,
16, 23));
dest[i + 7] = q_multsr_sat_32x32(src[i + 7], cd-
volume[7],
Q_SHIFT_BITS_64(15,
16, 23));
- }
+}
+/* copy and scale volume from 16 bit source buffer to 24 bit
- on 32 bit boundary dest buffer
- */
+static void vol_s24_to_s16_8ch(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 *src = (int32_t *)source->r_ptr;
- int16_t *dest = (int16_t *)sink->w_ptr;
- int32_t i, sample;
- /* buffer sizes are always divisible by period frames */
- /* Samples are Q1.23 --> Q1.15 and volume is Q1.16 */
- for (i = 0; i < frames * 8; i += 8) {
sample = sign_extend_s24(src[i]);
dest[i] = (int16_t)q_multsr_sat_32x32(sample, cd-
volume[0],
Q_SHIFT_BITS_6
4(23, 16,
15));
sample = sign_extend_s24(src[i + 1]);
dest[i + 1] = (int16_t)q_multsr_sat_32x32(sample,
cd-
volume[1],
Q_SHIFT_BI
TS_64(23,
16,
15));
sample = sign_extend_s24(src[i + 2]);
dest[i + 2] = (int16_t)q_multsr_sat_32x32(sample,
cd-
volume[2],
Q_SHIFT_BI
TS_64(23,
16,
15));
sample = sign_extend_s24(src[i + 3]);
dest[i + 3] = (int16_t)q_multsr_sat_32x32(sample,
cd-
volume[3],
Q_SHIFT_BI
TS_64(23,
16,
15));
sample = sign_extend_s24(src[i + 4]);
dest[i + 4] = (int16_t)q_multsr_sat_32x32(sample,
cd-
volume[4],
Q_SHIFT_BI
TS_64(23,
16,
15));
sample = sign_extend_s24(src[i + 5]);
dest[i + 5] = (int16_t)q_multsr_sat_32x32(sample,
cd-
volume[5],
Q_SHIFT_BI
TS_64(23,
16,
15));
sample = sign_extend_s24(src[i + 6]);
dest[i + 6] = (int16_t)q_multsr_sat_32x32(sample,
cd-
volume[6],
Q_SHIFT_BI
TS_64(23,
16,
15));
sample = sign_extend_s24(src[i + 7]);
dest[i + 7] = (int16_t)q_multsr_sat_32x32(sample,
cd-
volume[7],
Q_SHIFT_BI
TS_64(23,
16,
15));
- }
+}
+/* copy and scale volume from 32 bit source buffer to 24 bit
- on 32 bit boundary dest buffer
- */
+static void vol_s32_to_s24_8ch(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 *src = (int32_t *)source->r_ptr;
- int32_t *dest = (int32_t *)sink->w_ptr;
- int32_t i;
- /* buffer sizes are always divisible by period frames */
- /* Samples are Q1.31 --> Q1.23 and volume is Q1.16 */
- for (i = 0; i < frames * 8; i += 8) {
dest[i] = q_multsr_sat_32x32(src[i], cd->volume[0],
Q_SHIFT_BITS_64(31, 16,
23));
dest[i + 1] = q_multsr_sat_32x32(src[i + 1], cd-
volume[1],
Q_SHIFT_BITS_64(31,
16, 23));
dest[i + 2] = q_multsr_sat_32x32(src[i + 2], cd-
volume[2],
Q_SHIFT_BITS_64(31,
16, 23));
dest[i + 3] = q_multsr_sat_32x32(src[i + 3], cd-
volume[3],
Q_SHIFT_BITS_64(31,
16, 23));
dest[i + 4] = q_multsr_sat_32x32(src[i + 4], cd-
volume[4],
Q_SHIFT_BITS_64(31,
16, 23));
dest[i + 5] = q_multsr_sat_32x32(src[i + 5], cd-
volume[5],
Q_SHIFT_BITS_64(31,
16, 23));
dest[i + 6] = q_multsr_sat_32x32(src[i + 6], cd-
volume[6],
Q_SHIFT_BITS_64(31,
16, 23));
dest[i + 7] = q_multsr_sat_32x32(src[i + 7], cd-
volume[7],
Q_SHIFT_BITS_64(31,
16, 23));
- }
+}
+/* copy and scale volume from 16 bit source buffer to 24 bit
- on 32 bit boundary dest buffer
- */
+static void vol_s24_to_s32_8ch(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 *src = (int32_t *)source->r_ptr;
- int32_t *dest = (int32_t *)sink->w_ptr;
- int32_t i;
- /* buffer sizes are always divisible by period frames */
- /* Samples are Q1.23 --> Q1.31 and volume is Q1.16 */
- for (i = 0; i < frames * 8; i += 8) {
dest[i] =
q_multsr_sat_32x32(sign_extend_s24(src[i]),
cd->volume[0],
Q_SHIFT_BITS_64(23, 16,
31));
dest[i + 1] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 1]),
cd->volume[1],
Q_SHIFT_BITS_64(23,
16, 31));
dest[i + 2] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 2]),
cd->volume[2],
Q_SHIFT_BITS_64(23,
16, 31));
dest[i + 3] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 3]),
cd->volume[3],
Q_SHIFT_BITS_64(23,
16, 31));
dest[i + 4] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 4]),
cd->volume[4],
Q_SHIFT_BITS_64(23,
16, 31));
dest[i + 5] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 5]),
cd->volume[5],
Q_SHIFT_BITS_64(23,
16, 31));
dest[i + 6] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 6]),
cd->volume[6],
Q_SHIFT_BITS_64(23,
16, 31));
dest[i + 7] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 7]),
cd->volume[7],
Q_SHIFT_BITS_64(23,
16, 31));
- }
+}
+/* Copy and scale volume from 24 bit source buffer to 24 bit on 32 bit boundary
- dest buffer.
- */
+static void vol_s24_to_s24_8ch(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 i, *src = (int32_t *)source->r_ptr;
- int32_t *dest = (int32_t *)sink->w_ptr;
- /* buffer sizes are always divisible by period frames */
- /* Samples are Q1.23 --> Q1.23 and volume is Q1.16 */
- for (i = 0; i < frames * 8; i += 8) {
dest[i] =
q_multsr_sat_32x32(sign_extend_s24(src[i]),
cd->volume[0],
Q_SHIFT_BITS_64(23, 16,
23));
dest[i + 1] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 1]),
cd->volume[1],
Q_SHIFT_BITS_64(23,
16, 23));
dest[i + 2] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 2]),
cd->volume[2],
Q_SHIFT_BITS_64(23,
16, 23));
dest[i + 3] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 3]),
cd->volume[3],
Q_SHIFT_BITS_64(23,
16, 23));
dest[i + 4] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 4]),
cd->volume[4],
Q_SHIFT_BITS_64(23,
16, 23));
dest[i + 5] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 5]),
cd->volume[5],
Q_SHIFT_BITS_64(23,
16, 23));
dest[i + 6] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 6]),
cd->volume[6],
Q_SHIFT_BITS_64(23,
16, 23));
dest[i + 7] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 7]),
cd->volume[7],
Q_SHIFT_BITS_64(23,
16, 23));
- }
+}
/* map of source and sink buffer formats to volume function */ static const struct comp_func_map func_map[] = { {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, 2, vol_s16_to_s16_2ch}, @@ -535,6 +885,15 @@ static const struct comp_func_map func_map[] = { {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, 4, vol_s32_to_s24_4ch}, {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, 4, vol_s24_to_s32_4ch}, {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S24_4LE, 4, vol_s24_to_s24_4ch},
- {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, 8,
vol_s16_to_s16_8ch},
- {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, 8,
vol_s16_to_s32_8ch},
- {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, 8,
vol_s32_to_s16_8ch},
- {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, 8,
vol_s32_to_s32_8ch},
- {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S24_4LE, 8,
vol_s16_to_s24_8ch},
- {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S16_LE, 8,
vol_s24_to_s16_8ch},
- {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, 8,
vol_s32_to_s24_8ch},
- {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, 8,
vol_s24_to_s32_8ch},
- {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S24_4LE, 8,
vol_s24_to_s24_8ch}, };
/* synchronise host mmap() volume with real value */
On 2018年06月13日 14:00, Ranjani Sridharan wrote:
On Wed, 2018-06-13 at 13:47 +0800, Wu Zhigang wrote:
add the 8-channel feature for the capture function on apl-gpmrb.
Zhigang, Seppo and I ran into issues even with the 4-ch volume functions when compiling with xt-xcc on BYT. I forgot the details but i think we were exceeding the data section. Have you tried xt-xcc with this patch?
Could we possibly define these under #if defined(CONFIG_APOLLOLAKE)? to maybe avoid that situation?
I did not try the xt-xcc compiling on my platform. I have not installed the xt-xcc on my platform. I did not hit this issue with old compiler. I will add this macro for specific apl platform in V2. thanks ~zhigang
Signed-off-by: Wu Zhigang zhigang.wu@linux.intel.com Reviewed-by: Keyon Jie yang.jie@linux.intel.com
Test with: apl-gpmrb with tdf8532 codec
linux topic/sof-dev: 1e0f50565669815dd7daa19021b3b04a90487431 sof master: b0affc18c3068225e766190aa81cad1ddb082457 soft master: 2cc3ad2a9287e8354ae9f7dc5161d7f4d4539949
Pass the regression test already: Minnowboard Turbo UP^2 CNL-RVP
src/audio/volume.c | 359 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 359 insertions(+)
diff --git a/src/audio/volume.c b/src/audio/volume.c index d0b690b..7c2044a 100644 --- a/src/audio/volume.c +++ b/src/audio/volume.c @@ -515,6 +515,356 @@ static void vol_s24_to_s24_4ch(struct comp_dev *dev, struct comp_buffer *sink, } }
+/* volume scaling functions for 8-channel input */
+/* copy and scale volume from 16 bit source buffer to 32 bit dest buffer */ +static void vol_s16_to_s32_8ch(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 *dest = (int32_t *)sink->w_ptr;
- int32_t i;
- /* buffer sizes are always divisible by period frames */
- /* Samples are Q1.15 --> Q1.31 and volume is Q1.16 */
- for (i = 0; i < frames * 8; i += 8) {
dest[i] = (int32_t)src[i] * cd->volume[0];
dest[i + 1] = (int32_t)src[i + 1] * cd->volume[1];
dest[i + 2] = (int32_t)src[i + 2] * cd->volume[2];
dest[i + 3] = (int32_t)src[i + 3] * cd->volume[3];
dest[i + 4] = (int32_t)src[i + 4] * cd->volume[4];
dest[i + 5] = (int32_t)src[i + 5] * cd->volume[5];
dest[i + 6] = (int32_t)src[i + 6] * cd->volume[6];
dest[i + 7] = (int32_t)src[i + 7] * cd->volume[7];
- }
+}
+/* copy and scale volume from 32 bit source buffer to 16 bit dest buffer */ +static void vol_s32_to_s16_8ch(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 *src = (int32_t *)source->r_ptr;
- int16_t *dest = (int16_t *)sink->w_ptr;
- int32_t i;
- /* buffer sizes are always divisible by period frames */
- /* Samples are Q1.31 --> Q1.15 and volume is Q1.16 */
- for (i = 0; i < frames * 8; i += 8) {
dest[i] = (int16_t)q_multsr_sat_32x32(src[i], cd-
volume[0],
Q_SHIFT_BITS_6
4(31, 16,
15));
dest[i + 1] = (int16_t)q_multsr_sat_32x32(src[i +
1],
cd-
volume[1],
Q_SHIFT_BI
TS_64(31,
16,
15));
dest[i + 2] = (int16_t)q_multsr_sat_32x32(src[i +
2],
cd-
volume[2],
Q_SHIFT_BI
TS_64(31,
16,
15));
dest[i + 3] = (int16_t)q_multsr_sat_32x32(src[i +
3],
cd-
volume[3],
Q_SHIFT_BI
TS_64(31,
16,
15));
dest[i + 4] = (int16_t)q_multsr_sat_32x32(src[i +
4],
cd-
volume[4],
Q_SHIFT_BI
TS_64(31,
16,
15));
dest[i + 5] = (int16_t)q_multsr_sat_32x32(src[i +
5],
cd-
volume[5],
Q_SHIFT_BI
TS_64(31,
16,
15));
dest[i + 6] = (int16_t)q_multsr_sat_32x32(src[i +
6],
cd-
volume[6],
Q_SHIFT_BI
TS_64(31,
16,
15));
dest[i + 7] = (int16_t)q_multsr_sat_32x32(src[i +
7],
cd-
volume[7],
Q_SHIFT_BI
TS_64(31,
16,
15));
- }
+}
+/* copy and scale volume from 32 bit source buffer to 32 bit dest buffer */ +static void vol_s32_to_s32_8ch(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 *src = (int32_t *)source->r_ptr;
- int32_t *dest = (int32_t *)sink->w_ptr;
- int32_t i;
- /* buffer sizes are always divisible by period frames */
- /* Samples are Q1.31 --> Q1.31 and volume is Q1.16 */
- for (i = 0; i < frames * 8; i += 8) {
dest[i] = q_multsr_sat_32x32(src[i], cd->volume[0],
Q_SHIFT_BITS_64(31, 16,
31));
dest[i + 1] = q_multsr_sat_32x32(src[i + 1], cd-
volume[1],
Q_SHIFT_BITS_64(31,
16, 31));
dest[i + 2] = q_multsr_sat_32x32(src[i + 2], cd-
volume[2],
Q_SHIFT_BITS_64(31,
16, 31));
dest[i + 3] = q_multsr_sat_32x32(src[i + 3], cd-
volume[3],
Q_SHIFT_BITS_64(31,
16, 31));
dest[i + 4] = q_multsr_sat_32x32(src[i + 4], cd-
volume[4],
Q_SHIFT_BITS_64(31,
16, 31));
dest[i + 5] = q_multsr_sat_32x32(src[i + 5], cd-
volume[5],
Q_SHIFT_BITS_64(31,
16, 31));
dest[i + 6] = q_multsr_sat_32x32(src[i + 6], cd-
volume[6],
Q_SHIFT_BITS_64(31,
16, 31));
dest[i + 7] = q_multsr_sat_32x32(src[i + 7], cd-
volume[7],
Q_SHIFT_BITS_64(31,
16, 31));
- }
+}
+/* copy and scale volume from 16 bit source buffer to 16 bit dest buffer */ +static void vol_s16_to_s16_8ch(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;
- int16_t *dest = (int16_t *)sink->w_ptr;
- int32_t i;
- /* buffer sizes are always divisible by period frames */
- /* Samples are Q1.15 --> Q1.15 and volume is Q1.16 */
- for (i = 0; i < frames * 8; i += 8) {
dest[i] = q_multsr_sat_16x16(src[i], cd->volume[0],
Q_SHIFT_BITS_32(15, 16,
15));
dest[i + 1] = q_multsr_sat_16x16(src[i + 1], cd-
volume[1],
Q_SHIFT_BITS_32(15,
16, 15));
dest[i + 2] = q_multsr_sat_16x16(src[i + 2], cd-
volume[2],
Q_SHIFT_BITS_32(15,
16, 15));
dest[i + 3] = q_multsr_sat_16x16(src[i + 3], cd-
volume[3],
Q_SHIFT_BITS_32(15,
16, 15));
dest[i + 4] = q_multsr_sat_16x16(src[i + 4], cd-
volume[4],
Q_SHIFT_BITS_32(15,
16, 15));
dest[i + 5] = q_multsr_sat_16x16(src[i + 5], cd-
volume[5],
Q_SHIFT_BITS_32(15,
16, 15));
dest[i + 6] = q_multsr_sat_16x16(src[i + 6], cd-
volume[6],
Q_SHIFT_BITS_32(15,
16, 15));
dest[i + 7] = q_multsr_sat_16x16(src[i + 7], cd-
volume[7],
Q_SHIFT_BITS_32(15,
16, 15));
- }
+}
+/* copy and scale volume from 16 bit source buffer to 24 bit
- on 32 bit boundary buffer
- */
+static void vol_s16_to_s24_8ch(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 *dest = (int32_t *)sink->w_ptr;
- int32_t i;
- /* buffer sizes are always divisible by period frames */
- /* Samples are Q1.15 and volume is Q1.16 */
- for (i = 0; i < frames * 8; i += 8) {
dest[i] = q_multsr_sat_32x32(src[i], cd->volume[0],
Q_SHIFT_BITS_64(15, 16,
23));
dest[i + 1] = q_multsr_sat_32x32(src[i + 1], cd-
volume[1],
Q_SHIFT_BITS_64(15,
16, 23));
dest[i + 2] = q_multsr_sat_32x32(src[i + 2], cd-
volume[2],
Q_SHIFT_BITS_64(15,
16, 23));
dest[i + 3] = q_multsr_sat_32x32(src[i + 3], cd-
volume[3],
Q_SHIFT_BITS_64(15,
16, 23));
dest[i + 4] = q_multsr_sat_32x32(src[i + 4], cd-
volume[4],
Q_SHIFT_BITS_64(15,
16, 23));
dest[i + 5] = q_multsr_sat_32x32(src[i + 5], cd-
volume[5],
Q_SHIFT_BITS_64(15,
16, 23));
dest[i + 6] = q_multsr_sat_32x32(src[i + 6], cd-
volume[6],
Q_SHIFT_BITS_64(15,
16, 23));
dest[i + 7] = q_multsr_sat_32x32(src[i + 7], cd-
volume[7],
Q_SHIFT_BITS_64(15,
16, 23));
- }
+}
+/* copy and scale volume from 16 bit source buffer to 24 bit
- on 32 bit boundary dest buffer
- */
+static void vol_s24_to_s16_8ch(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 *src = (int32_t *)source->r_ptr;
- int16_t *dest = (int16_t *)sink->w_ptr;
- int32_t i, sample;
- /* buffer sizes are always divisible by period frames */
- /* Samples are Q1.23 --> Q1.15 and volume is Q1.16 */
- for (i = 0; i < frames * 8; i += 8) {
sample = sign_extend_s24(src[i]);
dest[i] = (int16_t)q_multsr_sat_32x32(sample, cd-
volume[0],
Q_SHIFT_BITS_6
4(23, 16,
15));
sample = sign_extend_s24(src[i + 1]);
dest[i + 1] = (int16_t)q_multsr_sat_32x32(sample,
cd-
volume[1],
Q_SHIFT_BI
TS_64(23,
16,
15));
sample = sign_extend_s24(src[i + 2]);
dest[i + 2] = (int16_t)q_multsr_sat_32x32(sample,
cd-
volume[2],
Q_SHIFT_BI
TS_64(23,
16,
15));
sample = sign_extend_s24(src[i + 3]);
dest[i + 3] = (int16_t)q_multsr_sat_32x32(sample,
cd-
volume[3],
Q_SHIFT_BI
TS_64(23,
16,
15));
sample = sign_extend_s24(src[i + 4]);
dest[i + 4] = (int16_t)q_multsr_sat_32x32(sample,
cd-
volume[4],
Q_SHIFT_BI
TS_64(23,
16,
15));
sample = sign_extend_s24(src[i + 5]);
dest[i + 5] = (int16_t)q_multsr_sat_32x32(sample,
cd-
volume[5],
Q_SHIFT_BI
TS_64(23,
16,
15));
sample = sign_extend_s24(src[i + 6]);
dest[i + 6] = (int16_t)q_multsr_sat_32x32(sample,
cd-
volume[6],
Q_SHIFT_BI
TS_64(23,
16,
15));
sample = sign_extend_s24(src[i + 7]);
dest[i + 7] = (int16_t)q_multsr_sat_32x32(sample,
cd-
volume[7],
Q_SHIFT_BI
TS_64(23,
16,
15));
- }
+}
+/* copy and scale volume from 32 bit source buffer to 24 bit
- on 32 bit boundary dest buffer
- */
+static void vol_s32_to_s24_8ch(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 *src = (int32_t *)source->r_ptr;
- int32_t *dest = (int32_t *)sink->w_ptr;
- int32_t i;
- /* buffer sizes are always divisible by period frames */
- /* Samples are Q1.31 --> Q1.23 and volume is Q1.16 */
- for (i = 0; i < frames * 8; i += 8) {
dest[i] = q_multsr_sat_32x32(src[i], cd->volume[0],
Q_SHIFT_BITS_64(31, 16,
23));
dest[i + 1] = q_multsr_sat_32x32(src[i + 1], cd-
volume[1],
Q_SHIFT_BITS_64(31,
16, 23));
dest[i + 2] = q_multsr_sat_32x32(src[i + 2], cd-
volume[2],
Q_SHIFT_BITS_64(31,
16, 23));
dest[i + 3] = q_multsr_sat_32x32(src[i + 3], cd-
volume[3],
Q_SHIFT_BITS_64(31,
16, 23));
dest[i + 4] = q_multsr_sat_32x32(src[i + 4], cd-
volume[4],
Q_SHIFT_BITS_64(31,
16, 23));
dest[i + 5] = q_multsr_sat_32x32(src[i + 5], cd-
volume[5],
Q_SHIFT_BITS_64(31,
16, 23));
dest[i + 6] = q_multsr_sat_32x32(src[i + 6], cd-
volume[6],
Q_SHIFT_BITS_64(31,
16, 23));
dest[i + 7] = q_multsr_sat_32x32(src[i + 7], cd-
volume[7],
Q_SHIFT_BITS_64(31,
16, 23));
- }
+}
+/* copy and scale volume from 16 bit source buffer to 24 bit
- on 32 bit boundary dest buffer
- */
+static void vol_s24_to_s32_8ch(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 *src = (int32_t *)source->r_ptr;
- int32_t *dest = (int32_t *)sink->w_ptr;
- int32_t i;
- /* buffer sizes are always divisible by period frames */
- /* Samples are Q1.23 --> Q1.31 and volume is Q1.16 */
- for (i = 0; i < frames * 8; i += 8) {
dest[i] =
q_multsr_sat_32x32(sign_extend_s24(src[i]),
cd->volume[0],
Q_SHIFT_BITS_64(23, 16,
31));
dest[i + 1] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 1]),
cd->volume[1],
Q_SHIFT_BITS_64(23,
16, 31));
dest[i + 2] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 2]),
cd->volume[2],
Q_SHIFT_BITS_64(23,
16, 31));
dest[i + 3] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 3]),
cd->volume[3],
Q_SHIFT_BITS_64(23,
16, 31));
dest[i + 4] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 4]),
cd->volume[4],
Q_SHIFT_BITS_64(23,
16, 31));
dest[i + 5] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 5]),
cd->volume[5],
Q_SHIFT_BITS_64(23,
16, 31));
dest[i + 6] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 6]),
cd->volume[6],
Q_SHIFT_BITS_64(23,
16, 31));
dest[i + 7] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 7]),
cd->volume[7],
Q_SHIFT_BITS_64(23,
16, 31));
- }
+}
+/* Copy and scale volume from 24 bit source buffer to 24 bit on 32 bit boundary
- dest buffer.
- */
+static void vol_s24_to_s24_8ch(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 i, *src = (int32_t *)source->r_ptr;
- int32_t *dest = (int32_t *)sink->w_ptr;
- /* buffer sizes are always divisible by period frames */
- /* Samples are Q1.23 --> Q1.23 and volume is Q1.16 */
- for (i = 0; i < frames * 8; i += 8) {
dest[i] =
q_multsr_sat_32x32(sign_extend_s24(src[i]),
cd->volume[0],
Q_SHIFT_BITS_64(23, 16,
23));
dest[i + 1] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 1]),
cd->volume[1],
Q_SHIFT_BITS_64(23,
16, 23));
dest[i + 2] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 2]),
cd->volume[2],
Q_SHIFT_BITS_64(23,
16, 23));
dest[i + 3] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 3]),
cd->volume[3],
Q_SHIFT_BITS_64(23,
16, 23));
dest[i + 4] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 4]),
cd->volume[4],
Q_SHIFT_BITS_64(23,
16, 23));
dest[i + 5] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 5]),
cd->volume[5],
Q_SHIFT_BITS_64(23,
16, 23));
dest[i + 6] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 6]),
cd->volume[6],
Q_SHIFT_BITS_64(23,
16, 23));
dest[i + 7] =
q_multsr_sat_32x32(sign_extend_s24(src[i + 7]),
cd->volume[7],
Q_SHIFT_BITS_64(23,
16, 23));
- }
+}
- /* map of source and sink buffer formats to volume function */ static const struct comp_func_map func_map[] = { {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, 2,
vol_s16_to_s16_2ch}, @@ -535,6 +885,15 @@ static const struct comp_func_map func_map[] = { {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, 4, vol_s32_to_s24_4ch}, {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, 4, vol_s24_to_s32_4ch}, {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S24_4LE, 4, vol_s24_to_s24_4ch},
- {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, 8,
vol_s16_to_s16_8ch},
- {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, 8,
vol_s16_to_s32_8ch},
- {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, 8,
vol_s32_to_s16_8ch},
- {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, 8,
vol_s32_to_s32_8ch},
- {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S24_4LE, 8,
vol_s16_to_s24_8ch},
- {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S16_LE, 8,
vol_s24_to_s16_8ch},
- {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, 8,
vol_s32_to_s24_8ch},
- {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, 8,
vol_s24_to_s32_8ch},
- {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S24_4LE, 8,
vol_s24_to_s24_8ch}, };
/* synchronise host mmap() volume with real value */
On Tue, 2018-06-12 at 23:00 -0700, Ranjani Sridharan wrote:
On Wed, 2018-06-13 at 13:47 +0800, Wu Zhigang wrote:
add the 8-channel feature for the capture function on apl-gpmrb.
Zhigang, Seppo and I ran into issues even with the 4-ch volume functions when compiling with xt-xcc on BYT. I forgot the details but i think we were exceeding the data section. Have you tried xt-xcc with this patch?
Could we possibly define these under #if defined(CONFIG_APOLLOLAKE)? to maybe avoid that situation?
Looks like a workaround that wont work for other platforms, better to increase the data section size.
Zhigang, please work on something for a few days else as Thomasz has some HiFi3 volume updates that do 8 channels iirc, we would want to merge your patch on top.
Thanks
Liam
On 2018年06月13日 15:39, Liam Girdwood wrote:
On Tue, 2018-06-12 at 23:00 -0700, Ranjani Sridharan wrote:
On Wed, 2018-06-13 at 13:47 +0800, Wu Zhigang wrote:
add the 8-channel feature for the capture function on apl-gpmrb.
Zhigang, Seppo and I ran into issues even with the 4-ch volume functions when compiling with xt-xcc on BYT. I forgot the details but i think we were exceeding the data section. Have you tried xt-xcc with this patch?
Could we possibly define these under #if defined(CONFIG_APOLLOLAKE)? to maybe avoid that situation?
Looks like a workaround that wont work for other platforms, better to increase the data section size.
Zhigang, please work on something for a few days else as Thomasz has some HiFi3 volume updates that do 8 channels iirc, we would want to merge your patch on top.
Thanks
Liam
OK! Thanks ~zhigang
Sound-open-firmware mailing list Sound-open-firmware@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/sound-open-firmware
participants (4)
-
Liam Girdwood
-
Ranjani Sridharan
-
Wu Zhigang
-
zhigangw