From 8fe3e6a850f06b499cc60834a925736ce95171d9 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Sat, 29 Jun 2019 07:25:46 +0800 Subject: chip/mt_scp: support software gain Multiply the audio data by a gain value. Note that it get muted when gain is 0. BRANCH=none BUG=b:122027734, b:123268236 TEST=1. define CONFIG_AUDIO_CODEC in board.h 2. define CONFIG_AUDIO_CODEC_DMIC in board.h 3. define CONFIG_AUDIO_CODEC_DMIC_SOFTWARE_GAIN in board.h 4. define CONFIG_AUDIO_CODEC_DMIC_MAX_SOFTWARE_GAIN in board.h 5. define CONFIG_AUDIO_CODEC_WOV in board.h 6. make BOARD=kukui_scp -j Change-Id: I8c308ffb6d7c8f5bd378524bdffc980d7b9948fa Signed-off-by: Tzung-Bi Shih Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1683028 Reviewed-by: Nicolas Boichat --- builtin/stdint.h | 3 +++ chip/mt_scp/audio_codec_wov.c | 13 +++++++++++-- common/audio_codec.c | 11 +++++++++++ include/audio_codec.h | 5 +++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/builtin/stdint.h b/builtin/stdint.h index ada936c2d3..dedc9de475 100644 --- a/builtin/stdint.h +++ b/builtin/stdint.h @@ -57,6 +57,9 @@ typedef int64_t int_fast64_t; #ifndef INT16_MAX #define INT16_MAX (32767U) #endif +#ifndef INT16_MIN +#define INT16_MIN (-32768) +#endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) diff --git a/chip/mt_scp/audio_codec_wov.c b/chip/mt_scp/audio_codec_wov.c index bff8f776b7..0a4684f909 100644 --- a/chip/mt_scp/audio_codec_wov.c +++ b/chip/mt_scp/audio_codec_wov.c @@ -69,11 +69,20 @@ static size_t wov_fifo_level(void) int32_t audio_codec_wov_read(void *buf, uint32_t count) { int16_t *out = buf; + uint8_t gain = 1; + + if (IS_ENABLED(CONFIG_AUDIO_CODEC_DMIC_SOFTWARE_GAIN)) + audio_codec_dmic_get_gain_idx(0, &gain); count >>= 1; - while (count-- && wov_fifo_level()) - *out++ = SCP_VIF_FIFO_DATA; + while (count-- && wov_fifo_level()) { + if (IS_ENABLED(CONFIG_AUDIO_CODEC_DMIC_SOFTWARE_GAIN)) + *out++ = audio_codec_s16_scale_and_clip( + SCP_VIF_FIFO_DATA, gain); + else + *out++ = SCP_VIF_FIFO_DATA; + } return (void *)out - buf; } diff --git a/common/audio_codec.c b/common/audio_codec.c index e21df5c039..43ba520707 100644 --- a/common/audio_codec.c +++ b/common/audio_codec.c @@ -7,6 +7,7 @@ #include "audio_codec.h" #include "console.h" #include "host_command.h" +#include "util.h" #define CPRINTS(format, args...) cprints(CC_AUDIO_CODEC, format, ## args) @@ -144,3 +145,13 @@ int audio_codec_memmap_ap_to_ec(uintptr_t ap_addr, uintptr_t *ec_addr) { return EC_ERROR_UNIMPLEMENTED; } + +int16_t audio_codec_s16_scale_and_clip(int16_t orig, uint8_t scalar) +{ + int32_t val; + + val = (int32_t)orig * (int32_t)scalar; + val = MIN(val, (int32_t)INT16_MAX); + val = MAX(val, (int32_t)INT16_MIN); + return val; +} diff --git a/include/audio_codec.h b/include/audio_codec.h index 62009e6c73..b80d1c0f57 100644 --- a/include/audio_codec.h +++ b/include/audio_codec.h @@ -58,6 +58,11 @@ int audio_codec_register_shm(uint8_t shm_id, uint8_t cap, */ int audio_codec_memmap_ap_to_ec(uintptr_t ap_addr, uintptr_t *ec_addr); +/* + * Scales a S16_LE sample by multiplying scalar. + */ +int16_t audio_codec_s16_scale_and_clip(int16_t orig, uint8_t scalar); + /* * DMIC abstract layer -- cgit v1.2.1