210 lines
6 KiB
C++
210 lines
6 KiB
C++
|
/***************************************************************************
|
||
|
*
|
||
|
* Copyright 2015-2019 BES.
|
||
|
* All rights reserved. All unpublished rights reserved.
|
||
|
*
|
||
|
* No part of this work may be used or reproduced in any form or by any
|
||
|
* means, or stored in a database or retrieval system, without prior written
|
||
|
* permission of BES.
|
||
|
*
|
||
|
* Use of this work is governed by a license granted by BES.
|
||
|
* This work contains confidential and proprietary information of
|
||
|
* BES. which is protected by copyright, trade secret,
|
||
|
* trademark and other intellectual property rights.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#include "cmsis_os.h"
|
||
|
#include "cmsis.h"
|
||
|
#include "hal_trace.h"
|
||
|
#include <string.h>
|
||
|
#include "app_utils.h"
|
||
|
#include "hal_timer.h"
|
||
|
#include <assert.h>
|
||
|
|
||
|
// for audio
|
||
|
#include "audioflinger.h"
|
||
|
#include "app_audio.h"
|
||
|
#include "app_bt_stream.h"
|
||
|
#include "app_media_player.h"
|
||
|
#include "speech_ssat.h"
|
||
|
#include "speech_memory.h"
|
||
|
#include "audio_dump.h"
|
||
|
|
||
|
#include "noise_tracker.h"
|
||
|
#include "noise_tracker_callback.h"
|
||
|
|
||
|
|
||
|
/**< NT Engine hooks */
|
||
|
#define NT_ENGINE_INIT(callback, ch, threshold) noise_tracker_init(callback, ch, threshold)
|
||
|
#define NT_ENGINE_FEED(frame, n_samples) noise_tracker_process(frame, n_samples)
|
||
|
|
||
|
|
||
|
/**< NT configuration settings */
|
||
|
#define NT_MIC_BITS_PER_SAMPLE (AUD_BITS_16)
|
||
|
#define NT_MIC_SAMPLE_RATE (16000) // (AUD_SAMPRATE_8000)
|
||
|
#define NT_MIC_VOLUME (16)
|
||
|
|
||
|
|
||
|
/**< NT Engine configuration settings */
|
||
|
#define NT_ENGINE_SAMPLES_PER_FRAME (240)
|
||
|
#define NT_ENGINE_SAMPLE_RATE (16000)
|
||
|
#define NT_ENGINE_SYSFREQ (APP_SYSFREQ_26M) // (APP_SYSFREQ_26M)
|
||
|
|
||
|
|
||
|
/* Utility functions */
|
||
|
#define NT_TRACE(s, ...) TRACE(1,"%s: " s, __FUNCTION__, ## __VA_ARGS__);
|
||
|
#define ALIGN4 __attribute__((aligned(4)))
|
||
|
|
||
|
|
||
|
/* Calcluate the audio-capture frame length, FRAME_LEN, based of decimation rate (1 or 2): */
|
||
|
#define FRAME_LEN (NT_ENGINE_SAMPLES_PER_FRAME * (NT_MIC_SAMPLE_RATE / NT_ENGINE_SAMPLE_RATE))
|
||
|
#define CAPTURE_CHANNEL_NUM (ANC_NOISE_TRACKER_CHANNEL_NUM)
|
||
|
#define CAPTURE_BUF_SIZE (FRAME_LEN * CAPTURE_CHANNEL_NUM * 2 * 2)
|
||
|
static uint8_t codec_capture_buf[CAPTURE_BUF_SIZE] ALIGN4;
|
||
|
|
||
|
STATIC_ASSERT(FRAME_LEN == NT_ENGINE_SAMPLES_PER_FRAME, "NT_ENGINE Config error");
|
||
|
|
||
|
|
||
|
/* Local state */
|
||
|
static bool nt_demo_is_streaming = false;
|
||
|
extern uint8_t bt_sco_mode;
|
||
|
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @breif Handle one-time initialization, like setting up the memory pool
|
||
|
*/
|
||
|
static int nt_demo_init(bool, const void *)
|
||
|
{
|
||
|
static bool done;
|
||
|
|
||
|
NT_TRACE(0,"Initialize kws_demo");
|
||
|
if (done) return 0;
|
||
|
|
||
|
done = true;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief DC block IIR filter
|
||
|
*
|
||
|
* @param inout Pointer of the PCM data (modify inplace).
|
||
|
* @param in_len Length of the PCM data in the buffer in samples.
|
||
|
*
|
||
|
*/
|
||
|
static void filter_iir_dc_block(short *inout, int in_len, int stride)
|
||
|
{
|
||
|
static int z = 0;
|
||
|
int tmp;
|
||
|
|
||
|
for (int i = 0; i < in_len; i += stride)
|
||
|
{
|
||
|
z = (15 * z + inout[i]) >> 4;
|
||
|
tmp = inout[i] - z;
|
||
|
inout[i] = speech_ssat_int16(tmp);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief Process the collected PCM data from MIC.
|
||
|
* Resample audio stream to 8KHz and pass audio to kws lib.
|
||
|
*
|
||
|
* @param buf Pointer of the PCM data buffer to access.
|
||
|
* @param length Length of the PCM data in the buffer in bytes.
|
||
|
*
|
||
|
* @return uint32_t 0 means no error happened
|
||
|
*/
|
||
|
static uint32_t nt_demo_stream_handler(uint8_t *buf, uint32_t length)
|
||
|
{
|
||
|
ASSERT(length == FRAME_LEN * CAPTURE_CHANNEL_NUM * sizeof(int16_t),
"stream length not matched");
|
||
|
|
||
|
short *pcm_buf = (short*)buf;
|
||
|
uint32_t pcm_len = length / 2;
|
||
|
|
||
|
filter_iir_dc_block(pcm_buf, pcm_len, ANC_NOISE_TRACKER_CHANNEL_NUM);
|
||
|
NT_ENGINE_FEED(pcm_buf, pcm_len);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief Setup audio streaming from MIC
|
||
|
*
|
||
|
* @param do_stream start / stop streaming
|
||
|
*
|
||
|
* @return int 0 means no error happened
|
||
|
*/
|
||
|
static int nt_demo_stream_start(bool do_stream, const void *)
|
||
|
{
|
||
|
struct AF_STREAM_CONFIG_T stream_cfg;
|
||
|
|
||
|
NT_TRACE(3,"Is running:%d enable:%d, bt_sco_mode:%d",
|
||
|
nt_demo_is_streaming, do_stream, bt_sco_mode);
|
||
|
|
||
|
if (bt_sco_mode)
|
||
|
return 0;
|
||
|
|
||
|
if (nt_demo_is_streaming == do_stream)
|
||
|
return 0;
|
||
|
nt_demo_is_streaming = do_stream;
|
||
|
|
||
|
if (do_stream) {
|
||
|
// Request sufficient system clock
|
||
|
app_sysfreq_req(APP_SYSFREQ_USER_APP_NT, NT_ENGINE_SYSFREQ);
|
||
|
NT_TRACE(1,"sys freq calc: %d Hz", hal_sys_timer_calc_cpu_freq(5, 0));
|
||
|
|
||
|
nt_demo_init(true, NULL);
|
||
|
|
||
|
// Initialize the NT ENGINE and install word-callback
|
||
|
NT_ENGINE_INIT(nt_demo_words_cb, ANC_NOISE_TRACKER_CHANNEL_NUM, -20);
|
||
|
|
||
|
memset(&stream_cfg, 0, sizeof(stream_cfg));
|
||
|
stream_cfg.sample_rate = (AUD_SAMPRATE_T)NT_MIC_SAMPLE_RATE;
|
||
|
stream_cfg.bits = NT_MIC_BITS_PER_SAMPLE;
|
||
|
stream_cfg.vol = NT_MIC_VOLUME;
|
||
|
stream_cfg.device = AUD_STREAM_USE_INT_CODEC;
|
||
|
stream_cfg.io_path = AUD_INPUT_PATH_NTMIC;
|
||
|
stream_cfg.channel_num = (enum AUD_CHANNEL_NUM_T)ANC_NOISE_TRACKER_CHANNEL_NUM;
|
||
|
stream_cfg.handler = nt_demo_stream_handler;
|
||
|
stream_cfg.data_ptr = codec_capture_buf;
|
||
|
stream_cfg.data_size = CAPTURE_BUF_SIZE;
|
||
|
|
||
|
af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg);
|
||
|
af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE);
|
||
|
|
||
|
NT_TRACE(0,"audio capture ON");
|
||
|
|
||
|
|
||
|
}
|
||
|
else {
|
||
|
af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE);
|
||
|
af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE);
|
||
|
|
||
|
app_sysfreq_req(APP_SYSFREQ_USER_APP_NT, APP_SYSFREQ_32K);
|
||
|
TRACE(1,"sys freq calc:(32K) %d Hz", hal_sys_timer_calc_cpu_freq(5, 0));
|
||
|
|
||
|
NT_TRACE(0,"audio capture OFF");
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
#include "app_thirdparty.h"
|
||
|
|
||
|
#define TP_EVENT(event, handler) {THIRDPARTY_FUNC_NO3, THIRDPARTY_ID_DEMO, THIRDPARTY_ ## event}, (APP_THIRDPARTY_HANDLE_CB_T)handler
|
||
|
|
||
|
THIRDPARTY_HANDLER_TAB(NOISE_TRACKER_LIB_NAME)
|
||
|
{
|
||
|
// {TP_EVENT(INIT, nt_demo_init), true, NULL},
|
||
|
{TP_EVENT(START, nt_demo_stream_start), true, NULL},
|
||
|
{TP_EVENT(STOP, nt_demo_stream_start), false, NULL},
|
||
|
};
|
||
|
|
||
|
THIRDPARTY_HANDLER_TAB_SIZE(NOISE_TRACKER_LIB_NAME)
|
||
|
|