From f337d5b320867c74672f517c87543acaa447278c Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Tue, 2 Jul 2019 03:05:33 +0800 Subject: audio_codec: integrate speech-micro Leverage speech-micro to detect hotword. BRANCH=none BUG=b:122027734, b:123268236, b:132319180 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: I8b238fd8bd9af8e70d5a747650eb8b7dbf4200cb Signed-off-by: Tzung-Bi Shih Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1602453 Reviewed-by: Nicolas Boichat --- common/audio_codec_wov.c | 39 +++++++++++++++++++++++++++++++++++++++ common/build.mk | 4 ++++ common/hotword_dsp_api.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 common/hotword_dsp_api.c (limited to 'common') diff --git a/common/audio_codec_wov.c b/common/audio_codec_wov.c index 3609967d9d..30ffe98836 100644 --- a/common/audio_codec_wov.c +++ b/common/audio_codec_wov.c @@ -7,6 +7,7 @@ #include "audio_codec.h" #include "console.h" #include "host_command.h" +#include "hotword_dsp_api.h" #include "sha256.h" #include "system.h" #include "task.h" @@ -60,6 +61,9 @@ static int is_buf_full(void) return ((audio_buf_wp + 2) % AUDIO_BUF_LEN) == audio_buf_rp; } +/* only used by host command */ +static uint8_t speech_lib_loaded; + static int check_lang_buf(uint8_t *data, uint32_t len, const uint8_t *hash) { /* @@ -108,6 +112,7 @@ static int wov_set_lang_shm(struct host_cmd_handler_args *args) memcpy(lang_hash, pp->hash, sizeof(lang_hash)); lang_len = pp->total_len; + speech_lib_loaded = 0; args->response_size = 0; return EC_RES_SUCCESS; @@ -143,6 +148,7 @@ static int wov_set_lang(struct host_cmd_handler_args *args) memcpy(lang_hash, pp->hash, sizeof(lang_hash)); lang_len = pp->total_len; + speech_lib_loaded = 0; } args->response_size = 0; @@ -168,6 +174,15 @@ static int wov_enable(struct host_cmd_handler_args *args) if (audio_codec_wov_enable() != EC_SUCCESS) return EC_RES_ERROR; + if (!speech_lib_loaded) { + if (!GoogleHotwordDspInit( + (void *)audio_codec_wov_lang_buf_addr)) + return EC_RES_ERROR; + speech_lib_loaded = 1; + } else { + GoogleHotwordDspReset(); + } + mutex_lock(&lock); wov_enabled = 1; hotword_detected = 0; @@ -334,6 +349,7 @@ void audio_codec_wov_task(void *arg) { uint32_t n, req; uint8_t *p; + int r; while (1) { mutex_lock(&lock); @@ -394,6 +410,29 @@ void audio_codec_wov_task(void *arg) audio_buf_wp = 0; mutex_unlock(&lock); + /* + * GoogleHotwordDspProcess() needs number of samples. In the + * case, sample is S16_LE. Thus, n / 2. + */ + if (!hotword_detected && + GoogleHotwordDspProcess(p, n / 2, &r)) { + CPRINTS("hotword detected"); + + mutex_lock(&lock); + /* + * Note: preserve 40% of buf size for AP to read + * (see go/cros-ec-codec#heading=h.582ga6pgfl2g) + */ + audio_buf_rp = audio_buf_wp + (AUDIO_BUF_LEN * 2 / 5); + if (audio_buf_rp >= AUDIO_BUF_LEN) + audio_buf_rp -= AUDIO_BUF_LEN; + + hotword_detected = 1; + mutex_unlock(&lock); + + host_set_single_event(EC_HOST_EVENT_WOV); + } + /* * Reasons to sleep here: * 1. read the audio data in a fixed pace (10ms) diff --git a/common/build.mk b/common/build.mk index 4475873eec..7ee4e102a4 100644 --- a/common/build.mk +++ b/common/build.mk @@ -164,6 +164,10 @@ common-$(HAS_TASK_LIGHTBAR)+=lb_common.o lightbar.o common-$(HAS_TASK_MOTIONSENSE)+=motion_sense.o common-$(HAS_TASK_TPM)+=tpm_registers.o +ifneq ($(HAVE_PRIVATE_AUDIO_CODEC_WOV_LIBS),y) +common-$(CONFIG_AUDIO_CODEC_WOV)+=hotword_dsp_api.o +endif + ifneq ($(CONFIG_COMMON_RUNTIME),) common-$(CONFIG_MALLOC)+=shmalloc.o common-$(call not_cfg,$(CONFIG_MALLOC))+=shared_mem.o diff --git a/common/hotword_dsp_api.c b/common/hotword_dsp_api.c new file mode 100644 index 0000000000..dc53cd0055 --- /dev/null +++ b/common/hotword_dsp_api.c @@ -0,0 +1,35 @@ +/* + * Copyright 2019 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "audio_codec.h" +#include "hotword_dsp_api.h" + +const int kGoogleHotwordRequiredDataAlignment = 4; + +int GoogleHotwordDspInit(void *hotword_memmap) +{ + return 1; +} + +int GoogleHotwordDspProcess(const void *samples, int num_samples, + int *preamble_length_ms) +{ + return 0; +} + +void GoogleHotwordDspReset(void) +{ +} + +int GoogleHotwordDspGetMaximumAudioPreambleMs(void) +{ + return 0; +} + +int GoogleHotwordVersion(void) +{ + return 0; +} -- cgit v1.2.1