helloyifa 31f179cb76 init
2025-05-15 14:19:56 +08:00

630 lines
18 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2023-2024 Beken
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifdef ILOCK_AI_ASR
#include "stdio.h"
#include <os/os.h>
#include <os/mem.h>
#include <os/str.h>
#include <modules/pm.h>
//#include "audio_record.h"
#include "bk_wanson_asr.h"
#include "cli.h"
#include "wanson_client.h"
#include "audio_record.h"
#include "aud_intf.h"
#include "aud_intf_types.h"
#define TAG "ws_asr_test"
#if defined(CONFIG_FATFS)
#include "diskio.h"
static FIL mic_file;
static char mic_file_name[50];
static FATFS *pfs = NULL;
static bk_err_t tf_mount(void)
{
FRESULT fr;
if (pfs != NULL)
{
os_free(pfs);
}
pfs = os_malloc(sizeof(FATFS));
if(NULL == pfs)
{
BK_LOGI(TAG, "f_mount malloc failed!\r\n");
return BK_FAIL;
}
fr = f_mount(pfs, "1:", 1);
if (fr != FR_OK)
{
BK_LOGE(TAG, "f_mount failed:%d\r\n", fr);
return BK_FAIL;
}
else
{
BK_LOGI(TAG, "f_mount OK!\r\n");
}
return BK_OK;
}
static bk_err_t tf_unmount(void)
{
FRESULT fr;
fr = f_unmount(DISK_NUMBER_SDIO_SD, "1:", 1);
if (fr != FR_OK)
{
BK_LOGE(TAG, "f_unmount failed:%d\r\n", fr);
return BK_FAIL;
}
else
{
BK_LOGI(TAG, "f_unmount OK!\r\n");
}
if (pfs)
{
os_free(pfs);
pfs = NULL;
}
return BK_OK;
}
#endif
#define WANSON_CLIENT_USE_UAC 1
static bool wanson_asr_running = false;
static beken_thread_t wanson_asr_task_hdl = NULL;
static beken_semaphore_t wanson_asr_sem = NULL;
static wanson_asr_handle_t gl_wanson_asr = NULL;
//static audio_record_t *gl_aud_record = NULL;
static bk_err_t wanson_asr_test_exit(void)
{
wanson_asr_running = false;
if (gl_wanson_asr)
{
bk_wanson_asr_destroy(gl_wanson_asr);
}
// if (gl_aud_record)
// {
// audio_record_destroy(gl_aud_record);
// }
return BK_OK;
}
static int wanson_asr_result_notify_handle(wanson_asr_handle_t wanson_asr, char *result, void *params)
{
BK_LOGE("%s \n", result);
if (os_strcmp(result, "小蜂管家") == 0) //识别出唤醒词 小蜂管家
{
BK_LOGE("%s \n", "xiao feng guan jia ");
}
else if (os_strcmp(result, "阿尔米诺") == 0) //识别出唤醒词 阿尔米诺
{
BK_LOGE("%s \n", "a er mi nuo ");
}
else if (os_strcmp(result, "会客模式") == 0) //识别出 会客模式
{
BK_LOGE("%s \n", "hui ke mo shi ");
}
else if (os_strcmp(result, "用餐模式") == 0) //识别出 用餐模式
{
BK_LOGE("%s \n", "yong can mo shi ");
}
else if (os_strcmp(result, "离开模式") == 0) //识别出 离开模式
{
BK_LOGE("%s \n", "li kai mo shi ");
}
else if (os_strcmp(result, "回家模式") == 0) //识别出 回家模式
{
BK_LOGE("%s \n", "hui jia mo shi ");
}
else
{
//nothing
}
return BK_OK;
}
static int count = 0;
//static uint16_t pcm8K16b [480] ;
//static uint16_t pcm16K16b [960] ;
static int send_mic_data_to_sd(uint8_t *data, unsigned int len)
{
//BK_LOGE(TAG, "send_mic_data_to_sd:%d\n", len);
uint8_t sounds[len/2];
int pos = 0;
for(int i = 2 ;i<len ;i=i+4){
//int16_t value = (data[i] << 8) | data[i+1];
//bk_wanson_asr_data_write(gl_wanson_asr, (void *)data+i, 1);
//bk_wanson_asr_data_write(gl_wanson_asr, (void *)data+i+1, 1);
//little endian
sounds[pos] = data[i+i];
pos++;
sounds[pos] = data[i];
pos++;
}
#if 0
FRESULT fr;
uint32 uiTemp = 0;
/* write data to file */
fr = f_write(&mic_file, (void *)sounds, len/2, &uiTemp);
if (fr != FR_OK) {
BK_LOGE(TAG, "write %s fail.\r\n", mic_file_name);
}
BK_LOGE(TAG, "write count %d \r\n", count);
if(count >800){
/* close mic file */
f_close(&mic_file);
tf_unmount();
}
count++;
#endif
//BK_LOGE(TAG, "@@ %02X %02X %02X %02X %02X %02X\n", sounds[0], sounds[1],sounds[2],sounds[3],sounds[4],sounds[5]);
bk_wanson_asr_data_write(gl_wanson_asr, (void *)sounds, len/2);
#if 0
/*
8K8位转8K16位
//对8K8位采样的每个字节加上0x80再移位成2个字节
short sData16 = (( short )( byData8 + 0x80 )) << 8;
*/
/*
8K16位转8K8位把上面的表达式反转来就可以。
BYTE byData8 = ( BYTE )(( sData16 >> 8 ) - 0x80 );
*/
int pos = 0;
for(int i = 0 ;i<len; i++){
pcm8K16b[i] = (( short )( data[i] + 0x80 )) << 8 ;
// 插入插值样本:前一样本与当前样本的平均值
//int16_t interpolated = (sample16_prev + sample16_current) / 2;
//fwrite(&interpolated, sizeof(int16_t), 1, out);
//BK_LOGE(TAG, "pcm16K16b:%d\n", pos);
pcm16K16b[pos] = pcm8K16b[i];
pos++;
//BK_LOGE(TAG, "pcm16K16b:%d\n", pos);
pcm16K16b[pos] = pcm8K16b[i];
pos++;
//
// 写入当前样本
//fwrite(&sample16_current, sizeof(int16_t), 1, out);
}
BK_LOGE(TAG, "write count %d \r\n", count);
if(count >500){
/* close mic file */
f_close(&mic_file);
tf_unmount();
}
count++;
//bk_wanson_asr_data_write(gl_wanson_asr, (int16_t *)pcm16k, len);
//BK_LOGE(TAG, "%02X %02X %02X %02X %02X %02X\n", data[2], data[10],data[30],data[80],data[100],data[200]);
//bk_wanson_asr_data_write(gl_wanson_asr, (int16_t *)data, len/2);
//BK_LOGE(TAG, "%02X %02X %02X %02X %02X %02X\n", pcm16K16b[0], pcm16K16b[1],pcm16K16b[2],pcm16K16b[3],pcm16K16b[4],pcm16K16b[5]);
//bk_wanson_asr_data_write(gl_wanson_asr, (int16_t *)pcm16K16b, 960);
FRESULT fr;
uint32 uiTemp = 0;
/* write data to file */
fr = f_write(&mic_file, (void *)data, len, &uiTemp);
if (fr != FR_OK) {
BK_LOGE(TAG, "write %s fail.\r\n", mic_file_name);
}
#endif
return len;
}
#ifdef WANSON_CLIENT_USE_UAC
static int volume_adjust2(int16_t * in_buf, float in_vol)
{
int tmp;
// in_vol[0, 100]
float vol = in_vol - 98;
if(-98<vol && vol<0)
vol = 1/(vol*(-1));
else if(0<=vol && vol<=1)
vol = 1;
/*
else if(1<=vol && vol<=2)
vol = vol;
*/
else if(vol<=-98)
vol = 0;
else if(vol>=2)
vol = 30; //这个值可以根据你的实际情况去调整
tmp = (*in_buf)*vol; // 上面所有关于vol的判断其实都是为了此处*in_buf乘以一个倍数你可以根据自己的需要去修改
// 下面的code主要是为了溢出判断
if(tmp > 32767)
tmp = 32767;
else if(tmp < -32768)
tmp = -32768;
*in_buf = tmp;
return 0;
}
static int convert_8khz_to_16khz(void * dst_buf, void *src_buf, int src_size)
{
int i;
for(i=0; i<src_size/2; i++)
{
*((short *)dst_buf + i*2) = *((short *)src_buf + i);
volume_adjust2((short *)dst_buf + i*2,100);
*((short *)dst_buf + i*2 + 1) = *((short *)src_buf + i);
volume_adjust2((short *)dst_buf + i*2 + 1,100);
}
return src_size * 2;
}
//static uint16_t pcm8K16b [480] ;
//static uint8_t pcm16K16b [960] ;
static int send_uac_mic_data_to_sd(uint8_t *data, unsigned int len)
{
//UAC PCM signed 16bit ,little endian,8000k mono
if(count >800){
#if defined(CONFIG_FATFS)
/* close mic file */
f_close(&mic_file);
tf_unmount();
#endif
}else{
uint8_t pcm16K16b [len*2] ;
convert_8khz_to_16khz(&pcm16K16b,data,len);
bk_wanson_asr_data_write(gl_wanson_asr, (void *)pcm16K16b, len*2);
/*
FRESULT fr;
uint32 uiTemp = 0;
fr = f_write(&mic_file, (void *)pcm16K16b, len*2, &uiTemp);
if (fr != FR_OK) {
BK_LOGE(TAG, "write %s fail.\r\n", mic_file_name);
}
count++;
*/
}
return len;
}
void test(){
rtos_delay_milliseconds(3000);
//audio_tras_init();
bk_err_t ret = BK_OK;
aud_intf_drv_setup_t aud_intf_drv_setup = DEFAULT_AUD_INTF_DRV_SETUP_CONFIG();
aud_intf_drv_setup.aud_intf_tx_mic_data = send_uac_mic_data_to_sd;
ret = bk_aud_intf_drv_init(&aud_intf_drv_setup);
if (ret != BK_ERR_AUD_INTF_OK) {
BK_LOGE(TAG, "bk_aud_intf_drv_init fail, ret:%d \r\n", ret);
} else {
BK_LOGE(TAG, "bk_aud_intf_drv_init complete \r\n");
}
ret = bk_aud_intf_set_mode(AUD_INTF_WORK_MODE_VOICE);
if (ret != BK_ERR_AUD_INTF_OK) {
BK_LOGE(TAG, "bk_aud_intf_set_mode fail, ret:%d \r\n", ret);
} else {
BK_LOGE(TAG, "bk_aud_intf_set_mode complete \r\n");
}
aud_intf_voc_setup_t aud_intf_voc_setup = DEFAULT_AUD_INTF_VOC_SETUP_CONFIG();
aud_intf_voc_setup.data_type = AUD_INTF_VOC_DATA_TYPE_PCM;
aud_intf_voc_setup.samp_rate = 8000;
aud_intf_voc_setup.spk_en = AUD_INTF_VOC_SPK_OPEN;
aud_intf_voc_setup.spk_mode = AUD_DAC_WORK_MODE_SIGNAL_END;
aud_intf_voc_setup.mic_type = AUD_INTF_MIC_TYPE_UAC;
aud_intf_voc_setup.spk_type = AUD_INTF_MIC_TYPE_UAC;
ret = bk_aud_intf_voc_init(aud_intf_voc_setup);
if (ret != BK_ERR_AUD_INTF_OK) {
BK_LOGE(TAG, "bk_aud_intf_voc_init fail, ret:%d \r\n", ret);
} else {
BK_LOGE(TAG, "bk_aud_intf_voc_init complete \r\n");
}
ret = bk_aud_intf_voc_start();
}
#endif
static void wanson_asr_main(beken_thread_arg_t param_data)
{
#if defined(CONFIG_FATFS)
bk_err_t ret;
FRESULT fr;
#if 1
ret = tf_mount();
if (ret != BK_ERR_AUD_INTF_OK) {
BK_LOGE(TAG, "tfcard mount fail, ret:%d\n", ret);
}
/*open file to save pcm data */
sprintf(mic_file_name, "1:/%s", "999.pcm");
fr = f_open(&mic_file, mic_file_name, FA_CREATE_ALWAYS | FA_WRITE);
if (fr != FR_OK) {
BK_LOGE(TAG, "open %s fail\n", mic_file_name);
}
#endif
#endif
char *mic_data_buff = NULL;
/* init audio record */
//audio_record_cfg_t record_config = DEFAULT_AUDIO_RECORD_CONFIG();
//record_config.sampRate = 16000;
//record_config.frame_size = 960;
//record_config.pool_size = 1920;
//gl_aud_record = audio_record_create(AUDIO_RECORD_ONBOARD_MIC, &record_config);
//if (!gl_aud_record)
//{
// BK_LOGE(TAG, "%s, %d, create audio record handle fail\n", __func__, __LINE__);
// goto fail;
//}
//BK_LOGI(TAG, "audio record create complete\n");
#ifdef WANSON_CLIENT_USE_UAC
test();
#elif
aud_intf_drv_setup_t aud_intf_drv_setup = DEFAULT_AUD_INTF_DRV_SETUP_CONFIG();
aud_intf_mic_setup_t aud_intf_mic_setup = DEFAULT_AUD_INTF_MIC_SETUP_CONFIG();
aud_intf_drv_setup.aud_intf_tx_mic_data = send_mic_data_to_sd;
ret = bk_aud_intf_drv_init(&aud_intf_drv_setup);
if (ret != BK_ERR_AUD_INTF_OK) {
BK_LOGE(TAG, "bk_aud_intf_drv_init fail, ret:%d\n", ret);
goto fail;
}
ret = bk_aud_intf_set_mode(AUD_INTF_WORK_MODE_GENERAL);
if (ret != BK_ERR_AUD_INTF_OK) {
BK_LOGE(TAG, "bk_aud_intf_set_mode fail, ret:%d\n", ret);
goto fail;
}
aud_intf_mic_setup.mic_chl = AUD_INTF_MIC_CHL_DUAL;
aud_intf_mic_setup.samp_rate = 16000;//8000 16000
//aud_intf_mic_setup.mic_type = AUD_INTF_MIC_TYPE_UAC;
aud_intf_mic_setup.frame_size = 960;
//aud_intf_mic_setup.mic_gain = 0x2d;
ret = bk_aud_intf_mic_init(&aud_intf_mic_setup);
if (ret != BK_ERR_AUD_INTF_OK) {
BK_LOGE(TAG, "bk_aud_intf_mic_init fail, ret:%d\n", ret);
goto fail;
}
BK_LOGE(TAG, "bk_aud_intf_mic_init OK:\n");
ret = bk_aud_intf_mic_start();
if (ret != BK_ERR_AUD_INTF_OK) {
BK_LOGE(TAG, "bk_aud_intf_mic_start fail, ret:%d\n", ret);
goto fail;
}
BK_LOGE(TAG, "bk_aud_intf_mic_start OK:\n");
#endif
//test();
wanson_asr_cfg_t asr_config = DEFAULT_WANSON_ASR_CONFIG();
asr_config.asr_result_notify = wanson_asr_result_notify_handle;
gl_wanson_asr = bk_wanson_asr_create(&asr_config);
if (!gl_wanson_asr)
{
BK_LOGE(TAG, "%s, %d, create wanson asr handle fail\n", __func__, __LINE__);
goto fail;
}
BK_LOGI(TAG, "audio wanson asr complete\n");
#ifdef CONFIG_BEKEN_WANSON_ASR_USE_SRAM
mic_data_buff = os_malloc(960);
#else
mic_data_buff = psram_malloc(960);
#endif
if (!mic_data_buff)
{
BK_LOGE(TAG, "%s, %d, malloc mic_data_buff: 960 fail\n", __func__, __LINE__);
goto fail;
}
os_memset(mic_data_buff, 0, 960);
bk_wanson_asr_start(gl_wanson_asr);
BK_LOGI(TAG, "wanson asr start complete\n");
//audio_record_open(gl_aud_record);
//BK_LOGI(TAG, "audio record open complete\n");
rtos_set_semaphore(&wanson_asr_sem);
wanson_asr_running = true;
while (wanson_asr_running)
{
//bk_err_t read_size = audio_record_read_data(gl_aud_record, mic_data_buff, 960);
bk_err_t read_size = 0;
if (read_size == 960)
{
int write_size = bk_wanson_asr_data_write(gl_wanson_asr, (int16_t *)mic_data_buff, 960);
if (write_size != 960)
{
BK_LOGE(TAG, "%s, %d, wanson_asr write size: %d != 960\n", __func__, __LINE__, write_size);
}
}
else
{
//BK_LOGE(TAG, "%s, %d, audio_record read size: %d != 960\n", __func__, __LINE__, read_size);
}
rtos_delay_milliseconds(500);
}
fail:
wanson_asr_running = false;
wanson_asr_test_exit();
if (mic_data_buff)
{
#ifdef CONFIG_BEKEN_WANSON_ASR_USE_SRAM
os_free(mic_data_buff);
#else
psram_free(mic_data_buff);
#endif
mic_data_buff = NULL;
}
rtos_set_semaphore(&wanson_asr_sem);
wanson_asr_task_hdl = NULL;
rtos_delete_thread(NULL);
}
static bk_err_t wanson_asr_test_start(void)
{
bk_err_t ret = BK_OK;
ret = rtos_init_semaphore(&wanson_asr_sem, 1);
if (ret != BK_OK)
{
BK_LOGE(TAG, "%s, %d, create semaphore fail\n", __func__, __LINE__);
return BK_FAIL;
}
ret = rtos_create_thread(&wanson_asr_task_hdl,
(BEKEN_DEFAULT_WORKER_PRIORITY - 1),
"audio_play",
(beken_thread_function_t)wanson_asr_main,
6*1024,
NULL);
if (ret != BK_OK)
{
BK_LOGE(TAG, "%s, %d, create wanson_asr_main task fail\n", __func__, __LINE__);
goto fail;
}
rtos_get_semaphore(&wanson_asr_sem, BEKEN_NEVER_TIMEOUT);
BK_LOGI(TAG, "%s, %d, create wanson_asr_main task complete\n", __func__, __LINE__);
return BK_OK;
fail:
if (wanson_asr_sem)
{
rtos_deinit_semaphore(&wanson_asr_sem);
wanson_asr_sem = NULL;
}
return BK_FAIL;
}
static bk_err_t wanson_asr_test_stop(void)
{
if (!wanson_asr_running)
{
BK_LOGW(TAG, "%s, %d, wanson_asr not work\n", __func__, __LINE__);
return BK_OK;
}
wanson_asr_running = false;
rtos_get_semaphore(&wanson_asr_sem, BEKEN_NEVER_TIMEOUT);
rtos_deinit_semaphore(&wanson_asr_sem);
wanson_asr_sem = NULL;
return BK_OK;
}
/*
static void cli_wanson_asr_test_help(void)
{
BK_LOGI(TAG, "wanson_asr_test {start|stop}\n");
}
void cli_wanson_asr_test_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
if (argc != 2)
{
cli_wanson_asr_test_help();
return;
}
if (os_strcmp(argv[1], "start") == 0)
{
wanson_asr_test_start();
}
else if (os_strcmp(argv[1], "stop") == 0)
{
wanson_asr_test_stop();
}
else
{
cli_wanson_asr_test_help();
}
}
#define WANSON_ASR_TEST_CMD_CNT (sizeof(s_wanson_asr_test_commands) / sizeof(struct cli_command))
static const struct cli_command s_wanson_asr_test_commands[] =
{
{"wanson_asr_test", "wanson_asr_test {start|stop}", cli_wanson_asr_test_cmd},
};
int cli_wanson_asr_test_init(void)
{
BK_LOGI(TAG, "cli_wanson_asr_test_init \n");
return cli_register_commands(s_wanson_asr_test_commands, WANSON_ASR_TEST_CMD_CNT);
}
*/
void poka_wanson_asr_test_init(){
wanson_asr_test_start();
}
#endif