2025-10-10 16:07:00 +08:00

490 lines
12 KiB
C
Executable File

#include <common/bk_include.h>
#include <os/os.h>
#include <modules/pm.h>
#include "FreeRTOS.h"
#include "task.h"
#include "audio_pipeline.h"
#include "audio_mem.h"
#include "raw_stream.h"
#include "onboard_mic_stream.h"
#include "wanson_asr.h"
#include "asr.h"
#include "ui.h"
//#define TAG "wanson_asr"
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
#define VOICE_PLAY (0)
#define RAW_READ_SIZE (960)
#define TEST_CHECK_NULL(ptr) do {\
if (ptr == NULL) {\
BK_LOGI(TAG, "TEST_CHECK_NULL fail \n");\
return BK_FAIL;\
}\
} while(0)
static audio_element_handle_t onboard_mic = NULL, raw_read = NULL;
static audio_pipeline_handle_t record_pipeline = NULL;
static beken_thread_t wanson_asr_task_hdl = NULL;
static beken_queue_t wanson_asr_msg_que = NULL;
//#define ASR_BUFF_SIZE 8000 //>960*2
int8_t *asr_buff = NULL;
const static char *text;
static float score;
static int rs;
static char result0[13] = {0xE5,0xB0,0x8F,0xE8,0x9C,0x82,0xE7,0xAE,0xA1,0xE5,0xAE,0xB6,0x00};//小蜂管家
static char result1[13] = {0xE9,0x98,0xBF,0xE5,0xB0,0x94,0xE7,0xB1,0xB3,0xE8,0xAF,0xBA,0x00};//阿尔米诺
static char result2[13] = {0xE4,0xBC,0x9A,0xE5,0xAE,0xA2,0xE6,0xA8,0xA1,0xE5,0xBC,0x8F,0x00};//会客模式
static char result3[13] = {0xE7,0x94,0xA8,0xE9,0xA4,0x90,0xE6,0xA8,0xA1,0xE5,0xBC,0x8F,0x00};//用餐模式
static char resulta[13] = {0xE7,0xA6,0xBB,0xE5,0xBC,0x80,0xE6,0xA8,0xA1,0xE5,0xBC,0x8F,0x00};//离开模式
static char resultc[13] = {0xE5,0x9B,0x9E,0xE5,0xAE,0xB6,0xE6,0xA8,0xA1,0xE5,0xBC,0x8F,0x00};//回家模式
static bk_err_t record_pipeline_open(void)
{
BK_LOGI(TAG, "--------- step1: record pipeline init ----------\n");
audio_pipeline_cfg_t record_pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
record_pipeline_cfg.rb_size = 640;
record_pipeline = audio_pipeline_init(&record_pipeline_cfg);
TEST_CHECK_NULL(record_pipeline);
BK_LOGI(TAG, "--------- step2: init elements ----------\n");
onboard_mic_stream_cfg_t onboard_mic_cfg = ONBOARD_MIC_ADC_STREAM_CFG_DEFAULT();
onboard_mic_cfg.adc_cfg.samp_rate = 16000;
onboard_mic_cfg.task_stack = 1024;
onboard_mic_cfg.task_prio = 6;
onboard_mic = onboard_mic_stream_init(&onboard_mic_cfg);
TEST_CHECK_NULL(onboard_mic);
raw_stream_cfg_t raw_read_cfg = RAW_STREAM_CFG_DEFAULT();
raw_read_cfg.type = AUDIO_STREAM_READER;
raw_read_cfg.out_rb_size = RAW_READ_SIZE*2;
raw_read = raw_stream_init(&raw_read_cfg);
TEST_CHECK_NULL(raw_read);
BK_LOGI(TAG, "--------- step3: pipeline register ----------\n");
if (BK_OK != audio_pipeline_register(record_pipeline, onboard_mic, "onboard_mic")) {
BK_LOGE(TAG, "register element fail, %d \n", __LINE__);
return BK_FAIL;
}
if (BK_OK != audio_pipeline_register(record_pipeline, raw_read, "raw_read")) {
BK_LOGE(TAG, "register element fail, %d \n", __LINE__);
return BK_FAIL;
}
BK_LOGI(TAG, "--------- step4: pipeline link ----------\n");
/* pipeline record */
if (BK_OK != audio_pipeline_link(record_pipeline, (const char *[]) {"onboard_mic", "raw_read"}, 2)) {
BK_LOGE(TAG, "pipeline link fail, %d \n", __LINE__);
return BK_FAIL;
}
return BK_OK;
}
static bk_err_t record_pipeline_close(void)
{
BK_LOGI(TAG, "%s \n", __func__);
BK_LOGI(TAG, "%s, terminate record pipeline \n", __func__);
if (BK_OK != audio_pipeline_terminate(record_pipeline)) {
BK_LOGE(TAG, "pipeline terminate fail, %d \n", __LINE__);
return BK_FAIL;
}
if (BK_OK != audio_pipeline_unregister(record_pipeline, onboard_mic)) {
BK_LOGE(TAG, "pipeline terminate fail, %d \n", __LINE__);
return BK_FAIL;
}
if (BK_OK != audio_pipeline_unregister(record_pipeline, raw_read)) {
BK_LOGE(TAG, "pipeline terminate fail, %d \n", __LINE__);
return BK_FAIL;
}
if (BK_OK != audio_pipeline_deinit(record_pipeline)) {
BK_LOGE(TAG, "pipeline terminate fail, %d \n", __LINE__);
return BK_FAIL;
} else {
record_pipeline = NULL;
}
if (BK_OK != audio_element_deinit(onboard_mic)) {
BK_LOGE(TAG, "element deinit fail, %d \n", __LINE__);
return BK_FAIL;
} else {
onboard_mic = NULL;
}
if (BK_OK != audio_element_deinit(raw_read)) {
BK_LOGE(TAG, "element deinit fail, %d \n", __LINE__);
return BK_FAIL;
} else {
raw_read = NULL;
}
return BK_OK;
}
static bk_err_t wanson_read_mic_data(char *buffer, uint32_t size)
{
return raw_stream_read(raw_read, buffer, size);
}
static bk_err_t send_mic_data_send_msg(wanson_asr_op_t op, void *param)
{
bk_err_t ret;
wanson_asr_msg_t msg;
msg.op = op;
msg.param = param;
if (wanson_asr_msg_que) {
ret = rtos_push_to_queue(&wanson_asr_msg_que, &msg, BEKEN_NO_WAIT);
if (kNoErr != ret) {
LOGE("send_mic_data_send_msg fail \r\n");
return kOverrunErr;
}
return ret;
}
return kNoResourcesErr;
}
static bk_err_t _xiao_feng_guan_jia_act(void)
{
return BK_OK;
}
static bk_err_t _a_er_mi_nuo_act(void)
{
ui_tabview_set(1);
#if VOICE_PLAY
#if CONFIG_86BOX_SMART_PANEL_VERSION_CN
voice_play_send_msg(VOICE_PLAY_START, "armino.pcm");
#else
voice_play_send_msg(VOICE_PLAY_START, "armino_EN.pcm");
#endif
#endif
return BK_OK;
}
static bk_err_t _hui_ke_mo_shi_act(void)
{
lv_event_send(ui_Ui2Panel2, LV_EVENT_CLICKED, NULL);
if(lv_obj_has_state(ui_Ui2Panel2, LV_STATE_CHECKED)) {
lv_obj_clear_state(ui_Ui2Panel2, LV_STATE_CHECKED);
#if VOICE_PLAY
#if CONFIG_86BOX_SMART_PANEL_VERSION_CN
voice_play_send_msg(VOICE_PLAY_START, "hui_ke_mode_close.pcm");
#else
voice_play_send_msg(VOICE_PLAY_START, "hui_ke_mode_close_EN.pcm");
#endif
#endif
} else {
lv_obj_add_state(ui_Ui2Panel2, LV_STATE_CHECKED);
#if VOICE_PLAY
#if CONFIG_86BOX_SMART_PANEL_VERSION_CN
voice_play_send_msg(VOICE_PLAY_START, "hui_ke_mode_open.pcm");
#else
voice_play_send_msg(VOICE_PLAY_START, "hui_ke_mode_open_EN.pcm");
#endif
#endif
}
lv_event_send(ui_Ui2Panel2, LV_EVENT_VALUE_CHANGED, NULL);
return BK_OK;
}
static bk_err_t _yong_can_mo_shi_act(void)
{
lv_event_send(ui_Ui2Panel4, LV_EVENT_CLICKED, NULL);
if(lv_obj_has_state(ui_Ui2Panel4, LV_STATE_CHECKED)) {
lv_obj_clear_state(ui_Ui2Panel4, LV_STATE_CHECKED);
#if VOICE_PLAY
#if CONFIG_86BOX_SMART_PANEL_VERSION_CN
voice_play_send_msg(VOICE_PLAY_START, "yong_can_mode_close.pcm");
#else
voice_play_send_msg(VOICE_PLAY_START, "yong_can_mode_close_EN.pcm");
#endif
#endif
} else {
lv_obj_add_state(ui_Ui2Panel4, LV_STATE_CHECKED);
#if VOICE_PLAY
#if CONFIG_86BOX_SMART_PANEL_VERSION_CN
voice_play_send_msg(VOICE_PLAY_START, "yong_can_mode_open.pcm");
#else
voice_play_send_msg(VOICE_PLAY_START, "yong_can_mode_open_EN.pcm");
#endif
#endif
}
lv_event_send(ui_Ui2Panel4, LV_EVENT_VALUE_CHANGED, NULL);
return BK_OK;
}
static bk_err_t _li_kai_mo_shi_act(void)
{
lv_event_send(ui_Ui2Panel3, LV_EVENT_CLICKED, NULL);
lv_obj_clear_state(ui_Ui2Panel2, LV_STATE_CHECKED);
lv_obj_clear_state(ui_Ui2Panel4, LV_STATE_CHECKED);
#if VOICE_PLAY
#if CONFIG_86BOX_SMART_PANEL_VERSION_CN
voice_play_send_msg(VOICE_PLAY_START, "li_kai_mode.pcm");
#else
voice_play_send_msg(VOICE_PLAY_START, "li_kai_mode_EN.pcm");
#endif
#endif
return BK_OK;
}
static bk_err_t _hui_jia_mo_shi_act(void)
{
lv_event_send(ui_Ui2Panel1, LV_EVENT_CLICKED, NULL);
lv_obj_add_state(ui_Ui2Panel2, LV_STATE_CHECKED);
lv_obj_add_state(ui_Ui2Panel4, LV_STATE_CHECKED);
#if VOICE_PLAY
#if CONFIG_86BOX_SMART_PANEL_VERSION_CN
voice_play_send_msg(VOICE_PLAY_START, "hui_jia_mode.pcm");
#else
voice_play_send_msg(VOICE_PLAY_START, "hui_jia_mode_EN.pcm");
#endif
#endif
return BK_OK;
}
static bk_err_t wanson_asr_result_handle(const char *result)
{
BK_LOGE(TAG, " ASR Result: \n"); //识别结果打印
for (uint8_t n = 0; n >= 0; n++) {
os_printf("0x%02x \n", (uint8_t)text[n]);
if (text[n] == 0x00) {
break;
}
}
if (os_strcmp(text, result0) == 0) { //识别出唤醒词 小蜂管家
BK_LOGI(TAG, "%s \n", "xiao feng guan jia ");
_xiao_feng_guan_jia_act();
} else if (os_strcmp(text, result1) == 0) { //识别出唤醒词 阿尔米诺
BK_LOGI(TAG, "%s \n", "a er mi nuo ");
_a_er_mi_nuo_act();
} else if (os_strcmp(text, result2) == 0) { //识别出 会客模式
BK_LOGI(TAG, "%s \n", "hui ke mo shi ");
_hui_ke_mo_shi_act();
} else if (os_strcmp(text, result3) == 0) { //识别出 用餐模式
BK_LOGI(TAG, "%s \n", "yong can mo shi ");
_yong_can_mo_shi_act();
} else if (os_strcmp(text, resulta) == 0) { //识别出 离开模式
BK_LOGI(TAG, "%s \n", "li kai mo shi ");
_li_kai_mo_shi_act();
} else if (os_strcmp(text, resultc) == 0) { //识别出 回家模式
BK_LOGI(TAG, "%s \n", "hui jia mo shi ");
_hui_jia_mo_shi_act();
} else {
BK_LOGI(TAG, "other command \n");
}
return BK_OK;
}
static void wanson_asr_task_main(beken_thread_arg_t param_data)
{
bk_err_t ret = BK_OK;
int read_size = 0;
uint8_t *aud_temp_data = os_malloc(RAW_READ_SIZE);
if (!aud_temp_data)
{
BK_LOGE(TAG, "malloc aud_temp_data\n");
goto wanson_asr_exit;
}
os_memset(aud_temp_data, 0, RAW_READ_SIZE);
if (Wanson_ASR_Init() < 0)
{
os_printf("Wanson_ASR_Init Failed!\n");
goto wanson_asr_exit;
}
Wanson_ASR_Reset();
BK_LOGI(TAG, "Wanson_ASR_Init OK!\n");
wanson_asr_op_t task_state = WANSON_ASR_IDLE;
wanson_asr_msg_t msg;
uint32_t wait_time = BEKEN_WAIT_FOREVER;
while (1) {
ret = rtos_pop_from_queue(&wanson_asr_msg_que, &msg, wait_time);
if (kNoErr == ret) {
switch (msg.op) {
case WANSON_ASR_IDLE:
task_state = WANSON_ASR_IDLE;
wait_time = BEKEN_WAIT_FOREVER;
break;
case WANSON_ASR_EXIT:
LOGD("goto: WANSON_ASR_EXIT \r\n");
goto wanson_asr_exit;
break;
case WANSON_ASR_START:
task_state = WANSON_ASR_START;
wait_time = 0;
break;
default:
break;
}
}
/* read mic data and send */
if (task_state == WANSON_ASR_START) {
// GPIO_UP(6);
read_size = wanson_read_mic_data((char *)aud_temp_data, RAW_READ_SIZE);
if (read_size == RAW_READ_SIZE) {
// GPIO_UP(44);
rs = Wanson_ASR_Recog((short*)aud_temp_data, 480, &text, &score);
// GPIO_DOWN(44);
if (rs == 1) {
wanson_asr_result_handle(text);
}
} else {
BK_LOGE(TAG, "wanson_read_mic_data fail, read_size: %d \n", read_size);
}
// GPIO_DOWN(6);
}
}
wanson_asr_exit:
if (aud_temp_data) {
os_free(aud_temp_data);
aud_temp_data == NULL;
}
Wanson_ASR_Release();
/* delete msg queue */
ret = rtos_deinit_queue(&wanson_asr_msg_que);
if (ret != kNoErr) {
LOGE("delete message queue fail \r\n");
}
wanson_asr_msg_que = NULL;
LOGI("delete send_mic_que \r\n");
/* delete task */
wanson_asr_task_hdl = NULL;
rtos_delete_thread(NULL);
}
static bk_err_t wanson_asr_task_init(void)
{
bk_err_t ret = BK_OK;
ret = rtos_init_queue(&wanson_asr_msg_que,
"send_mic_que",
sizeof(wanson_asr_msg_t),
2);
if (ret != kNoErr)
{
LOGE("ceate voice send mic data message queue fail\n");
return BK_FAIL;
}
LOGI("ceate voice send mic data message queue complete\n");
ret = rtos_create_thread(&wanson_asr_task_hdl,
6,
"wanson_asr",
(beken_thread_function_t)wanson_asr_task_main,
1024,
NULL);
if (ret != kNoErr)
{
LOGE("Error: Failed to create send_mic_task task \n");
ret = rtos_deinit_queue(&wanson_asr_msg_que);
if (ret != kNoErr) {
LOGE("delete message queue fail \r\n");
}
wanson_asr_msg_que = NULL;
return kGeneralErr;
}
LOGI("init send_mic_task task complete \n");
return BK_OK;
}
bk_err_t wanson_asr_init(void)
{
#if CONFIG_SOC_BK7236XX
bk_pm_module_vote_cpu_freq(PM_DEV_ID_AUDIO, PM_CPU_FRQ_480M);
#endif
#if CONFIG_SOC_BK7256XX
bk_pm_module_vote_cpu_freq(PM_DEV_ID_AUDIO, PM_CPU_FRQ_320M);
#endif
/* init wanson asr task */
wanson_asr_task_init();
record_pipeline_open();
return BK_OK;
}
bk_err_t wanson_asr_deinit(void)
{
send_mic_data_send_msg(WANSON_ASR_EXIT, NULL);
record_pipeline_close();
bk_pm_module_vote_cpu_freq(PM_DEV_ID_AUDIO, PM_CPU_FRQ_DEFAULT);
return BK_OK;
}
bk_err_t wanson_asr_start(void)
{
if (BK_OK != audio_pipeline_run(record_pipeline)) {
BK_LOGE(TAG, "pipeline run fail, %d \n", __LINE__);
return BK_FAIL;
}
send_mic_data_send_msg(WANSON_ASR_START, NULL);
return BK_OK;
}
bk_err_t wanson_asr_stop(void)
{
send_mic_data_send_msg(WANSON_ASR_IDLE, NULL);
if (BK_OK != audio_pipeline_stop(record_pipeline)) {
BK_LOGE(TAG, "pipeline stop fail, %d \n", __LINE__);
return BK_FAIL;
}
if (BK_OK != audio_pipeline_wait_for_stop(record_pipeline)) {
BK_LOGE(TAG, "pipeline wait stop fail, %d \n", __LINE__);
return BK_FAIL;
}
return BK_OK;
}