// 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 #include #include #include //#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 ;i800){ /* 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 ;i500){ /* 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=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; i800){ #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