add the 8-channel feature for the capture function
for apl-gpmrb platform.
Signed-off-by: Wu Zhigang <zhigang.wu(a)linux.intel.com>
Reviewed-by: Keyon Jie <yang.jie(a)linux.intel.com>
---
v2: rebase the code and make patch.
---
test with:
apl-gpmrb with tdf8532 codec
linux topic/sof-dev: commit 0d51a5ed28c5
sof master: commit 48d2a1c551d7
soft master: commit 2cc3ad2a9287
pass the regression test already:
Minnowboard Turbo
UP^2
CNL-RVP
---
src/audio/volume_generic.c | 363 +++++++++++++++++++++++++++++++++++++
1 file changed, 363 insertions(+)
diff --git a/src/audio/volume_generic.c b/src/audio/volume_generic.c
index 200cf12..fa23240 100644
--- a/src/audio/volume_generic.c
+++ b/src/audio/volume_generic.c
@@ -466,6 +466,358 @@ static void vol_s24_to_s24_4ch(struct comp_dev *dev, struct comp_buffer *sink,
}
}
+#ifdef CONFIG_APOLLOLAKE
+/* 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)
+{
+ 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 < dev->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)
+{
+ 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 < dev->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)
+{
+ 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 < dev->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)
+{
+ 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 < dev->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)
+{
+ 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 < dev->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)
+{
+ 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 < dev->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)
+{
+ 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 < dev->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)
+{
+ 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 < dev->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)
+{
+ 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 < dev->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));
+ }
+}
+#endif
+
const struct comp_func_map func_map[] = {
{SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, 2, vol_s16_to_s16_2ch},
{SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, 2, vol_s16_to_s32_2ch},
@@ -485,6 +837,17 @@ 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},
+#ifdef CONFIG_APOLLOLAKE
+ {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},
+#endif
};
scale_vol vol_get_processing_function(struct comp_dev *dev)
--
2.17.1