From: p15692025051 <846603105@qq.com> Date: Tue, 3 Jun 2025 02:26:42 +0000 (+0800) Subject: 新增led前备份,已加5秒内重复触发vad打断,续写asr结果 X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=2dccfaea8e5f9474401a08d3c365131215a6668e;p=mirrors%2FFX01.git 新增led前备份,已加5秒内重复触发vad打断,续写asr结果 --- diff --git a/2.code/aicos/app/AI_AMP_2_5/AI_AMP_2_5.c b/2.code/aicos/app/AI_AMP_2_5/AI_AMP_2_5.c index bb20303..a6dbc73 100644 --- a/2.code/aicos/app/AI_AMP_2_5/AI_AMP_2_5.c +++ b/2.code/aicos/app/AI_AMP_2_5/AI_AMP_2_5.c @@ -30,7 +30,7 @@ #include "sysoff.h" // #include "opus/include/opus.h" u8 current_card_id = 0; -u8 Close_flag = 0; +u8 VC_TTS_PLAY_EVENT = 0; typedef enum { inbound_attributes_format_PCM, @@ -41,9 +41,12 @@ AI_AMP_2_5_cfg vc_cfg; volatile char app_audio_flag = 0; volatile char audio_stop_flag = 0; int32_t bk_audio_start_callback(void *p_param, uint32_t size); -#define VAD_RB_LEN 16*1024 +#define VAD_RB_LEN 64*1024 bk_ring_buf_t *VAD_rb_data = NULL; -int VAD_status = 0;//VAD状态 +static u32 VAD_status = 0;//VAD状态 +static u32 VAD_time = 0;//缓存上一次VAD触发结束时间 +static int VAD_time_count = 0;//上一次VAD触发结束到下一次触发开始间隔时间,用来判断是否超时,没超时拼接上一次asr结果 +#define VAD_TIMEOUT 5000 char VC_mode = 0;//0:短按连续问答模式 1:长按录音模式 #define ai_VC_task_priority 35 static aos_thread_id AI_AMP_task_id = 0; @@ -75,6 +78,10 @@ static u32 close_timerout = 0; static u32 VC_pingping_timerout = 0; static u32 VC_END_play_timerout = 0; static char *AI_TTS_str = NULL; +static char *AI_ASR_str = NULL; +#define AI_ASR_STR_MAX_LEN 1024*2 +static char *AI_ASR_str_tmp = NULL; +#define AI_ASR_STR_MAX_TMP_LEN 1024 static aos_timer_ptr AI_VC_1S_timer = NULL; // OpusEncoder *opus_encoder_h = NULL; // OpusDecoder *opus_decoder_h = NULL; @@ -208,8 +215,8 @@ void reset_VC_cfg(void) { vc_cfg.start_flag = 0xaaaa; vc_cfg.end_flag = 0xaaaa; - vc_cfg.dev_type = DEV_FX1_H;//产品 - //vc_cfg.dev_type = DEV_ADS;//奥德赛 + //vc_cfg.dev_type = DEV_FX1_H;//产品 + vc_cfg.dev_type = DEV_ADS;//奥德赛 //strcpy(vc_cfg.server_ip,"amp.raisound.com");//服务器地址 strcpy(vc_cfg.server_ip,"115.190.94.208:22080");//服务器地址 vc_cfg.VC_mode =0;//对话模式 @@ -239,7 +246,8 @@ int init_VC_cfg(void) bk_printf("init_VC_cfg:获取配置正常。vc_cfg.VC_TTS_volume:%d",vc_cfg.VC_TTS_volume); }else if(vc_cfg.start_flag == 0xaaaa && vc_cfg.end_flag != 0xaaaa)//结构体新增参数 { - + bk_printf("init_VC_cfg:新增配置"); + reset_VC_cfg(); }else //if(vc_cfg.start_flag != 0xaaaa && vc_cfg.end_flag != 0xaaaa)//m没有配置,要初始化配置 { bk_printf("init_VC_cfg:没有配置"); @@ -447,7 +455,22 @@ int check_text(char *text,int ret_str_len) } if(ret_str_len<16 && (strstr(text,"关机") )) { - AI_AMP_MSG_put(tmp_data,tmp_data_len,POWER_OFF); + tmp_data_len = snprintf(tmp_data,sizeof(tmp_data),"正在关机。"); + AI_AMP_MSG_put(tmp_data,tmp_data_len,VC_TTS_PLAY_POWER_OFF); + } + if(ret_str_len<16 && (strstr(text,"重启") )) + { + tmp_data_len = snprintf(tmp_data,sizeof(tmp_data),"正在重启。"); + AI_AMP_MSG_put(tmp_data,tmp_data_len,VC_TTS_PLAY_RESET); + } + if(ret_str_len<24 && (strstr(text,"恢复出厂") )) + { + reset_VC_cfg(); + tmp_data_len = snprintf(tmp_data,sizeof(tmp_data),"恢复出厂成功,即将重启。"); + AI_AMP_MSG_put(tmp_data,tmp_data_len,VC_TTS_PLAY_RESET); + is_save_VC_cfg = 1; + ret = 0; + goto RET; } RET: if(is_save_VC_cfg == 1) @@ -507,7 +530,13 @@ static void AI_VC_send_satrt(void) cJSON *payload = cJSON_CreateObject(); cJSON_AddStringToObject(payload, "device_id", vc_cfg.dev_imei); cJSON_AddStringToObject(payload, "user_agent", "AudioClient/1.0"); - + if(AI_ASR_str && VAD_time_count !=0 && VAD_time_count <= VAD_TIMEOUT )//时间间隔短,认为是一次对话,加上上一次内容 + { + if(strlen(AI_ASR_str)>0) + cJSON_AddStringToObject(payload, "previous_result_text",AI_ASR_str); + bk_printf("上次asr内容追加:%s",AI_ASR_str); + + } // 创建 dialog_attributes 对象 cJSON *dialog_attributes = cJSON_CreateObject(); if(vc_cfg.dev_type == DEV_ADS) @@ -838,18 +867,6 @@ static void AI_VC_send_task(void *thread_input)//websocket 发送线程 opus_count += enc_inparam.output_len_array[i]; } bk_printf("opus data send:opus_count=%d",opus_count); - //测试: - // memset(pcm_data,0,AI_VC_send_queue_data.len); - // dec_inparam.input = opus_data; - // dec_inparam.inputfrm_count = enc_inparam.ouputfrm_cnt; - // memcpy(dec_inparam.input_len_array , enc_inparam.output_len_array, sizeof(dec_inparam.input_len_array)); - // dec_inparam.output = (int16_t*)pcm_data; - // dec_inparam.outbuffer_size = AI_VC_send_queue_data.len; - // ret = aic_opus_decode(&dec_inparam); - // audio_data(pcm_data,dec_inparam.outputfrms_size,25); - ////aos_sleep(10); - //bk_printf("OPUS:inputfrm_count:%d,opus_remain_size:%d,pcm_len:%d,dec_pcm_len:%d,opus_count:%d", - // dec_inparam.inputfrm_count,opus_remain_size,AI_VC_send_queue_data.len,dec_inparam.outputfrms_size,opus_count); if(opus_data) aic_free(opus_data); if(pcm_data) @@ -870,7 +887,6 @@ static void AI_VC_send_task(void *thread_input)//websocket 发送线程 bk_printf("send ret=%d,len=%d,str=%s",ret,AI_VC_send_queue_data.len,AI_VC_send_queue_data.data); else if(AI_VC_send_queue_data.AIC_WEBSOCKET_OPCODE ==AIC_WEBSOCKET_OPCODE_BINARY_FRAME ) { - audio_data(AI_VC_send_queue_data.data,AI_VC_send_queue_data.len,21); bk_printf("send ret=%d,len=%d",ret,AI_VC_send_queue_data.len); } @@ -928,7 +944,7 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 if(code == WS_TEXT)//字符串 { //bk_printf("AI_VC_read_task 3"); - bk_printf("read TEXT:status:%d,data:%s\n",status,recv_buff); + bk_printf("read TEXT:status:%d,data:%s",status,recv_buff); if(strstr(recv_buff,"\"started\""))//开始 { @@ -961,12 +977,47 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 //bk_printf("content!!"); str_tmp += strlen("\"content\":\""); int str_tmp_len = str_count(str_tmp,'\"'); - + //存asr结果 + if(AI_ASR_str_tmp) + { + if(str_tmp_len>AI_ASR_STR_MAX_LEN-1) + str_tmp_len = AI_ASR_STR_MAX_LEN-1; + memcpy(AI_ASR_str_tmp,str_tmp,str_tmp_len); + AI_ASR_str_tmp[str_tmp_len] = 0; + } + + int ret = check_text(str_tmp,str_tmp_len) ; //识别到有命令词,退出 if(ret == 0) break; } + }else if(strstr(recv_buff,"\"asr.completed\""))//asr结束 + { + if(AI_ASR_str && AI_ASR_str_tmp) + { + if(VAD_time_count <= VAD_TIMEOUT )//时间间隔短,认为是一次对话,拼接内容 + { + + + + if(strlen(AI_ASR_str) +strlen(AI_ASR_str_tmp)> AI_ASR_STR_MAX_LEN-1)//超出缓存长度,清零 + { + memset(AI_ASR_str,0,AI_ASR_STR_MAX_LEN); + bk_printf("ASR内容超出缓存长度,清零缓存"); + + } + strncpy(AI_ASR_str+strlen(AI_ASR_str),AI_ASR_str_tmp,AI_ASR_STR_MAX_LEN -strlen(AI_ASR_str) ); + + + bk_printf("vad间隔时间短拼接asr结果:%s",AI_ASR_str); + + }else//超时,不用拼接 + { + strncpy(AI_ASR_str,AI_ASR_str_tmp,AI_ASR_STR_MAX_LEN); + bk_printf("vad间隔时间长,判断为两次对话:%s",AI_ASR_str); + } + } } else if(strstr(recv_buff,"\"vad.active\""))//vad触发 { @@ -979,6 +1030,7 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 else if(strstr(recv_buff,"\"tts.started\""))//tts开始 { VC_state = VC_State_TTSStart; + play_data_len = 0; AI_AMP_MSG_put(0,0,VC_PLAY_START);//打开声音 }else if(strstr(recv_buff,"\"tts.completed\""))//tts结束 @@ -997,17 +1049,7 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 else if(code == WS_BINARY)//二进制 { - // for(int i = 0;i<4;i++) - // { - // audio_data(recv_buff+status/4*i,status/4,24); - // //bk_printf("recv_buff len = %d",status/4); - // aos_sleep(1); - // } - // if(status%4) - // { - // audio_data(recv_buff+status/4*4,status%4,24); - // aos_sleep(1); - // } + //bk_printf("read BIN status:%d,code:%d!!!!!!",status,code); AI_VC_put_play_data(recv_buff,status);//音频调试1 @@ -1030,7 +1072,7 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 aos_sleep(1); }else { - bk_printf("AI_VC_read_task:error AI_VC_client_websocket_handle=%d\n",AI_VC_client_websocket_handle); + bk_printf("AI_VC_read_task:error AI_VC_client_websocket_handle=%d",AI_VC_client_websocket_handle); break; } // bk_printf("AI_VC_read_task ..... \n"); @@ -1084,7 +1126,7 @@ static void AI_VC_record_task(void *thread_input)//录音线程 aos_sleep(1); continue; } - audio_data(vrecord_buf,ret,23); + if(vc_cfg.is_VAD == 1)//VAD逻辑:先判断有没有有效数据,触发了有效数据才发送 { @@ -1093,37 +1135,48 @@ static void AI_VC_record_task(void *thread_input)//录音线程 run_vad((int16_t *)vrecord_buf, ret / 2); vad_status_t = vad_detect(); //bk_printf("VAD:vad_status_t:%d",vad_status_t); - - if (vad_status_t == 2) { + audio_data(vrecord_buf,ret,23); + if (vad_status_t == 2) {//说话停止 vad_clear(); if(VAD_status == 1)//清空buff { + //VAD_timeout = aos_get_tickcount()-VAD_time; + VAD_time = aos_get_tickcount(); bk_rb_clear(VAD_rb_data); AI_VC_put_record_data(vrecord_buf,ret); } VAD_status = 2; - + audio_data(vrecord_buf,ret,21); + memset(vrecord_buf,0xff,sizeof(vrecord_buf)); + audio_data(vrecord_buf,sizeof(vrecord_buf),21); }else if(vad_status_t == 1 )//检测到说话 { if(VAD_status ==0)//第一次检测到说话 { + if(VAD_time !=0) + VAD_time_count = aos_get_tickcount()-VAD_time; int rb_len_t = bk_rb_data_len(VAD_rb_data); bk_printf("VAD:检测到说话了,回溯音频大小:%d,VC_state:%d",rb_len_t,VC_state); + unsigned char *vad_r_tmp = aic_malloc(2560); while(bk_rb_data_len(VAD_rb_data))//清空缓存数据 { - unsigned char *vad_r_tmp = aic_malloc(1280); + if(vad_r_tmp) { - unsigned int r_len = bk_rb_read(VAD_rb_data,vad_r_tmp,1280); + unsigned int r_len = bk_rb_read(VAD_rb_data,vad_r_tmp,2560); //AI_VC_send_data(vad_r_tmp,r_len,AIC_WEBSOCKET_OPCODE_BINARY_FRAME);//发送缓冲数据 AI_VC_put_record_data(vad_r_tmp,r_len);//入队缓冲数据 - aic_free(vad_r_tmp); + audio_data(vad_r_tmp,r_len,21); + } } + if(vad_r_tmp) + aic_free(vad_r_tmp); VAD_status = 1; } AI_VC_put_record_data(vrecord_buf,ret); + audio_data(vrecord_buf,ret,21); //bk_printf("VAD:检测到说话了"); }else if(vad_status_t == 0 )//m没有说话 { @@ -1145,7 +1198,7 @@ static void AI_VC_record_task(void *thread_input)//录音线程 bk_rb_write(VAD_rb_data,vrecord_buf,ret); } } - + VAD_status =0; } u32 count_tmp = 0; if(AI_VC_record_tmp_queue) @@ -1267,7 +1320,7 @@ static void AI_VC_play_task(void *thread_input)//音频播放线程 if(AI_VC_play_task_flag >=2) break; //app_logi("app_audio_write0!!\r\n"); - if(VC_Play_flag ==1 && AI_VC_play_queue ) + if(play_data_len>8*1024 &&VC_Play_flag ==1 && AI_VC_play_queue ) { queue_ret = aos_recv_from_queue(AI_VC_play_queue,&AI_VC_play_queue_data,AOS_NO_WAIT); if( queue_ret== AOS_SUCCESS) @@ -1696,12 +1749,19 @@ static void AI_VC_1S_timeout(void *param) { if(VC_mode == 0) { - if(Close_flag == 1) + if(VC_TTS_PLAY_EVENT == VC_TTS_PLAY_CLOSE) { - Close_flag = 0; + VC_TTS_PLAY_EVENT = 0; AI_AMP_MSG_put(0,0,VC_CLOSE); - }else + }else if (VC_TTS_PLAY_EVENT == VC_TTS_PLAY_POWER_OFF) { + AI_AMP_MSG_put(0,0,POWER_OFF); + }else if (VC_TTS_PLAY_EVENT == VC_TTS_PLAY_RESET) + { + AI_AMP_MSG_put(0,0,POWER_RESET); + } + + else{ VAD_status = 0; VC_state = VC_State_Listening;//重新开始了 } @@ -1819,12 +1879,23 @@ void AI_VC_start(void) bk_printf("app_audio_start ret=%d",ret); app_logi("app_audio_start ret=%d",ret); } - // aic_gpio_output(GPIO_25,GPIO_OUTPUT_LVL_HIGH );//led - // aic_gpio_output(GPIO_30,GPIO_OUTPUT_LVL_HIGH );//led - // aic_gpio_output(GPIO_31,GPIO_OUTPUT_LVL_HIGH );//led - // aic_gpio_output(GPIO_GPO_8,GPIO_OUTPUT_LVL_HIGH );//马达 - // aic_gpio_output(GPIO_GPO_1,GPIO_OUTPUT_LVL_LOW );//马达 - // aic_gpio_output(GPIO_20,GPIO_OUTPUT_LVL_HIGH );//马达 + VAD_time = 0; + VAD_time_count = 0; + if(AI_ASR_str_tmp == NULL) + { + AI_ASR_str_tmp = aic_zalloc(AI_ASR_STR_MAX_TMP_LEN); + } + if(AI_ASR_str == NULL) + { + AI_ASR_str = aic_zalloc(AI_ASR_STR_MAX_LEN); + + } + aic_gpio_output(GPIO_25,GPIO_OUTPUT_LVL_HIGH );//led + aic_gpio_output(GPIO_30,GPIO_OUTPUT_LVL_HIGH );//led + aic_gpio_output(GPIO_31,GPIO_OUTPUT_LVL_HIGH );//led + aic_gpio_output(GPIO_GPO_8,GPIO_OUTPUT_LVL_HIGH );//马达 + aic_gpio_output(GPIO_GPO_1,GPIO_OUTPUT_LVL_LOW );//马达 + aic_gpio_output(GPIO_20,GPIO_OUTPUT_LVL_HIGH );//马达 //app_audio_set_master_volume(8); // if (ret) { // bk_printf("AI_VC_start app_audio_start error"); @@ -1919,12 +1990,12 @@ void AI_VC_start(void) void AI_VC_Close(void) { int count; - // aic_gpio_output(GPIO_25,GPIO_OUTPUT_LVL_LOW ); - // aic_gpio_output(GPIO_30,GPIO_OUTPUT_LVL_LOW ); - // aic_gpio_output(GPIO_31,GPIO_OUTPUT_LVL_LOW ); - // aic_gpio_output(GPIO_GPO_8,GPIO_OUTPUT_LVL_LOW ); - // aic_gpio_output(GPIO_GPO_1,GPIO_OUTPUT_LVL_LOW); - // aic_gpio_output(GPIO_20,GPIO_OUTPUT_LVL_LOW ); + aic_gpio_output(GPIO_25,GPIO_OUTPUT_LVL_LOW ); + aic_gpio_output(GPIO_30,GPIO_OUTPUT_LVL_LOW ); + aic_gpio_output(GPIO_31,GPIO_OUTPUT_LVL_LOW ); + aic_gpio_output(GPIO_GPO_8,GPIO_OUTPUT_LVL_LOW ); + aic_gpio_output(GPIO_GPO_1,GPIO_OUTPUT_LVL_LOW); + aic_gpio_output(GPIO_20,GPIO_OUTPUT_LVL_LOW ); if(vc_cfg.is_VAD == 1) { // 不使用或暂停使用VAD时调用 @@ -2092,7 +2163,16 @@ void AI_VC_Close(void) } bk_printf("app_audio_stop2 audio_count:%d",audio_count); } - + if(AI_ASR_str_tmp) + { + aic_free(AI_ASR_str_tmp); + AI_ASR_str_tmp =NULL; + } + if(AI_ASR_str) + { + aic_free(AI_ASR_str); + AI_ASR_str =NULL; + } //app_logi("app_audio_stop2"); @@ -2139,7 +2219,7 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 if(pdp_activated == TRUE) break; bk_printf("AI_AMP_2_5_init 等待注网..... \n"); - audio_play_tone(3,200);//播放提示音,测试用 + audio_play_tone(count%10,500);//播放提示音,测试用 aos_sleep(1000); } @@ -2169,6 +2249,12 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 //播放关机提示音 sysoff_shutdown(); break; + case POWER_RESET://重启 + AI_VC_Close(); + //播放关机提示音 + sysoff_reset(); + break; + case VC_Cancel://打断 //发送打断 //AI_VC_send_cancel();//发送打断,发送完打断还有发开始音频 @@ -2207,12 +2293,25 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 if(AI_AMP_msg.data!=NULL) { VC_TTS_Play(AI_AMP_msg.data); - Close_flag = 1; + VC_TTS_PLAY_EVENT = VC_TTS_PLAY_CLOSE; + } + break; + case VC_TTS_PLAY_POWER_OFF://播放完关机 + if(AI_AMP_msg.data!=NULL) + { + VC_TTS_Play(AI_AMP_msg.data); + VC_TTS_PLAY_EVENT = VC_TTS_PLAY_POWER_OFF; + } + break; + case VC_TTS_PLAY_RESET://播放完重启: + if(AI_AMP_msg.data!=NULL) + { + VC_TTS_Play(AI_AMP_msg.data); + VC_TTS_PLAY_EVENT = VC_TTS_PLAY_RESET; } - - break; + case VC_CONNECT_ERROR://连接错误 AI_VC_Close(); if(AI_AMP_msg.data) diff --git a/2.code/aicos/app/AI_AMP_2_5/AI_AMP_2_5.h b/2.code/aicos/app/AI_AMP_2_5/AI_AMP_2_5.h index 57a7ac4..b2e93d5 100644 --- a/2.code/aicos/app/AI_AMP_2_5/AI_AMP_2_5.h +++ b/2.code/aicos/app/AI_AMP_2_5/AI_AMP_2_5.h @@ -43,6 +43,7 @@ extern AI_AMP_2_5_cfg vc_cfg; typedef enum AI_AMP_MSG { POWER_OFF,//关机 + POWER_RESET,//重启 VC_START, VC_PLAY_START, VC_PLAY_END, @@ -51,6 +52,8 @@ typedef enum AI_AMP_MSG VC_Cancel,//打断取消 VC_TTS_PLAY, VC_TTS_PLAY_CLOSE,//播放完关闭对话 + VC_TTS_PLAY_RESET,//播放完重启 + VC_TTS_PLAY_POWER_OFF,//播放完关机 VC_CLOSE, VC_CONNECT_ERROR, AI_KEY_PRESS,//AI键按下 diff --git a/2.code/aicos/app/AI_AMP_2_5/dev_authentication.c b/2.code/aicos/app/AI_AMP_2_5/dev_authentication.c index 7e21ade..e47c368 100644 --- a/2.code/aicos/app/AI_AMP_2_5/dev_authentication.c +++ b/2.code/aicos/app/AI_AMP_2_5/dev_authentication.c @@ -391,7 +391,7 @@ void aut_active(void)//设备激活 // 创建JSON对象 cJSON *root = cJSON_CreateObject(); if (root == NULL) { - bk_printf(stderr, "Failed to create JSON object\n"); + bk_printf( "Failed to create JSON object\n"); return ; } @@ -405,7 +405,7 @@ void aut_active(void)//设备激活 // 生成JSON字符串 char *json_string = cJSON_Print(root); if (json_string == NULL) { - bk_printf(stderr, "Failed to print JSON\n"); + bk_printf("Failed to print JSON\n"); cJSON_Delete(root); return ; }