344 lines
9.0 KiB
C++
344 lines
9.0 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 "hal_trace.h"
|
||
|
#include "resources.h"
|
||
|
#include "app_bt_stream.h"
|
||
|
#include "app_media_player.h"
|
||
|
//#include "app_factory.h"
|
||
|
#include "string.h"
|
||
|
|
||
|
// for audio
|
||
|
#include "audioflinger.h"
|
||
|
#include "app_audio.h"
|
||
|
#include "app_utils.h"
|
||
|
#include "hal_timer.h"
|
||
|
|
||
|
#include "app_mic_alg.h"
|
||
|
#include "tgt_hardware.h"
|
||
|
|
||
|
#ifdef NOTCH_FILTER
|
||
|
#include "autowah.h"
|
||
|
#endif
|
||
|
|
||
|
#ifdef WL_NSX
|
||
|
#include "nsx_main.h"
|
||
|
#endif
|
||
|
#include "app_overlay.h"
|
||
|
#include "math.h"
|
||
|
|
||
|
#include "apps.h"
|
||
|
|
||
|
|
||
|
#ifdef WEBRTC_AGC
|
||
|
#include "agc_main.h"
|
||
|
#endif
|
||
|
|
||
|
#ifdef WL_NSX
|
||
|
#define WEBRTC_NSX_BUFF_SIZE (14000)
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#ifdef WL_VAD
|
||
|
#include "vad_user.h"
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#ifdef WL_DEBUG_MODE
|
||
|
#include "nvrecord_env.h"
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#ifdef REMOTE_UART
|
||
|
#include "app_remoter_uart.h"
|
||
|
#endif
|
||
|
|
||
|
#if defined(WL_AEC)
|
||
|
#include "wl_sco_process.h"
|
||
|
#endif
|
||
|
#include "speech_memory.h"
|
||
|
|
||
|
#ifdef I2C_SENSOR
|
||
|
#include "app_i2c_sensor.h"
|
||
|
#endif
|
||
|
|
||
|
static inline float clampf(float v, float min, float max){
|
||
|
return v < min ? min : (v > max ? max : v);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
#ifdef WL_NSX_5MS
|
||
|
#define BT_AUDIO_FACTORMODE_BUFF_SIZE (160*2)
|
||
|
#else
|
||
|
#define BT_AUDIO_FACTORMODE_BUFF_SIZE (6*320*16)
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
#define NSX_FRAME_SIZE 160
|
||
|
|
||
|
|
||
|
static enum APP_AUDIO_CACHE_T a2dp_cache_status = APP_AUDIO_CACHE_QTY;
|
||
|
|
||
|
|
||
|
#if defined(WL_AEC)
|
||
|
static short POSSIBLY_UNUSED aec_out[BT_AUDIO_FACTORMODE_BUFF_SIZE>>2];
|
||
|
static short POSSIBLY_UNUSED far_buff[BT_AUDIO_FACTORMODE_BUFF_SIZE>>2];
|
||
|
#endif
|
||
|
|
||
|
|
||
|
static short POSSIBLY_UNUSED out_buff[BT_AUDIO_FACTORMODE_BUFF_SIZE>>2];
|
||
|
static short POSSIBLY_UNUSED tmp_buff[BT_AUDIO_FACTORMODE_BUFF_SIZE>>2];
|
||
|
|
||
|
//static short revert_buff[BT_AUDIO_FACTORMODE_BUFF_SIZE>>2];
|
||
|
//static short audio_uart_buff[BT_AUDIO_FACTORMODE_BUFF_SIZE>>2];
|
||
|
|
||
|
|
||
|
#if SPEECH_CODEC_CAPTURE_CHANNEL_NUM == 2
|
||
|
|
||
|
static short POSSIBLY_UNUSED one_buff[BT_AUDIO_FACTORMODE_BUFF_SIZE>>2];
|
||
|
static short POSSIBLY_UNUSED two_buff[BT_AUDIO_FACTORMODE_BUFF_SIZE>>2];
|
||
|
|
||
|
static short POSSIBLY_UNUSED left_out[BT_AUDIO_FACTORMODE_BUFF_SIZE>>2];
|
||
|
static short POSSIBLY_UNUSED right_out[BT_AUDIO_FACTORMODE_BUFF_SIZE>>2];
|
||
|
|
||
|
static void POSSIBLY_UNUSED aaudio_div_stero_to_rmono(int16_t *dst_buf, int16_t *src_buf, uint32_t src_len)
|
||
|
{
|
||
|
// Copy from tail so that it works even if dst_buf == src_buf
|
||
|
for (uint32_t i = 0; i < src_len>>1; i++)
|
||
|
{
|
||
|
dst_buf[i] = src_buf[i*2 + 1];
|
||
|
}
|
||
|
}
|
||
|
static void POSSIBLY_UNUSED aaudio_div_stero_to_lmono(int16_t *dst_buf, int16_t *src_buf, uint32_t src_len)
|
||
|
{
|
||
|
// Copy from tail so that it works even if dst_buf == src_buf
|
||
|
for (uint32_t i = 0; i < src_len>>1; i++)
|
||
|
{
|
||
|
dst_buf[i] = src_buf[i*2 + 0];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
static void POSSIBLY_UNUSED audio_mono2stereo_16bits(int16_t *dst_buf, int16_t *left_buf, int16_t *right_buf, uint32_t src_len)
|
||
|
{
|
||
|
uint32_t i = 0;
|
||
|
for (i = 0; i < src_len; ++i) {
|
||
|
dst_buf[i*2 + 0] = left_buf[i];
|
||
|
dst_buf[i*2 + 1] = right_buf[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#elif SPEECH_CODEC_CAPTURE_CHANNEL_NUM == 3
|
||
|
|
||
|
|
||
|
#elif SPEECH_CODEC_CAPTURE_CHANNEL_NUM == 4
|
||
|
|
||
|
#endif
|
||
|
|
||
|
extern uint8_t supress_step;
|
||
|
extern uint32_t transfer_factor;
|
||
|
extern uint32_t diff_energy;
|
||
|
extern uint32_t level_shift;
|
||
|
|
||
|
static inline double convert_multiple_to_db(uint32_t multiple)
|
||
|
{
|
||
|
return 20*log10(multiple);
|
||
|
}
|
||
|
#define DUMP_FRAME_LEN 0x3C0
|
||
|
static short POSSIBLY_UNUSED revert_buff[2+1*DUMP_FRAME_LEN];
|
||
|
int32_t tx_pcmbuf32[960];
|
||
|
|
||
|
|
||
|
extern int app_reset(void);
|
||
|
|
||
|
extern void app_bt_volumeup();
|
||
|
extern void app_bt_volumedown();
|
||
|
|
||
|
void vol_state_process(uint32_t db_val)
|
||
|
{
|
||
|
TRACE(2,"db value is:%d volume_is:%d ",db_val,app_bt_stream_local_volume_get());
|
||
|
|
||
|
if((db_val < 52) && (app_bt_stream_local_volume_get() > 10))
|
||
|
{
|
||
|
app_bt_volumedown();
|
||
|
}
|
||
|
else if((db_val > 60) && (app_bt_stream_local_volume_get() < 13))
|
||
|
{
|
||
|
app_bt_volumeup();
|
||
|
}
|
||
|
else if((db_val > 72) && (app_bt_stream_local_volume_get() < 15))
|
||
|
{
|
||
|
app_bt_volumeup();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
static uint32_t app_mic_alg_data_come(uint8_t *buf, uint32_t len)
|
||
|
{
|
||
|
uint32_t pcm_len = len>>1;
|
||
|
|
||
|
short POSSIBLY_UNUSED *tx_pcmbuf16 = (short*)buf;
|
||
|
|
||
|
//DUMP16("%d, ",tx_pcmbuf16,30);
|
||
|
// memcpy(tmp_buff,pcm_buff,len);
|
||
|
|
||
|
int32_t stime = 0;
|
||
|
static int32_t nsx_cnt = 0;
|
||
|
static int32_t dump_cnt = 0;
|
||
|
|
||
|
|
||
|
nsx_cnt++;
|
||
|
dump_cnt++;
|
||
|
|
||
|
DUMP16("%d,",tx_pcmbuf16,30);
|
||
|
if(false == (nsx_cnt & 0x3F))
|
||
|
{
|
||
|
stime = hal_sys_timer_get();
|
||
|
//TRACE("aecm echo time: lens:%d g_time_cnt:%d ",len, g_time_cnt);
|
||
|
}
|
||
|
|
||
|
#ifdef WL_DET
|
||
|
if(nsx_cnt > 100)
|
||
|
{
|
||
|
static double last_sum = 0,last_avg = 0;
|
||
|
|
||
|
uint32_t sum_ss = 0;
|
||
|
//short db_val = 0;
|
||
|
double db_sum = 0;
|
||
|
for (uint32_t i_cnt = 0; i_cnt < pcm_len; i_cnt++)
|
||
|
{
|
||
|
sum_ss += ABS(tx_pcmbuf16[i_cnt]);
|
||
|
}
|
||
|
|
||
|
sum_ss = 1*sum_ss/pcm_len;
|
||
|
|
||
|
db_sum = convert_multiple_to_db(sum_ss);
|
||
|
//db_val = (short)(100*db_sum);
|
||
|
last_sum += db_sum;
|
||
|
last_avg = last_sum/nsx_cnt;
|
||
|
|
||
|
db_sum = db_sum*(double)0.02 + last_avg*(double)0.98;
|
||
|
|
||
|
//TRACE(2,"db value is:%d sum_ss:%d ",(uint32_t)db_sum,sum_ss);
|
||
|
//TRACE(2,"db value is:%d ",(uint32_t)db_sum);
|
||
|
vol_state_process((uint32_t)db_sum);
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
if(false == (nsx_cnt & 0x3F))
|
||
|
{
|
||
|
//TRACE("drc 48 mic_alg 16k nsx 3 agc 15 closed speed time:%d ms and pcm_lens:%d freq:%d ", TICKS_TO_MS(hal_sys_timer_get() - stime), pcm_len,hal_sysfreq_get());
|
||
|
//TRACE("notch 500 mic_alg 16k nsx 3 agc 15 closed speed time:%d ms and pcm_lens:%d freq:%d ", TICKS_TO_MS(hal_sys_timer_get() - stime), pcm_len,hal_sysfreq_get());
|
||
|
TRACE(2,"denoise det speed time:%d ms and pcm_lens:%d freq:%d ", TICKS_TO_MS(hal_sys_timer_get() - stime), pcm_len,hal_sysfreq_get());
|
||
|
}
|
||
|
|
||
|
|
||
|
if (a2dp_cache_status == APP_AUDIO_CACHE_QTY){
|
||
|
a2dp_cache_status = APP_AUDIO_CACHE_OK;
|
||
|
}
|
||
|
return len;
|
||
|
}
|
||
|
|
||
|
// static uint32_t app_mic_uart_playback_data(uint8_t *buf, uint32_t len)
|
||
|
// {
|
||
|
// if (a2dp_cache_status != APP_AUDIO_CACHE_QTY){
|
||
|
// #if SPEECH_CODEC_CAPTURE_CHANNEL_NUM == 2
|
||
|
// #ifdef WL_AEC
|
||
|
// app_audio_pcmbuff_get((uint8_t *)app_audioloop_play_cache, len/2);
|
||
|
// app_bt_stream_copy_track_one_to_two_16bits((int16_t *)buf, app_audioloop_play_cache, len/2/2);
|
||
|
// #else
|
||
|
// app_audio_pcmbuff_get((uint8_t *)buf, len);
|
||
|
// #endif
|
||
|
// #else
|
||
|
// app_audio_pcmbuff_get((uint8_t *)app_audioloop_play_cache, len/2);
|
||
|
// app_bt_stream_copy_track_one_to_two_16bits((int16_t *)buf, app_audioloop_play_cache, len/2/2);
|
||
|
// #endif
|
||
|
// }
|
||
|
// return len;
|
||
|
// }
|
||
|
|
||
|
static uint8_t buff_capture[BT_AUDIO_FACTORMODE_BUFF_SIZE];
|
||
|
|
||
|
int app_mic_alg_audioloop(bool on, enum APP_SYSFREQ_FREQ_T freq)
|
||
|
{
|
||
|
struct AF_STREAM_CONFIG_T stream_cfg;
|
||
|
static bool isRun = false;
|
||
|
|
||
|
TRACE(2,"app_mic_alg work:%d op:%d freq:%d", isRun, on, freq);
|
||
|
|
||
|
if (isRun==on)
|
||
|
return 0;
|
||
|
|
||
|
if (on){
|
||
|
|
||
|
|
||
|
app_sysfreq_req(APP_SYSFREQ_USER_APP_0, freq);
|
||
|
|
||
|
a2dp_cache_status = APP_AUDIO_CACHE_QTY;
|
||
|
|
||
|
memset(&stream_cfg, 0, sizeof(stream_cfg));
|
||
|
|
||
|
|
||
|
stream_cfg.bits = AUD_BITS_16;
|
||
|
|
||
|
stream_cfg.channel_num = AUD_CHANNEL_NUM_1;
|
||
|
|
||
|
stream_cfg.sample_rate = AUD_SAMPRATE_48000;
|
||
|
|
||
|
|
||
|
stream_cfg.device = AUD_STREAM_USE_INT_CODEC;
|
||
|
|
||
|
stream_cfg.vol = CODEC_SADC_VOL;
|
||
|
stream_cfg.io_path = AUD_INPUT_PATH_ASRMIC;
|
||
|
|
||
|
stream_cfg.handler = app_mic_alg_data_come;
|
||
|
|
||
|
stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(buff_capture);
|
||
|
stream_cfg.data_size = BT_AUDIO_FACTORMODE_BUFF_SIZE*stream_cfg.channel_num;
|
||
|
af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg);
|
||
|
|
||
|
// stream_cfg.channel_num = AUD_CHANNEL_NUM_2;
|
||
|
// stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER;
|
||
|
// stream_cfg.handler = app_mic_uart_playback_data;
|
||
|
|
||
|
// stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(buff_play);
|
||
|
// stream_cfg.data_size = BT_AUDIO_FACTORMODE_BUFF_SIZE*2;
|
||
|
// af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg);
|
||
|
|
||
|
//af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK);
|
||
|
af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE);
|
||
|
TRACE(2,"app_mic_uart ss loopback on");
|
||
|
|
||
|
} else {
|
||
|
af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE);
|
||
|
//af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK);
|
||
|
af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE);
|
||
|
//af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK);
|
||
|
TRACE(2,"app_mic_16k loopback off");
|
||
|
|
||
|
//app_sysfreq_req(APP_SYSFREQ_USER_APP_0, APP_SYSFREQ_32K);
|
||
|
}
|
||
|
|
||
|
isRun=on;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|