From: p15692025051 <846603105@qq.com> Date: Mon, 23 Jun 2025 02:14:55 +0000 (+0800) Subject: 更新,vad鉴权没加 X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=982b9d85f4f8e5b2adecdd43fe003c368e290343;p=mirrors%2FFX01.git 更新,vad鉴权没加 --- 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 a511aeb..6f76250 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 @@ -1,7 +1,7 @@ #define AIC_THIS_FILE 0x888888 -#define SUPPORT_OPUS 1 + #include #include #include @@ -22,7 +22,9 @@ #include #if SUPPORT_OPUS #include "opus/guixin/opus_interface.h" + #endif +#include "bk_opus_coder.h" #include "dev_authentication.h" #include "imsl_vad.h" #include "imsl_kws.h" @@ -30,33 +32,37 @@ #include "power_supply.h" #include "sysoff.h" #include "app_msg.h" +#include "aic_ogg.h" +#include "efuse.h" // #include "opus/include/opus.h" u8 current_card_id = 0; u8 VC_TTS_PLAY_EVENT = 0; typedef enum { - inbound_attributes_format_PCM, - inbound_attributes_format_OPUS, -}inbound_attributes_format_type; -inbound_attributes_format_type inbound_attributes_format = inbound_attributes_format_PCM; + attributes_format_PCM, + attributes_format_OPUS, +}attributes_format_type; +attributes_format_type inbound_attributes_format = attributes_format_PCM; +attributes_format_type outbound_attributes_format = attributes_format_OPUS; #define OPUS_ENCODER_PACK_MS 60 //多少ms一帧数据 -#define OPUS_PERIOD_MS OPUS_PERIOD_60_MS -#define OPUS_RB_LEN OPUS_ENCODER_PACK_MS*32*10//10贞数据 -bk_ring_buf_t *OPUS_rb_data = NULL; + + +int send_opus_data(char *PCM_data,int data_len); AI_AMP_2_5_cfg vc_cfg; +volatile char AI_VC_stata = 0;//VC是否在运行 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 IS_KWS 0 #define IS_VAD 1 -#define VAD_RB_LEN 64*1024 +#define VAD_RB_LEN 32*1024 bk_ring_buf_t *VAD_rb_data = NULL; 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:长按录音模式 +//char vc_cfg.VC_mode = 0;//0:短按连续问答模式 1:长按录音模式 #define ai_VC_task_priority 35 static aos_thread_id AI_AMP_task_id = 0; static aos_queue_ptr AI_AMP_task_queue = NULL; @@ -97,17 +103,16 @@ static aos_timer_ptr sys_10S_timer = NULL; static int login_timer_count = 0; static int power_off_count = 60*6*24; -// OpusEncoder *opus_encoder_h = NULL; -// OpusDecoder *opus_decoder_h = NULL; static void play_file_stop(void); -static struct opus_enc_init_param *opus_encoder_h = NULL; -static struct opus_dec_init_param *opus_decoder_h = NULL; +int get_AI_key_longstate(void); + static void AI_VC_send_satrt(void); static aos_status AI_VC_send_data(char *data,u32 len,u8 AIC_WEBSOCKET_OPCODE); VC_state_type VC_state = VC_State_None; +static u8 uid[50]; +static int uid_len =0; -static void AI_VC_put_play_data(char *data,u32 len);//音频数据入队播放 //关闭录音 void VC_record_End(void); //打开录音 @@ -130,6 +135,7 @@ int bk_get_imei(char *imei) strcpy(imei,vc_cfg.dev_imei); return 0; } +#if (BK_LOG_CFG==BK_LOG_UART) int bk_printf(const char *format, ...) { int ret=0; @@ -153,6 +159,35 @@ int bk_printf(const char *format, ...) aic_free(out); return ret; } +#elif (BK_LOG_CFG == BK_LOG_USB) +int bk_printf(const char *format, ...) +{ + int ret=0; + int bk_printf_count = 10*1024; + va_list args; + char *out = NULL; + out = aic_zalloc(bk_printf_count); + if(!out) + { + app_logi("bk_printf ERROR!!!!!\r\n"); + return 0; + } + va_start( args, format ); + ret = vsnprintf(out, bk_printf_count, format, args); + memcpy(out+ret,"\r\n",2); + ret+=2; + uart_write(ai_uart_handle,out, ret); + app_logi("[BK]%s",out); + //aos_sleep(100); + va_end( args ); + aic_free(out); + return ret; +} +#else +int bk_printf(const char *format, ...) +{ +} +#endif //用于定时器打印 int bk_msg_printf(const char *format, ...) { @@ -191,6 +226,10 @@ void bk_print_hex(u8 *data,int data_len) { tmp_len = snprintf(tmp,sizeof(tmp),"%02X ",data[i]); uart_write(ai_uart_handle,tmp, tmp_len); + if((i+1)%16 ==0) + { + uart_write(ai_uart_handle,"\r\n", 2); + } } uart_write(ai_uart_handle,"\r\n", 2); } @@ -231,7 +270,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_ADS;//奥德赛 + vc_cfg.dev_type = DEV_JSWM;//金山完美 //strcpy(vc_cfg.server_ip,"amp.raisound.com");//服务器地址 strcpy(vc_cfg.server_ip,"115.190.94.208:22080");//服务器地址 vc_cfg.VC_mode =0;//对话模式 @@ -244,7 +284,7 @@ void reset_VC_cfg(void) vc_cfg.is_KWS = IS_KWS;//=1打开本地语言打断 vc_cfg.speech_rate = 0;//语速配置 vc_cfg.vad_silence = 200;//vad断句时间 ms - vc_cfg.VC_TTS_volume = 50;//音量 + vc_cfg.VC_TTS_volume = 80;//音量 } int init_VC_cfg(void) { @@ -337,6 +377,33 @@ int check_text(char *text,int ret_str_len) goto RET; } } + if(strstr(text,"切换")) + { + if(strstr(text,"对话模式") || strstr(text,"兑换模式")) + { + vc_cfg.VC_mode+=1; + if(vc_cfg.VC_mode > 2) + vc_cfg.VC_mode = 0; + bk_printf("切换对话模式:vc_cfg.VC_mode :%d",vc_cfg.VC_mode ); + if(vc_cfg.VC_mode == 0) + { + AI_AMP_MSG_put("已切换到连续对话模式。",strlen("已切换到连续对话模式。"),VC_TTS_PLAY); + + }else if(vc_cfg.VC_mode == 1) + { + AI_AMP_MSG_put("已切换到单对话模式。长按按钮说话,说完松开即可。",strlen("已切换到单对话模式。长按按钮说话,说完松开即可。"),VC_TTS_PLAY); + + }else + { + AI_AMP_MSG_put("已切换到按键打断模式。我说话的时候需要短按按钮打断。",strlen("已切换到按键打断模式。我说话的时候需要短按按钮打断。"),VC_TTS_PLAY); + } + is_save_VC_cfg = 1; + ret = 0; + goto RET; + } + + } + if(strstr(text,"查询")) { if(strstr(text,"信号")) @@ -622,8 +689,14 @@ static void AI_VC_send_satrt(void) cJSON_AddStringToObject(outbound_attributes, "provider", "volcengine"); // 创建 outbound_attributes 下的 cfg 对象 cJSON *outbound_cfg = cJSON_CreateObject(); - cJSON_AddStringToObject(outbound_cfg, "format", "pcm"); - cJSON_AddNumberToObject(outbound_cfg, "sample_rate", 16000); + if(outbound_attributes_format == attributes_format_OPUS) + { + cJSON_AddStringToObject(outbound_cfg, "format", "ogg_opus"); + cJSON_AddNumberToObject(outbound_cfg, "compression_rate", 20); + } + else + cJSON_AddStringToObject(outbound_cfg, "format", "pcm"); + cJSON_AddNumberToObject(outbound_cfg, "sample_rate", vc_cfg.VC_play_samplerate); cJSON_AddNumberToObject(outbound_cfg, "bit_rate", 16); cJSON_AddNumberToObject(outbound_cfg, "channel", 1); cJSON_AddNumberToObject(outbound_cfg, "volume", 100); @@ -644,7 +717,7 @@ static void AI_VC_send_satrt(void) // 创建 inbound_attributes 对象 cJSON *inbound_attributes = cJSON_CreateObject(); cJSON_AddStringToObject(inbound_attributes, "provider", "volcengine"); - if(VC_mode == 0 && vc_cfg.is_VAD == 0)//连续对话模式 + if(vc_cfg.VC_mode == 0 && vc_cfg.is_VAD == 0)//连续对话模式,开在线vad cJSON_AddBoolToObject(inbound_attributes, "disable_vad", 0); else cJSON_AddBoolToObject(inbound_attributes, "disable_vad", 1); @@ -667,7 +740,7 @@ static void AI_VC_send_satrt(void) // 创建 inbound_attributes 下的 cfg 对象 cJSON *inbound_cfg = cJSON_CreateObject(); - if(inbound_attributes_format == inbound_attributes_format_OPUS) + if(inbound_attributes_format == attributes_format_OPUS) { cJSON_AddStringToObject(inbound_cfg, "codec", "opus"); cJSON_AddStringToObject(inbound_cfg, "format", "pcm"); @@ -675,7 +748,7 @@ static void AI_VC_send_satrt(void) else cJSON_AddStringToObject(inbound_cfg, "format", "pcm"); - cJSON_AddNumberToObject(inbound_cfg, "sample_rate", 16000); + cJSON_AddNumberToObject(inbound_cfg, "sample_rate", vc_cfg.VC_record_samplerate); cJSON_AddNumberToObject(inbound_cfg, "bit_rate", 16); cJSON_AddNumberToObject(inbound_cfg, "channel", 1); cJSON_AddBoolToObject(inbound_cfg, "enable_punctuation", 1); @@ -852,10 +925,30 @@ static void AI_VC_send_task(void *thread_input)//websocket 发送线程 if(AI_client_VC && AI_VC_send_queue_data.data) { VC_pingping_timerout = 4; - + if(inbound_attributes_format == attributes_format_OPUS&& AI_VC_send_queue_data.AIC_WEBSOCKET_OPCODE ==AIC_WEBSOCKET_OPCODE_BINARY_FRAME )//转码opus + { + char *opus_data = aic_malloc(OPUS_ENCODER_PACK_MS*16); + if(opus_data) + { + ret = opus_encode_data(AI_VC_send_queue_data.data,AI_VC_send_queue_data.len,OPUS_ENCODER_PACK_MS*32,opus_data,OPUS_ENCODER_PACK_MS*16); + bk_printf("opus_encode_data1:len:%d",ret); + if(ret >0) + { + AI_VC_send_queue_data.len = ret; + ret = send_websocket_message(AI_client_VC,opus_data,ret,(WebSocketMessageType)AI_VC_send_queue_data.AIC_WEBSOCKET_OPCODE); + } + + aic_free(opus_data); + } + else + { + bk_printf("opus_data malloc error!"); + } + }else { ret = send_websocket_message(AI_client_VC,AI_VC_send_queue_data.data,AI_VC_send_queue_data.len, (WebSocketMessageType)AI_VC_send_queue_data.AIC_WEBSOCKET_OPCODE); + //bk_printf("AI_VC_send_task:send str!"); } if(AI_VC_send_queue_data.AIC_WEBSOCKET_OPCODE ==AIC_WEBSOCKET_OPCODE_TEXT_FRAME ) @@ -864,8 +957,8 @@ static void AI_VC_send_task(void *thread_input)//websocket 发送线程 { bk_printf("send ret=%d,len=%d",ret,AI_VC_send_queue_data.len); } - - aic_free(AI_VC_send_queue_data.data); + if(AI_VC_send_queue_data.data) + aic_free(AI_VC_send_queue_data.data); }else { bk_printf("AI_VC_send ERROR:close_websocket_client = %d",AI_client_VC); @@ -932,16 +1025,18 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 }else { - if(VC_mode == 1)//长按模式,或者本地vad模式 + if(vc_cfg.VC_mode == 1)//长按模式 { AI_VC_send_audio_create(); - }else if(VC_mode == 0 )//连续对话模式 + }else if(vc_cfg.VC_mode == 0 )//连续对话模式 + VC_state = VC_State_Listening; + else if(vc_cfg.VC_mode == 2 )//连续对话模式,按键打断 VC_state = VC_State_Listening; } }else if(strstr(recv_buff,"\"asr.started\""))//asr开始 { - if(VC_mode == 1 || vc_cfg.is_VAD ==1)//长按模式 + if(vc_cfg.VC_mode == 1 || vc_cfg.is_VAD ==1)//长按模式,或开机本地vad模式 VC_state = VC_State_SpeechIng; }else if(strstr(recv_buff,"\"asr.result\"")) { @@ -963,16 +1058,17 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 } - int ret = check_text(str_tmp,str_tmp_len) ; - //识别到有命令词,退出 - if(ret == 0) - break; + } }else if(strstr(recv_buff,"\"asr.completed\""))//asr结束 { VC_state = VC_State_ASR_End; if(AI_ASR_str && AI_ASR_str_tmp) { + int ret = check_text(AI_ASR_str_tmp,strlen(AI_ASR_str_tmp)) ; + //识别到有命令词,退出 + if(ret == 0) + break; if(VAD_time_count <= VAD_TIMEOUT )//时间间隔短,认为是一次对话,拼接内容 { @@ -1018,7 +1114,7 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 } else if(strstr(recv_buff,"\"completed\""))//结束 { - VC_state = VC_State_End;//VC_State_Listening; + VC_state = VC_State_End;// //AI_AMP_MSG_put(0,0,VC_RECORD_START);//打开录音 }else if(strstr(recv_buff,"\"event\":\"failed\""))//扣子报错 @@ -1040,10 +1136,16 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 { - //bk_printf("read BIN status:%d,code:%d!!!!!!",status,code); + bk_printf("read BIN status:%d,code:%d!!!!!!",status,code); + if(outbound_attributes_format == attributes_format_OPUS) + { + ogg_opus_decode_data(recv_buff,status); + }else + { + AI_VC_put_play_data(recv_buff,status);// + play_data_len+=status; + } - AI_VC_put_play_data(recv_buff,status);//音频调试1 - play_data_len+=status; } }else// if(status == -1)//报错,关闭连接 @@ -1077,47 +1179,8 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 AI_VC_read_task_flag=3; } -u8 opus_remain_buf[OPUS_ENCODER_PACK_MS*32]; -u32 opus_remain_len = 0; -u8 opus_data[OPUS_ENCODER_PACK_MS*16]; -void send_opus_end(void) -{ - opus_remain_len = 0; -} -// -void send_opus_data(char *PCM_data,int data_len) -{ - #if SUPPORT_OPUS - int ret; - - //struct opus_dec_param dec_inparam; - struct opus_enc_param enc_inparam; - - if(opus_remain_len+data_len>=32*OPUS_ENCODER_PACK_MS)//够一帧数据 - { - memcpy(opus_remain_buf+opus_remain_len,PCM_data,32*OPUS_ENCODER_PACK_MS-opus_remain_len); - bk_printf("send_opus_data:cpy1:偏移:%d,长度:%d",opus_remain_len,32*OPUS_ENCODER_PACK_MS-opus_remain_len); - enc_inparam.input = (int16_t*)(opus_remain_buf);//PCM数据 - enc_inparam.input_size = 32*OPUS_ENCODER_PACK_MS; - enc_inparam.output = (int8_t*)opus_data; - enc_inparam.outbuffer_size = OPUS_ENCODER_PACK_MS*16; - ret = aic_opus_encode(&enc_inparam); - //enc_inparam.output_len_array[0];//长度 - AI_VC_send_data(opus_data,enc_inparam.output_len_array[0],AIC_WEBSOCKET_OPCODE_BINARY_FRAME);//够一帧,发送数据 - bk_printf("send_opus_data:send:data_len = %d",enc_inparam.output_len_array[0]); - memcpy(opus_remain_buf,PCM_data+32*OPUS_ENCODER_PACK_MS-opus_remain_len,data_len-32*OPUS_ENCODER_PACK_MS-opus_remain_len); - bk_printf("send_opus_data:cpy2:偏移:%d,长度:%d",32*OPUS_ENCODER_PACK_MS-opus_remain_len,data_len-32*OPUS_ENCODER_PACK_MS-opus_remain_len); - opus_remain_len = data_len-32*OPUS_ENCODER_PACK_MS-opus_remain_len; - }else - { - memcpy(opus_remain_buf+opus_remain_len,PCM_data,data_len);//缓存数据,等待够一帧数据 - bk_printf("send_opus_data:cpy3:偏移:%d,长度:%d",opus_remain_len,data_len); - opus_remain_len+=data_len; - } - - #endif - -} + + u8 vrecord_buf[3500 + 4]; static void AI_VC_record_task(void *thread_input)//录音线程 { @@ -1153,7 +1216,7 @@ static void AI_VC_record_task(void *thread_input)//录音线程 vrecord_buf, 3200, 1010); // u32 timer_ms = aos_get_tickcount(); // bk_printf("%d:ret=%d",timer_ms,ret); - //bk_printf("AI_VC_record_task app_audio_read len = %d,VC_state = %d",ret,VC_state); + app_logi("AI_VC_record_task app_audio_read len = %d,VC_state = %d",ret,VC_state); if(ret<=0) { //bk_printf("AI_VC_record_task continue len = %d,VC_state = %d",ret,VC_state); @@ -1161,11 +1224,16 @@ static void AI_VC_record_task(void *thread_input)//录音线程 continue; } - if(vc_cfg.is_VAD == 1)//VAD逻辑:先判断有没有有效数据,触发了有效数据才发送 + if((vc_cfg.VC_mode == 0 || vc_cfg.VC_mode == 2)&& vc_cfg.is_VAD == 1)//VAD逻辑:先判断有没有有效数据,触发了有效数据才发送 { + if(vc_cfg.VC_mode == 2 && VC_state > VC_State_SpeechEnd )//按钮打断模式,tts播放时禁止打断,不输入语音 + continue; // 每次获得语音后调用, 语音长度最好小于100ms // wave为u8*或void*指针时需要 / 2 + //int vad_test_time = aos_get_tickcount(); + //bk_printf("run_vad vad_test_time:%d,data_len:%d",vad_test_time,ret); run_vad((int16_t *)vrecord_buf, ret / 2); + //bk_printf("run_vad 用时:%d",aos_get_tickcount()-vad_test_time); vad_status_t = vad_detect(); //bk_printf("VAD:vad_status_t:%d",vad_status_t); audio_data(vrecord_buf,ret,23); @@ -1176,6 +1244,14 @@ static void AI_VC_record_task(void *thread_input)//录音线程 //VAD_timeout = aos_get_tickcount()-VAD_time; VAD_time = aos_get_tickcount(); bk_rb_clear(VAD_rb_data); + if(inbound_attributes_format == attributes_format_OPUS)//填充更多数据,以免后面丢失 + { + if(sizeof(vrecord_buf)>ret) + { + memset(vrecord_buf+ret,0,sizeof(vrecord_buf)-ret-1); + } + ret = sizeof(vrecord_buf); + } AI_VC_put_record_data(vrecord_buf,ret); } VAD_status = 2; @@ -1226,6 +1302,8 @@ static void AI_VC_record_task(void *thread_input)//录音线程 aic_free(vad_r_tmp); VAD_status = 1; } + + AI_VC_put_record_data(vrecord_buf,ret); audio_data(vrecord_buf,ret,21); if(vc_cfg.is_KWS) @@ -1243,8 +1321,9 @@ static void AI_VC_record_task(void *thread_input)//录音线程 //bk_printf("VAD:检测到说话了"); }else if(vad_status_t == 0 )//m没有说话 { + //把音频入队,缓存回溯数据 - if(VAD_rb_data) + if(ret>0 && VAD_rb_data) { if(VAD_RB_LEN - bk_rb_data_len(VAD_rb_data) >= ret)//缓存够 { @@ -1285,12 +1364,10 @@ static void AI_VC_record_task(void *thread_input)//录音线程 if(aos_recv_from_queue(AI_VC_record_tmp_queue,&AI_VC_play_record_data,AOS_NO_WAIT) == AOS_SUCCESS)//有有效录音数据 { audio_data(AI_VC_play_record_data.data,AI_VC_play_record_data.len,22); - if(inbound_attributes_format == inbound_attributes_format_OPUS) - { - send_opus_data(AI_VC_play_record_data.data,AI_VC_play_record_data.len); - }else - AI_VC_send_data(AI_VC_play_record_data.data,AI_VC_play_record_data.len,AIC_WEBSOCKET_OPCODE_BINARY_FRAME); - aic_free(AI_VC_play_record_data.data); + + AI_VC_send_data(AI_VC_play_record_data.data,AI_VC_play_record_data.len,AIC_WEBSOCKET_OPCODE_BINARY_FRAME); + if(AI_VC_play_record_data.data) + aic_free(AI_VC_play_record_data.data); }else break; } @@ -1320,8 +1397,8 @@ static void AI_VC_record_task(void *thread_input)//录音线程 bk_printf("VAD:发送停止音频"); bk_printf("VAD:vad_status_t:%d",vad_status_t); vad_end_flag = 0; - if(inbound_attributes_format == inbound_attributes_format_OPUS) - send_opus_end(); + if(inbound_attributes_format == attributes_format_OPUS) + opus_clean(); } } @@ -1341,7 +1418,8 @@ static void AI_VC_record_task(void *thread_input)//录音线程 AI_VC_put_record_data(vrecord_buf,ret); } //else if(VC_state >= VC_State_Listening && VC_state= VC_State_Listening )//正常录音 + else if((vc_cfg.VC_mode == 0 && VC_state >= VC_State_Listening) || //连续对话模式 + ((vc_cfg.VC_mode == 1 || vc_cfg.VC_mode == 2 )&& VC_state >= VC_State_SpeechIng && VC_state < VC_State_SpeechEnd ))//长按对话模式,TTS过程不录音 { char count_t = 200; while(count_t--) @@ -1349,11 +1427,15 @@ static void AI_VC_record_task(void *thread_input)//录音线程 if(aos_recv_from_queue(AI_VC_record_tmp_queue,&AI_VC_play_record_data,AOS_NO_WAIT) == AOS_SUCCESS)//有录音数据 { AI_VC_send_data(AI_VC_play_record_data.data,AI_VC_play_record_data.len,AIC_WEBSOCKET_OPCODE_BINARY_FRAME); - aic_free(AI_VC_play_record_data.data); + if(AI_VC_play_record_data.data) + aic_free(AI_VC_play_record_data.data); }else break; } AI_VC_send_data(vrecord_buf,ret,AIC_WEBSOCKET_OPCODE_BINARY_FRAME); + + if(vc_cfg.VC_mode == 1 && get_AI_key_longstate() == 0)//长按模式,按键释放后停止发送数据 + AI_VC_send_audio_completed(); //bk_printf("AI_VC_record_task send_data len = %d",ret); }else { @@ -1362,7 +1444,8 @@ static void AI_VC_record_task(void *thread_input)//录音线程 { if(aos_recv_from_queue(AI_VC_record_tmp_queue,&AI_VC_play_record_data,AOS_NO_WAIT) == AOS_SUCCESS)//有录音数据 { - aic_free(AI_VC_play_record_data.data); + if(AI_VC_play_record_data.data) + aic_free(AI_VC_play_record_data.data); }else break; } @@ -1402,7 +1485,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(play_data_len>8*1024 &&VC_Play_flag ==1 && AI_VC_play_queue ) + if((play_data_len>8*1024 || outbound_attributes_format == attributes_format_OPUS)&&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) @@ -1419,8 +1502,8 @@ static void AI_VC_play_task(void *thread_input)//音频播放线程 } - - aic_free(AI_VC_play_queue_data.data); + if(AI_VC_play_queue_data.data) + aic_free(AI_VC_play_queue_data.data); if(VC_state == VC_State_End) { u32 count_tmp = 0; @@ -1489,7 +1572,11 @@ static int websocket_connect_VC(void) dev_authentication_MSG_put(NULL,0,AUT_LOGIN); return - 1; } - url_len =snprintf(url,511,"ws://%s/vc/chat?is_auth=1&dt=%s",vc_cfg.server_ip,get_token()); + if(vc_cfg.dev_type == DEV_JSWM) + url_len =snprintf(url,511,"ws://%s/vc/agent?is_auth=1&dt=%s",vc_cfg.server_ip,get_token()); + else + url_len =snprintf(url,511,"ws://%s/vc/chat?is_auth=1&dt=%s",vc_cfg.server_ip,get_token()); + url[url_len] = 0; bk_printf("连接服务器 url:%s",url); AI_client_VC = init_websocket_client(url,NULL); @@ -1635,8 +1722,7 @@ int play_audio_file(char *file_name) { bk_printf("play_audio_file:%s",file_name); AI_AMP_MSG_put(file_name,strlen(file_name)+1,PLAY_AUDIO_FILE); - - + return 0; } volatile char app_audio_play_file_stop_flag = 0; @@ -1741,9 +1827,11 @@ static int play_file_stream_data_event(char *file_name) return -1; return 0; } -static void AI_VC_put_play_data(char *data,u32 len) +void AI_VC_put_play_data(char *data,u32 len) { u32 count_tmp = 0; + if(len <= 0) + return ; while(1) { if(AI_VC_play_queue == NULL) @@ -1790,7 +1878,8 @@ static void AI_VC_put_play_data(char *data,u32 len) return ; PUT_PLAY_ERROR: - aic_free(AI_VC_play_queue_data.data); + if(AI_VC_play_queue_data.data) + aic_free(AI_VC_play_queue_data.data); } //打开音频播放 @@ -1852,7 +1941,8 @@ void VC_Play_End(void) static void AI_VC_put_record_data(char *data,u32 len) { - + if(len <= 0) + return ; AI_VC_audio_queue_t AI_VC_record_queue_data; AI_VC_record_queue_data.data = aic_malloc(len); @@ -1879,7 +1969,8 @@ static void AI_VC_put_record_data(char *data,u32 len) return; PUT_RECORD_ERROR: - aic_free(AI_VC_record_queue_data.data); + if(AI_VC_record_queue_data.data) + aic_free(AI_VC_record_queue_data.data); } @@ -1964,7 +2055,7 @@ static void AI_VC_1S_timeout(void *param) VC_END_play_timerout --; if(VC_END_play_timerout<=0) { - if(VC_mode == 0) + if(vc_cfg.VC_mode == 0 || vc_cfg.VC_mode == 2) { if(VC_TTS_PLAY_EVENT == VC_TTS_PLAY_CLOSE) { @@ -1997,13 +2088,19 @@ static void AI_VC_1S_timeout(void *param) // bk_msg_printf("AI_VC_send_queue:play_queue_count=%d",play_queue_count); // } } +char AI_key_long_flag = 0; void AI_key_press(void) { static u64 timer_ms = 0; u64 timer_ms_tmp = aos_get_tickcount(); - if(timer_ms_tmp-timer_ms<1000)//每次触发小于1000ms不响应 + if(timer_ms_tmp-timer_ms<1000)//每次触发小于1000ms关闭对话 + { + if(vc_cfg.VC_mode ==0 || vc_cfg.VC_mode == 2)//关闭服务 + AI_VC_Close(); return; + } + timer_ms = timer_ms_tmp; bk_printf("AI_key_press"); AI_VC_Close(); @@ -2023,19 +2120,28 @@ void AI_key_press(void) } void AI_key_release(void) { - + + if(vc_cfg.VC_mode ==1) + { + AI_AMP_MSG_put("请您按住按钮讲话,讲完松开即可。",strlen("请您按住按钮讲话,讲完松开即可。"),VC_TTS_PLAY); + } bk_printf("AI_key_release"); } void AI_key_long_press(void) { + AI_key_long_flag = 1; bk_printf("AI_key_long_press"); } void AI_key_long_release(void) { + AI_key_long_flag = 0; bk_printf("AI_key_long_release"); - if(VC_mode == 1)//长按模式 - AI_VC_send_audio_completed(); + +} +int get_AI_key_longstate(void) +{ + return AI_key_long_flag; } void pwk_key_release(void) { @@ -2097,7 +2203,7 @@ int AI_VC_start(void) app_audio_param_t param; param.channel = 1; param.format = ASTREAM_FORMAT_PCM; - param.sample_rate = 16000; + param.sample_rate = vc_cfg.VC_play_samplerate; param.flag = 0; param.bit_rate = 0; play_data_len = 0; @@ -2136,65 +2242,14 @@ int AI_VC_start(void) AOS_AUTO_ACTIVATE, AOS_BE_PERIOD); aic_assert(AI_VC_1S_timer); } - if(inbound_attributes_format == inbound_attributes_format_OPUS) + if(inbound_attributes_format == attributes_format_OPUS ||outbound_attributes_format == attributes_format_OPUS) { - #if SUPPORT_OPUS - bk_printf("opus_init start"); - //int err; - if (opus_encoder_h == NULL) - { - opus_encoder_h = (opus_enc_init_param_t *)aic_zalloc(sizeof(opus_enc_init_param_t)); - if(!opus_encoder_h) - { - bk_printf("opus_encoder_h alloc error"); - ret = -1; - goto AI_VC_start_RET; - } - opus_encoder_h->channel_cnt = 1; - opus_encoder_h->sample_rate = 16000; - opus_encoder_h->period_ms = OPUS_PERIOD_MS; - opus_encoder_h->bitrate = 16000; - status = aic_opus_init_encoder(opus_encoder_h); - if (status) - { - bk_printf("aic_opus_init_encoder error"); - ret = -1; - goto AI_VC_start_RET; - } - //opus_encoder_h = opus_encoder_create(16000, 1, OPUS_APPLICATION_VOIP, &err); - - } - - if (opus_decoder_h == NULL) - { - - opus_decoder_h = (opus_dec_init_param_t *)aic_zalloc(sizeof(opus_dec_init_param_t)); - if(!opus_decoder_h) - { - bk_printf("opus_decoder_h alloc error"); - ret = -1; - goto AI_VC_start_RET; - } - opus_decoder_h->channel_cnt = 1; - opus_decoder_h->sample_rate = 16000; - status = aic_opus_init_decoder(opus_decoder_h); - if (status) - { - bk_printf("aic_opus_init_decoder error"); - ret = -1; - goto AI_VC_start_RET;; - } - - //opus_decoder_h = opus_decoder_create(16000, 1, &err); - } - if(OPUS_rb_data == NULL) - OPUS_rb_data = bk_rb_create(OPUS_RB_LEN); - if(!OPUS_rb_data ) + if(opus_init()!= 0) { - bk_printf("OPUS_rb_data error!申请失败"); + bk_printf("opus_init error!!!!!!!!!!!!!!!!!!!!!!!!"); + ret = -1; + goto AI_VC_start_RET; } - bk_printf("opus_init end"); - #endif } @@ -2212,7 +2267,10 @@ int AI_VC_start(void) conf.rule2_min_tailing_silence = vc_cfg.vad_silence ; conf.rule3_min_tailing_silence = vc_cfg.vad_silence; conf.vad_log_level = 2; - init_vad(&conf); + int init_vad_ret = init_vad(&conf); + bk_printf("VAD init_vad:ret = %d",init_vad_ret); + bk_printf("VAD init_vad:ret = %d",init_vad_ret); + bk_printf("VAD init_vad:ret = %d",init_vad_ret); VAD_status = 0; //创建VAD回溯缓冲buf if(VAD_rb_data == NULL) @@ -2255,7 +2313,8 @@ AI_VC_start_RET: { AI_VC_Close(); play_audio_file("C:/xinhaoruo1.mp3"); - } + }else + AI_VC_stata = 1; return ret; } char AI_VC_Close_lock = 0; @@ -2271,23 +2330,7 @@ void AI_VC_Close(void) // 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时调用 - free_vad(); - - VAD_status = 0; - //删除VAD回溯缓冲buf - if(VAD_rb_data != NULL) - { - bk_rb_destroy(&VAD_rb_data); - VAD_rb_data= NULL; - } - } - if(vc_cfg.is_KWS == 1) - { - free_kws(); - } + bk_printf("AI_VC_Close!!!!!!!!!!!!"); //销毁录音线程 @@ -2409,35 +2452,28 @@ void AI_VC_Close(void) AI_VC_1S_timer = NULL; } close_timerout = 0; - if(inbound_attributes_format == inbound_attributes_format_OPUS) - { - #if SUPPORT_OPUS - // if(opus_encoder_h) - // opus_encoder_destroy(opus_encoder_h); - // opus_encoder_h = NULL; - // if(opus_decoder_h) - // opus_decoder_destroy(opus_decoder_h); - // opus_decoder_h = NULL; - if(aic_opus_deinit_encoder() == 0) - { - if(opus_encoder_h) - aic_free(opus_encoder_h); - opus_encoder_h = NULL; - } - if(aic_opus_deinit_decoder() == 0) - { - if(opus_decoder_h) - aic_free(opus_decoder_h); - opus_decoder_h = NULL; - } - if(OPUS_rb_data != NULL) + if(inbound_attributes_format == attributes_format_OPUS||outbound_attributes_format == attributes_format_OPUS) + { + opus_close(); + } + bk_printf("app_audio_stop1"); + if(vc_cfg.is_VAD == 1) + { + // 不使用或暂停使用VAD时调用 + free_vad(); + + VAD_status = 0; + //删除VAD回溯缓冲buf + if(VAD_rb_data != NULL) { - bk_rb_destroy(&OPUS_rb_data); - OPUS_rb_data= NULL; + bk_rb_destroy(&VAD_rb_data); + VAD_rb_data= NULL; } - #endif } - bk_printf("app_audio_stop1"); + if(vc_cfg.is_KWS == 1) + { + free_kws(); + } //app_logi("app_audio_stop1"); if(app_audio_flag == 1) { @@ -2465,7 +2501,7 @@ void AI_VC_Close(void) AI_ASR_str =NULL; } //app_logi("app_audio_stop2"); - + AI_VC_stata = 0; AI_VC_Close_lock = 0; } @@ -2522,6 +2558,28 @@ static void sys_10S_timeout(void *param) } } + struct psy_info psy_info; + get_psy_info(&psy_info); + if(psy_info.bat_capacity> 15 &&psy_info.bat_capacity<=25 && AI_VC_stata == 0) + { + play_audio_file("C:/Low_power_warning.mp3"); + }else if(psy_info.bat_capacity<=15) + { + // AI_AMP_MSG_put(NULL,0,VC_CLOSE);//关闭对话 + // play_audio_file("C:/didianguanji.mp3");//播放低电关机 + AI_AMP_MSG_put("C:/didianguanji.mp3",strlen("C:/didianguanji.mp3"),POWER_OFF); + + } + // bk_printf("电量查询:psy_name:%s bat_vol:%d bat_cap:%d chg_status%d chg_type:%d bat_min_voltage:%d bat_max_voltage:%d\n", + + // psy_info.psy_name, + // psy_info.bat_current_voltage, + // psy_info.bat_capacity, + // psy_info.bat_chg_status, + // psy_info.bat_chg_type, + // psy_info.bat_min_voltage, + // psy_info.bat_max_voltage); + //tmp_data_len = snprintf(tmp_data,sizeof(tmp_data),"当前电量为百分之%d。",psy_info.bat_capacity); } static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 @@ -2535,39 +2593,6 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 app_audio_set_master_volume(15*vc_cfg.VC_TTS_volume/100); play_audio_file_event("C:/R_POWER_1.mp3"); - // volatile int32_t a = 1626; - // volatile int32_t b = 1536; - // volatile int32_t res = 0; - // int ai = 0; - // u32 time1 = aos_get_tickcount(); - // for (ai = 0; ai < 245000; ai++) { - // res += (a + ai) * (b + ai); - // } - // u32 time2 = aos_get_tickcount(); - // bk_printf("run int32 takes : %d\n", time2 - time1); - - // volatile int64_t a1 = 1626; - // volatile int64_t b1 = 1536; - // volatile int64_t res1 = 0; - // // int ai = 0; - // time1 = aos_get_tickcount(); - // for (ai = 0; ai < 245000; ai++) { - // res1 += (a1 + ai) * (b1 + ai); - // } - // time2 = aos_get_tickcount(); - // bk_printf("run int64 takes : %d\n", time2 - time1); - - // volatile float a2 = 1626.0f; - // volatile float b2 = 1536.0f; - // volatile float res2 = 0; - // // int ai = 0; - // time1 = aos_get_tickcount(); - // for (ai = 0; ai < 245000; ai++) { - // res2 += (a2 + ai) * (b2 + ai); - // } - // time2 = aos_get_tickcount(); - // bk_printf("run float takes : %d\n", time2 - time1); - while(count --) { @@ -2579,6 +2604,10 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 //audio_play_tone(3,500);//播放提示音,测试用 aos_sleep(1000); } + bk_websocket_demo(); + aic_get_uid(uid,&uid_len); + bk_printf("UID:%s",uid); + bk_printf("UID:%s",uid); current_card_id = aic_srv_tele_sim_get_current_card_sync(); aic_srv_tele_radio_get_current_slot_imei_sync(vc_cfg.dev_imei); @@ -2612,6 +2641,11 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 case POWER_OFF://关机 AI_VC_Close(); //播放关机提示音 + if(AI_AMP_msg.data)//有数据,播放本地文件 + { + play_audio_file_event(AI_AMP_msg.data); + aos_sleep(5); + } sysoff_shutdown(); break; case POWER_RESET://重启 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 dcbd798..9b115a2 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 @@ -1,8 +1,17 @@ #include "aic_osa.h" + +#define SUPPORT_OPUS 1 +#define BK_LOG_NONE 0//不打印 +#define BK_LOG_UART 1//串口打印 +#define BK_LOG_USB 2//USB打印 + + +#define BK_LOG_CFG BK_LOG_UART typedef enum { DEV_FX1_H,//玩具机芯 DEV_ADS,//奥德赛 + DEV_JSWM, } DEV_TYPE; typedef enum { @@ -118,4 +127,5 @@ int bk_msg_printf(const char *format, ...); aos_status AI_AMP_MSG_put(const char *data,u32 len,AI_AMP_MSG_Type MSG_Type); int bk_get_imei(char *imei); int save_VC_cfg(void); -int play_audio_file(char *file_name); \ No newline at end of file +int play_audio_file(char *file_name); +void AI_VC_put_play_data(char *data,u32 len);//音频数据入队播放 \ No newline at end of file diff --git a/2.code/aicos/app/AI_AMP_2_5/CMakeLists.txt b/2.code/aicos/app/AI_AMP_2_5/CMakeLists.txt index c5e7682..0ed5dfa 100644 --- a/2.code/aicos/app/AI_AMP_2_5/CMakeLists.txt +++ b/2.code/aicos/app/AI_AMP_2_5/CMakeLists.txt @@ -10,6 +10,7 @@ aic_library_sources_ifdef( ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/bk_websocket.c ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/bk_key.c ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/dev_authentication.c + ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/bk_opus_coder.c ) @@ -18,76 +19,27 @@ aic_library_include_directories_ifdef( CONFIG_APP_AI_AMP_2_5 ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/guixin/ ) -# # 官方opus库 -# file(GLOB SOURCES ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/src/src/*.c) -# aic_library_sources_ifdef( -# CONFIG_APP_AI_AMP_2_5 -# ${SOURCES}) -# file(GLOB SOURCES ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/src/celt/*.c) -# aic_library_sources_ifdef( -# CONFIG_APP_AI_AMP_2_5 -# ${SOURCES}) -# # file(GLOB SOURCES ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/src/celt/arm/*.c) -# # aic_library_sources_ifdef( ${SOURCES}) - -# file(GLOB SOURCES ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/src/silk/*.c) -# aic_library_sources_ifdef( -# CONFIG_APP_AI_AMP_2_5 -# ${SOURCES}) -# # file(GLOB SOURCES ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/src/silk/arm/*.c) -# # aic_library_sources_ifdef( -# # CONFIG_APP_AI_AMP_2_5 -# # ${SOURCES}) -# # ##有问题 -# # file(GLOB SOURCES ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/src/silk/scky/*.c) -# # aic_library_sources_ifdef( -# # CONFIG_APP_AI_AMP_2_5 -# # ${SOURCES}) - -# file(GLOB SOURCES ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/src/silk/fixed/*.c) -# aic_library_sources_ifdef( -# CONFIG_APP_AI_AMP_2_5 -# ${SOURCES}) -# #如果定义 FIXED_POINT,不能编译 -# # file(GLOB SOURCES ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/src/silk/float/*.c) -# # aic_library_sources_ifdef( -# # CONFIG_APP_AI_AMP_2_5 -# # ${SOURCES}) - -# #有问题 -# # file(GLOB SOURCES ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/src/silk/mips/*.c) -# # aic_library_sources_ifdef( -# # CONFIG_APP_AI_AMP_2_5 -# # ${SOURCES}) - -# # file(GLOB SOURCES ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/src/silk/tests/*.c) -# # aic_library_sources_ifdef( -# # CONFIG_APP_AI_AMP_2_5 -# # ${SOURCES}) -# aic_library_include_directories_ifdef( -# CONFIG_APP_AI_AMP_2_5 -# ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/src/ -# ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/include/ -# ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/src/celt/ -# ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/src/silk/ -# ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/src/silk/float/ -# ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/src/silk/fixed/ -# ) aic_library_include_directories_ifdef( CONFIG_APP_AI_AMP_2_5 ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/ ) +aic_library_import(APP_AI_AMP_2_5_OPUS + ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/guixin/libopus.a +) +aic_library_import(APP_AI_AMP_2_5_OGG + ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/guixin/libogg.a +) +# aic_library_import(APP_AI_AMP_2_5_OGG_DSP +# ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/guixin/libogg_dsp.a +# ) + # aic_library_import(APP_AI_AMP_2_5_VAD ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/libimslvad.a - #${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/guixin/libopus.a -) -aic_library_import(APP_AI_AMP_2_5_OPUS - #${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/libimslvad.a - ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/opus/guixin/libopus.a ) + aic_library_import(APP_AI_AMP_2_5_KWS ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/libimslkws.a ) diff --git a/2.code/aicos/app/AI_AMP_2_5/bk_dev.c b/2.code/aicos/app/AI_AMP_2_5/bk_dev.c new file mode 100644 index 0000000..be08020 --- /dev/null +++ b/2.code/aicos/app/AI_AMP_2_5/bk_dev.c @@ -0,0 +1,105 @@ + +#include "bk_dev.h" +#include +#include +#include +#include +#include "app_msg.h" +#include "aic_net_pdp_mgr.h" +#include "aic_network_pcap.h" +#include "aic_osa.h" +#include +static aos_thread_id bk_dev_task_id = 0; +static aos_queue_ptr bk_dev_task_queue = NULL; + +//鉴权消息发送 +aos_status bk_dev_MSG_put(const char *data,u32 len,bk_dev_MSG_Type MSG_Type) +{ + bk_dev_MSG_queue_t bk_dev_MSG_queue_data = {0}; + //bk_msg_printf("bk_dev_MSG_put1 MSG_Type:%d",MSG_Type); + if(len >0) + { + bk_dev_MSG_queue_data.data = aic_malloc(len+1); + memset(bk_dev_MSG_queue_data.data ,0,len+1); + if(!bk_dev_MSG_queue_data.data) + { + //bk_msg_printf("AI_VC_send_data aic_malloc ERROR!!!!!!!!!!"); + return AOS_ERROR; + } + memcpy(bk_dev_MSG_queue_data.data,data,len); + bk_dev_MSG_queue_data.len=len; + } + + bk_dev_MSG_queue_data.MSG_Type=MSG_Type; + if(bk_dev_task_queue && AOS_SUCCESS!=aos_send_to_queue(bk_dev_task_queue,&bk_dev_MSG_queue_data,AOS_NO_WAIT)) + { + if(!bk_dev_MSG_queue_data.data) + aic_free(bk_dev_MSG_queue_data.data); + return AOS_ERROR; + } + //bk_msg_printf("bk_dev_MSG_put2 MSG_Type:%d",MSG_Type); + return AOS_SUCCESS; +} + +static void bk_dev_task(void *thread_input)//设备驱动控制线程 +{ + bk_dev_MSG_queue_t bk_dev_msg = {0}; + // ase_encrypt_demo(); + // //dev_NTP();//获取时间 + // aut_active();//激活 + // aut_login();//登录 + if(LOGIN_1H_timeout == NULL) + { + LOGIN_1H_timer = aos_create_timer("AI_VC_1S_timer", + LOGIN_1H_timeout, &LOGIN_1H_timer, + 1000*60, + AOS_AUTO_ACTIVATE, AOS_BE_PERIOD); + aic_assert(LOGIN_1H_timer); + } + + /** + * 原来已激活过了...AuthVo(password=rPbSCNTIVYWKso6I5+6l0KIbSiIembg3p10IEny2UVg=, deviceId=860132061481751, nonce=xiRqXDqkqGFodIiw) + */ + while (1) { + if(bk_dev_task_queue) + { + aos_recv_from_queue(bk_dev_task_queue,&bk_dev_msg,AOS_WAIT_FOREVER) ; + switch (bk_dev_msg.MSG_Type) + { + case BK_OPEN_LED_RED://亮红灯 + + break; + case BK_OPEN_LED_GREEN://亮绿灯 + + break; + case BK_BK_OPEN_LED_BLUE://亮蓝灯 + + break; + } + if(bk_dev_msg.data) + aic_free(bk_dev_msg.data); + }else + { + aos_sleep(10); + } + } +} +void bk_dev_init(void) +{ + //创建设备激活队列 + if(bk_dev_task_queue == NULL) + { + bk_dev_task_queue = aos_create_queue("bk_dev_task_queue", + sizeof(bk_dev_MSG_queue_t), + 200); + } + bk_dev_task_id = aos_create_thread( + "bk_dev_task", + bk_dev_task, + &bk_dev_task_id, + 4096u, + 0, + NULL, + 35, + AOS_AUTO_START); +} \ No newline at end of file diff --git a/2.code/aicos/app/AI_AMP_2_5/bk_dev.h b/2.code/aicos/app/AI_AMP_2_5/bk_dev.h new file mode 100644 index 0000000..eefcf74 --- /dev/null +++ b/2.code/aicos/app/AI_AMP_2_5/bk_dev.h @@ -0,0 +1,31 @@ +#ifndef __BK_DEV_H__ +#define __BK_DEV_H__ +#include +// 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 );//马达 +#define OPEN_LED GPIO_OUTPUT_LVL_HIGH +#define CLOSE_LED GPIO_OUTPUT_LVL_LOW + +#define RED_LED GPIO_25 +#define GREEN_LED GPIO_30 +#define BLUE_LED GPIO_31 + +typedef enum bk_dev_MSG +{ + BK_OPEN_LED_RED,//亮红灯 + BK_OPEN_LED_GREEN,//亮绿灯 + BK_BK_OPEN_LED_BLUE,//亮蓝灯 + BK_CLOSE_LED //关闭所有灯 +} bk_dev_MSG_Type; +typedef struct +{ + char *data; + u32 len; + bk_dev_MSG_Type MSG_Type; +}bk_dev_MSG_queue_t; +void bk_dev_init(void); +#endif diff --git a/2.code/aicos/app/AI_AMP_2_5/bk_key.c b/2.code/aicos/app/AI_AMP_2_5/bk_key.c index 08c566a..7e426c7 100644 --- a/2.code/aicos/app/AI_AMP_2_5/bk_key.c +++ b/2.code/aicos/app/AI_AMP_2_5/bk_key.c @@ -27,7 +27,7 @@ static int32_t bk_kpc_callback(void *p_param, uint32_t size) return -1; } - for (int i = 0; i < 5; i++) { + for (int i = 0; i < KPC_KEY_PRESSED_MAX_KEY_NUM; i++) { bk_printf("bk_kpc_callback key[%d].key_value=%d",i,key_arr->key[i].key_value); switch (key_arr->key[i].key_event) { case KPC_KEY_EVENT_PRESS://按下 diff --git a/2.code/aicos/app/AI_AMP_2_5/bk_opus_coder.c b/2.code/aicos/app/AI_AMP_2_5/bk_opus_coder.c new file mode 100644 index 0000000..f245945 --- /dev/null +++ b/2.code/aicos/app/AI_AMP_2_5/bk_opus_coder.c @@ -0,0 +1,360 @@ +//opus编解码应用 +#include +#include +#include +#include +#include "app_msg.h" +#include "aic_net_pdp_mgr.h" +#include "aic_network_pcap.h" +#include "aic_websocket_client.h" +#include "cJSON.h" +#include +#include "aic_osa.h" +#include "app_audio.h" +#include "bk_ringbuf.h" +#include "bk_websocket.h" +#include "AI_AMP_2_5.h" +#include "bk_key.h" +#include "aic_srv_tele_sim.h" +#include +#if SUPPORT_OPUS +#include "opus/guixin/opus_interface.h" +#endif +#include "dev_authentication.h" +#include "imsl_vad.h" +#include "imsl_kws.h" +#include "aic_srv_tele_ex.h" +#include "power_supply.h" +#include "sysoff.h" +#include "app_msg.h" +#include "aic_ogg.h" +#define OPUS_PERIOD_MS OPUS_PERIOD_60_MS +#define OPUS_ENCODER_RB_LEN 64*32*8//要2的次方 +bk_ring_buf_t *OPUS_encoder_rb_data = NULL; +#define OPUS_DECODER_RB_LEN 16*1024//要2的次方 +bk_ring_buf_t *OPUS_decoder_rb_data = NULL; +static struct opus_enc_init_param *opus_encoder_h = NULL; +static struct opus_dec_init_param *opus_decoder_h = NULL; +int opus_init(void) +{ + #if SUPPORT_OPUS + int status = 0; + int ret = -1; + bk_printf("opus_init start"); + //int err; + if (opus_encoder_h == NULL) + { + opus_encoder_h = (opus_enc_init_param_t *)aic_zalloc(sizeof(opus_enc_init_param_t)); + if(!opus_encoder_h) + { + bk_printf("opus_encoder_h alloc error"); + ret = -1; + goto opus_init_RET; + } + opus_encoder_h->channel_cnt = 1; + opus_encoder_h->sample_rate = 16000; + opus_encoder_h->period_ms = OPUS_PERIOD_MS; + opus_encoder_h->bitrate = 16000; + status = aic_opus_init_encoder(opus_encoder_h); + if (status) + { + bk_printf("aic_opus_init_encoder error"); + ret = -1; + goto opus_init_RET; + } + //opus_encoder_h = opus_encoder_create(16000, 1, OPUS_APPLICATION_VOIP, &err); + } + + if (opus_decoder_h == NULL) + { + + opus_decoder_h = (opus_dec_init_param_t *)aic_zalloc(sizeof(opus_dec_init_param_t)); + if(!opus_decoder_h) + { + bk_printf("opus_decoder_h alloc error"); + ret = -1; + goto opus_init_RET; + } + opus_decoder_h->channel_cnt = 1; + opus_decoder_h->sample_rate = 16000; + status = aic_opus_init_decoder(opus_decoder_h); + if (status) + { + bk_printf("aic_opus_init_decoder error"); + ret = -1; + goto opus_init_RET; + } + + //opus_decoder_h = opus_decoder_create(16000, 1, &err); + } + if(OPUS_encoder_rb_data == NULL) + OPUS_encoder_rb_data = bk_rb_create(OPUS_ENCODER_RB_LEN); + if(!OPUS_encoder_rb_data ) + { + bk_printf("OPUS_encoder_rb_data error!申请失败"); + ret = -1; + goto opus_init_RET; + } + if(OPUS_decoder_rb_data == NULL) + OPUS_decoder_rb_data = bk_rb_create(OPUS_DECODER_RB_LEN); + if(!OPUS_decoder_rb_data ) + { + bk_printf("OPUS_decoder_rb_data error!申请失败"); + ret = -1; + goto opus_init_RET; + } + + bk_printf("opus_init end"); + return 0; + opus_init_RET: + if(opus_decoder_h ) + aic_free(opus_decoder_h); + if(opus_encoder_h) + aic_free(opus_encoder_h); + return ret; + #endif +} +void opus_close(void) +{ + #if SUPPORT_OPUS + if(aic_opus_deinit_encoder() == 0) + { + + } + if(opus_encoder_h) + aic_free(opus_encoder_h); + opus_encoder_h = NULL; + if(aic_opus_deinit_decoder() == 0) + { + + } + if(opus_decoder_h) + aic_free(opus_decoder_h); + opus_decoder_h = NULL; + if(OPUS_encoder_rb_data != NULL) + { + bk_rb_destroy(&OPUS_encoder_rb_data); + OPUS_encoder_rb_data= NULL; + } + if(OPUS_decoder_rb_data != NULL) + { + bk_rb_destroy(&OPUS_decoder_rb_data); + OPUS_decoder_rb_data= NULL; + } + + #endif +} +void opus_clean(void) +{ + + if(OPUS_encoder_rb_data) + { + bk_rb_clear(OPUS_encoder_rb_data); + } +} +int opus_encode_data(char *PCM_data,int data_len,int one_pack_len,char *opus_data,int opus_data_max_len) +{ + int ret = 0; + #if SUPPORT_OPUS + + //struct opus_dec_param dec_inparam; + + struct opus_enc_param enc_inparam; + //OPUS_encoder_rb_data + if(OPUS_encoder_rb_data) + { + if(OPUS_ENCODER_RB_LEN - bk_rb_data_len(OPUS_encoder_rb_data) >= data_len)//缓存够 + { + bk_rb_write(OPUS_encoder_rb_data,PCM_data,data_len); + }else//缓存太大,需要出队处理 + { + return -1; + // unsigned char *OPUS_tmp = aic_malloc(data_len); + // if(OPUS_tmp) + // { + // bk_rb_read(OPUS_encoder_rb_data,OPUS_tmp,data_len); + // aic_free(OPUS_tmp); + // } + // bk_printf("send_opus_data:缓存太大,先出队"); + // bk_rb_write(OPUS_encoder_rb_data,PCM_data,data_len); + } + while(1) + { + if(bk_rb_data_len(OPUS_encoder_rb_data) < one_pack_len)//数据不够,退出 + { + break; + }else + { + unsigned char *pcm_data = aic_malloc(one_pack_len); + //unsigned char *opus_data = aic_malloc(one_pack_len); + if(!pcm_data) + { + bk_printf("opus_encode_data:alloc error!"); + + if(pcm_data) + aic_free(pcm_data); + return -1; + } + // int time_tmp = aos_get_tickcount(); + // bk_printf("opus_encode_data:time = %d",time_tmp); + int pcm_len=bk_rb_read(OPUS_encoder_rb_data,pcm_data,one_pack_len);//解码数据 + enc_inparam.input = (int16_t*)(pcm_data);//PCM数据 + enc_inparam.input_size = pcm_len; + enc_inparam.output = (int8_t*)opus_data; + enc_inparam.outbuffer_size = opus_data_max_len; + ret = aic_opus_encode(&enc_inparam); + + //enc_inparam.output_len_array[0];//长度 + //AI_VC_send_data(opus_data,enc_inparam.output_len_array[0],AIC_WEBSOCKET_OPCODE_BINARY_FRAME);//够一帧,发送数据 + // ret = send_websocket_message(AI_client_VC,opus_data,enc_inparam.output_len_array[0], + // AIC_WEBSOCKET_OPCODE_BINARY_FRAME); + + //bk_printf("opus_encode_data:data_len = %d 用时:%d MS",enc_inparam.output_len_array[0],aos_get_tickcount()-time_tmp); + aic_free(pcm_data); + + if(ret < 0) + return -1; + ret = enc_inparam.output_len_array[0]; + } + } + } + + + #endif + return ret; +} + +int ogg_opus_decode_data(char *in_ogg_data,int in_ogg_data_len) +{ + int data_count = 0; + int page_type; + int channel_cnt, sample_rate; + unsigned char* p_audio; + int frame_length; + struct opus_dec_param dec_inparam; + int ret = 0; + static char ogg_hend[27+256] ={0}; + static int ogg_hend_len = 0; + int seg_num =0; + //fread(page_buffer, 1, 27 + seg_num, fin); + if(!in_ogg_data) + return -2; + //fseek(fin, -1 * (27 + seg_num), SEEK_CUR); + //fread(page_buffer, 1, 27 + seg_num + seg_size, fin); + int seg_size; + #if SUPPORT_OPUS + if(OPUS_decoder_rb_data) + { + if(OPUS_DECODER_RB_LEN - bk_rb_data_len(OPUS_decoder_rb_data) >= in_ogg_data_len)//缓存够 + { + bk_rb_write(OPUS_decoder_rb_data,in_ogg_data,in_ogg_data_len); + } + }else + { + bk_printf("OPUS_decoder_rb_data error!!!!!"); + return -1; + } + data_count = 0; + u64 timer_ms = aos_get_tickcount(); + + while(1) + { + + if(bk_rb_data_len(OPUS_decoder_rb_data) < 27)//不够一页数据 + { + break; + }else + { + /**********1阶段判断头********** */ + if(ogg_hend_len==0)//没有剩余的头数据 + { + bk_rb_read(OPUS_decoder_rb_data,ogg_hend,27); + ogg_hend_len+=27;//读页头 + + } + /**********2阶段判段数********** */ + seg_num = ogg_get_segment_num(ogg_hend, 27);//读有多少段 + //bk_printf("ogg段数:%d",seg_num); + if(ogg_hend_len < 27+seg_num)//没有段数据 + { + if(bk_rb_data_len(OPUS_decoder_rb_data)< seg_num)//判断可读数据够不够 + { + bk_printf("算页大小数据不够,退出当前解包:seg_num %d",seg_num); + break; + } + + ogg_hend_len+=bk_rb_read(OPUS_decoder_rb_data,ogg_hend+27,seg_num);//读页的段数据 + } + seg_size = ogg_calc_total_segment_data_size(ogg_hend, ogg_hend_len);//算这一页有多少数据 + //bk_printf("整页数据大小:%d",seg_size); + /************3阶段读完整包****************** */ + if(bk_rb_data_len(OPUS_decoder_rb_data)< seg_size)//判断可读数据够不够 + { + bk_printf("读整页数据大小不够,退出当前解包:seg_size %d,ogg_hend_len:%d",seg_size,ogg_hend_len); + + break; + } + char *ogg_buf = aic_malloc(27+seg_num+seg_size); + if(ogg_buf) + { + memcpy(ogg_buf,ogg_hend,27+seg_num); + bk_rb_read(OPUS_decoder_rb_data,ogg_buf+27+seg_num,seg_size);//读一整页 + ogg_hend_len = 0;//头部已读完,认为读完一整帧 + page_type = ogg_check_opus_page_type(ogg_buf, &channel_cnt, &sample_rate);//获取数据类型,1是头,3是音频帧 + if (1 == page_type) { + bk_printf("ogg头:lchannel cnt = %d, sample rate = %d", channel_cnt, sample_rate); + } + else if (3 == page_type) { + ogg_demux_context demux_context = { 0, 0 }; + while (1) { + p_audio = ogg_get_next_audio_frame(ogg_buf, &demux_context, &frame_length); + if (p_audio == NULL || frame_length == 0) + break; + //bk_printf("ogg解包:len:%d",frame_length); + char *pcm_buf = aic_malloc(4096); + if(pcm_buf) + { + + dec_inparam.input = p_audio; + dec_inparam.inputfrm_count = 1; + dec_inparam.input_len_array[0] = frame_length; + //memcpy(dec_inparam.input_len_array , enc_inparam.output_len_array, sizeof(dec_inparam.input_len_array)); + dec_inparam.output = (int16_t *)pcm_buf; + dec_inparam.outbuffer_size = 4096; + ret = aic_opus_decode(&dec_inparam); + + // bk_printf("opus解码 result:%d,outsize:%d", ret,dec_inparam.outputfrms_size); + if (ret == OPUS_RESULT_ERROR) { + //bk_printf("opus解码 error:%d", ret); + //bk_printf("ogg data:"); + bk_print_hex(ogg_buf,27+seg_num+seg_size); + aic_free(pcm_buf); + break; + } + AI_VC_put_play_data(pcm_buf,dec_inparam.outputfrms_size);//发送数据到音频队列 + //aos_sleep(1); + aic_free(pcm_buf); + } + + } + }else if(2 == page_type)//标签 + { + bk_printf("opus标签 :%s", ogg_buf+27+seg_num); + } + else + { + bk_printf("ogg解析失败 :%d!!!!!!!!!!!!", page_type); + aic_free(ogg_buf); + break; + } + aic_free(ogg_buf); + } + + } + + //aos_sleep(1); + } + bk_printf("ogg-opus解码 数据大小:%d,耗时:%d ms",in_ogg_data_len,aos_get_tickcount()-timer_ms ); + #endif + return 0; +} \ No newline at end of file diff --git a/2.code/aicos/app/AI_AMP_2_5/bk_opus_coder.h b/2.code/aicos/app/AI_AMP_2_5/bk_opus_coder.h new file mode 100644 index 0000000..82eed1c --- /dev/null +++ b/2.code/aicos/app/AI_AMP_2_5/bk_opus_coder.h @@ -0,0 +1,8 @@ +#ifndef __BK_OPUS_CODER_H__ +#define __BK_OPUS_CODER_H__ +int opus_init(void); +void opus_close(void); +void opus_clean(void); +int opus_encode_data(char *PCM_data,int data_len,int one_pack_len,char *opus_data,int opus_data_max_len); +int ogg_opus_decode_data(char *in_ogg_data,int in_ogg_data_len); +#endif diff --git a/2.code/aicos/app/AI_AMP_2_5/bk_websocket.c b/2.code/aicos/app/AI_AMP_2_5/bk_websocket.c index 8b322cc..d78265d 100644 --- a/2.code/aicos/app/AI_AMP_2_5/bk_websocket.c +++ b/2.code/aicos/app/AI_AMP_2_5/bk_websocket.c @@ -72,6 +72,7 @@ typedef struct { char *protocol; char *host; int port; + char port_str[7]; char *path; char *query; int error; @@ -150,6 +151,7 @@ BK_URL parse_url(const char *url) { aic_free(temp_url_t); return result; } + result.port = atoi(colon_port + 1); if (!result.port) { set_url_error(&result, "Invalid port number"); @@ -169,6 +171,8 @@ BK_URL parse_url(const char *url) { result.port = 443; } } + memset(result.port_str,0,sizeof(result.port_str)); + snprintf(result.port_str,sizeof(result.port_str),"%d",result.port ); temp_url = slash+1; //bk_printf("parse_url slash=%s\n",temp_url); // 解析路径和查询字符串 @@ -367,6 +371,8 @@ int send_handshake(WebSocketClient *client,const char *headers) { // 发送 WebSocket 消息 int send_websocket_message(WebSocketClient *client, const unsigned char *message, size_t message_len, WebSocketMessageType type) { + if(!client) + return -1; unsigned char *frame=aic_zalloc(message_len + 50); int offset = 0; int ret = -1; @@ -430,6 +436,8 @@ send_websocket_message_ERROR: int receive_websocket_message(WebSocketClient *client, unsigned char *buf,int len,WebSocketMessageType *code) { //u64 timer_ms = aos_get_tickcount(); //bk_printf("receive_websocket_message 1 timer_ms=%d\n",timer_ms); + if(!client ) + return -1; unsigned char frame[20]={0}; unsigned char masking_key[4]; int bytes_received = 0; @@ -679,24 +687,54 @@ WebSocketClient *init_websocket_client(const char *url, const char *headers) { bk_printf("init_websocket_client alloc error"); goto client_ERROR; } - - client->sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (client->sockfd < 0) { - bk_printf("socket creation failed"); + struct addrinfo hints, *addr_list, *cur; + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + if( getaddrinfo( parsed_url.host, parsed_url.port_str, &hints, &addr_list ) != 0 ) + //if( getaddrinfo( "www.baidu.com", "80", &hints, &addr_list ) != 0 ) + { + bk_printf("init_websocket_client getaddrinfo error"); goto client_ERROR; } - // bk_printf("init_websocket_client 3\n"); - struct sockaddr_in server_addr; - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(parsed_url.port); - inet_pton(AF_INET, parsed_url.host, &server_addr.sin_addr); + for( cur = addr_list; cur != NULL; cur = cur->ai_next ) + { + client->sockfd = (int) socket( cur->ai_family, cur->ai_socktype, + cur->ai_protocol ); + if( client->sockfd < 0 ) + { + continue; + } + + if( connect( client->sockfd , cur->ai_addr, (int)cur->ai_addrlen ) == 0 ) + { + + break; + } - if (connect(client->sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { - bk_printf("connection failed"); - close(client->sockfd); + close( client->sockfd ); goto client_ERROR; + bk_printf("init_websocket_client connect error"); } + bk_printf("init_websocket_client connect ok,sockfd:%d",client->sockfd); +// client->sockfd = socket(AF_INET, SOCK_STREAM, 0); +// if (client->sockfd < 0) { +// bk_printf("socket creation failed"); +// goto client_ERROR; +// } + +// // bk_printf("init_websocket_client 3\n"); +// struct sockaddr_in server_addr; +// server_addr.sin_family = AF_INET; +// server_addr.sin_port = htons(parsed_url.port); +// inet_pton(AF_INET, parsed_url.host, &server_addr.sin_addr); + +// if (connect(client->sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { +// bk_printf("connection failed"); +// close(client->sockfd); +// goto client_ERROR; +// } strcpy(client->host, parsed_url.host); @@ -740,17 +778,183 @@ void close_websocket_client(WebSocketClient *client) { } } - +int http_get_client(const char *url, const char *headers,const char *Content_Type,char* response,int response_len); int bk_websocket_demo(void) { - WebSocketClient *client; - client = init_websocket_client("ws://118.145.158.207:22086/vc/coze?is_auth=0",NULL); - if (client== NULL) { - return -1; + // WebSocketClient *client; + // client = init_websocket_client("ws://118.145.158.207:22086/vc/coze?is_auth=0",NULL); + // if (client== NULL) { + // return -1; + // } + // close_websocket_client(client); + // aos_sleep(2); + // char *response =aic_zalloc(BUFFER_SIZE); + // //char *url = "http://dmp.raisound.com/sv/vad/auth/token?nonceStr=abc&sign=3470327e8eee163f00d5f54cc936d32595189b16d1e89c2b50155b80227c85d0×tamp=1750406765243&token=9542143a532adc10ec6ee530cd1824d53b"; + // char *url = "http://dmp.raisound.com/bz-mp-api/sv/vad/auth/token?nonceStr=abc&sign=3470327e8eee163f00d5f54cc936d32595189b16d1e89c2b50155b80227c85d0×tamp=1750406765243&token=9542143a532adc10ec6ee530cd1824d53b"; + // http_get_client(url,"bz-dt:9542143a532adc10ec6ee530cd1824d53b","application/x-www-form-urlencoded",response,BUFFER_SIZE); + // bk_printf("http GET data:%s",response); + // aic_free(response); + return 0; +} + +/************************http*********************************** */ + +// WebSocket 客户端结构体 +typedef struct { + int sockfd; + char host[128]; + char path[128]; + char query[512]; + int port; +} httpClient; +int send_http_get_handshake(httpClient *client,const char *headers,const char *Content_Type) { + char key[WEBSOCKET_KEY_LEN]; + bk_printf("send_handshake1"); + generate_websocket_key(key); + char accept_key[64]; + int ret = 0; + generate_accept_key(key, accept_key); + bk_printf("send_handshake2"); + char *request =aic_zalloc(BUFFER_SIZE); + if(headers!= NULL) + { + snprintf(request, BUFFER_SIZE, + "GET /%s?%s HTTP/1.1\r\n" + "Host: %s:%d\r\n" + "Content-Type: %s\r\n" + "Connection: close\r\n" + "%s\r\n" + "\r\n", + client->path,client->query ,client->host,client->port,Content_Type,headers); + }else + { + snprintf(request, BUFFER_SIZE, + "GET /%s?%s HTTP/1.1\r\n" + "Host: %s:%d\r\n" + "Content-Type: %s\r\n" + "Connection: close\r\n" + "\r\n", + client->path,client->query , client->host,client->port,Content_Type); + } + + bk_printf("send_handshake request:\r\n%s",request); + if (send(client->sockfd, request, strlen(request), 0) < 0) { + bk_printf("send handshake failed :sockfd:%d",client->sockfd); + + ret = -1; } + bk_printf("send_handshake3"); + aic_free(request); + return ret; +} +//http get 客户端 +int http_get_client(const char *url, const char *headers,const char *Content_Type,char* response,int response_len) { + //bk_printf("init_websocket_client 1\n"); + httpClient *client =NULL; + BK_URL parsed_url = {0}; + parsed_url = parse_url(url);//解析url + //bk_printf("url: %s", url); + if (parsed_url.error) { + bk_printf("Error: %s", parsed_url.error_message); + goto client_ERROR; + } else { + bk_printf("Protocol: %s", parsed_url.protocol); + bk_printf("Host: %s", parsed_url.host); + bk_printf("Port: %d", parsed_url.port); + bk_printf("Path: %s", parsed_url.path); + bk_printf("Query: %s", parsed_url.query); + + } + client = aic_zalloc(sizeof(httpClient)) ; + if(!client) + { + bk_printf("http_get_client alloc error"); + goto client_ERROR; + } + struct addrinfo hints, *addr_list, *cur; + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + if( getaddrinfo( parsed_url.host, parsed_url.port_str, &hints, &addr_list ) != 0 ) + //if( getaddrinfo( "www.baidu.com", "80", &hints, &addr_list ) != 0 ) + { + bk_printf("getaddrinfo error"); + goto client_ERROR; + } + + for( cur = addr_list; cur != NULL; cur = cur->ai_next ) + { + client->sockfd = (int) socket( cur->ai_family, cur->ai_socktype, + cur->ai_protocol ); + if( client->sockfd < 0 ) + { + continue; + } + + if( connect( client->sockfd , cur->ai_addr, (int)cur->ai_addrlen ) == 0 ) + { + + break; + } + + close( client->sockfd ); + goto client_ERROR; + bk_printf("http_get_client connect error"); + } + bk_printf("http_get_client connect ok,sockfd:%d",client->sockfd); +// client->sockfd = socket(AF_INET, SOCK_STREAM, 0); +// if (client->sockfd < 0) { +// bk_printf("socket creation failed"); +// goto client_ERROR; +// } + +// // bk_printf("init_websocket_client 3\n"); +// struct sockaddr_in server_addr; +// server_addr.sin_family = AF_INET; +// server_addr.sin_port = htons(parsed_url.port); + +// inet_pton(AF_INET, parsed_url.host, &server_addr.sin_addr); +// if (connect(client->sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { +// bk_printf("connection failed"); +// close(client->sockfd); +// goto client_ERROR; +// } - close_websocket_client(client); - return 0; + + strcpy(client->host, parsed_url.host); + strcpy(client->path, parsed_url.path); + strcpy(client->query, parsed_url.query); + client->port = parsed_url.port; + if (send_http_get_handshake(client,headers,Content_Type) < 0) { //发送头 + close(client->sockfd); + goto client_ERROR; + } + + + ssize_t bytes_received = recv(client->sockfd, response, response_len-1, 0); + if (bytes_received > 0) { + response[bytes_received] = '\0'; + bk_printf("Received handshake response:\n%s\n", response); + }else + { + bk_printf("recv error bytes_received %d", recv); + } + // if(strstr(buffer,"HTTP/1.1 101") == NULL) + // { + + // goto client_ERROR; + // } + + free_url(parsed_url); + if(client) + aic_free(client); + return bytes_received; +client_ERROR: + + if(client) + aic_free(client); + free_url(parsed_url); + return -1; } - \ No newline at end of file + diff --git a/2.code/aicos/app/AI_AMP_2_5/bk_websocket.h b/2.code/aicos/app/AI_AMP_2_5/bk_websocket.h index 5214e65..01d55ea 100644 --- a/2.code/aicos/app/AI_AMP_2_5/bk_websocket.h +++ b/2.code/aicos/app/AI_AMP_2_5/bk_websocket.h @@ -32,5 +32,5 @@ int receive_websocket_message(WebSocketClient *client, unsigned char *buf,int l // 发送 WebSocket 消息 int send_websocket_message(WebSocketClient *client, const unsigned char *message, size_t message_len, WebSocketMessageType type) ; - +int bk_websocket_demo(void); #endif diff --git a/2.code/aicos/app/AI_AMP_2_5/imsl_vad.h b/2.code/aicos/app/AI_AMP_2_5/imsl_vad.h index bde69af..8f36374 100644 --- a/2.code/aicos/app/AI_AMP_2_5/imsl_vad.h +++ b/2.code/aicos/app/AI_AMP_2_5/imsl_vad.h @@ -21,7 +21,7 @@ struct VadConfig 1 试用模式 (最长30分钟) 2 授权模型 (授权失败 控制台会打印,同时转为试用模式) */ -int init_vad(struct VadConfig* conf); +int init_vad(const struct VadConfig* conf); // 运行vad函数,data为16khz 16bit的pcm音频数据 // 注意data_len是int16_t的data_len,如果传入u8*或void* 数据data_len需要 / 2 diff --git a/2.code/aicos/app/AI_AMP_2_5/libimslnn.a b/2.code/aicos/app/AI_AMP_2_5/libimslnn.a index 399cedb..8ae85d5 100644 Binary files a/2.code/aicos/app/AI_AMP_2_5/libimslnn.a and b/2.code/aicos/app/AI_AMP_2_5/libimslnn.a differ diff --git a/2.code/aicos/app/AI_AMP_2_5/libimslvad.a b/2.code/aicos/app/AI_AMP_2_5/libimslvad.a index 19fd159..692d6a4 100644 Binary files a/2.code/aicos/app/AI_AMP_2_5/libimslvad.a and b/2.code/aicos/app/AI_AMP_2_5/libimslvad.a differ diff --git a/2.code/aicos/app/AI_AMP_2_5/opus/guixin/aic_ogg.h b/2.code/aicos/app/AI_AMP_2_5/opus/guixin/aic_ogg.h new file mode 100644 index 0000000..94c4172 --- /dev/null +++ b/2.code/aicos/app/AI_AMP_2_5/opus/guixin/aic_ogg.h @@ -0,0 +1,66 @@ +#ifndef AIC_OGG_H +#define AIC_OGG_H + +#ifdef __cplusplus +extern "C" +{ +#endif + /* + p_page: page buffer pointer + length: length of the page buffer + return: segment entry nunber + */ + int ogg_get_segment_num(unsigned char* p_page, int length); + /* + p_page: page buffer pointer + length: length of the page buffer + return: total length of the page + */ + int ogg_calc_total_segment_data_size(unsigned char* p_page, int length); + + typedef struct { + int index;//init to 0 + int pre_total_len;//init to 0 + } ogg_demux_context; + + /* + p_page: page buffer pointer + p_ctx: init for every page + return : pointer to audio frame data, frame lehgth of this auido frame + */ + //to reduce the latency, we can use this function to get the length of the next audio frame first and ignore the return + //buffer address. as soon as we get the data from network, send the data to opus decoder. + unsigned char* ogg_get_next_audio_frame(unsigned char* p_page, ogg_demux_context* p_ctx, int* frame_length); + + + //1: OpusHead, 2: OpusTags, 3: audio frame + //for OpusHead, return audio channel count and sample rate + int ogg_check_opus_page_type(unsigned char* p_page, int* channel_cnt, int* sample_rate); + + + + //buf length must >= 47+57 + //return length of the page + int ogg_generate_opus_head_and_tags(unsigned char* p_buf, int buf_length, int channel_cnt, int sample_rate); + + + typedef struct { + int frame_length;//pcm samples per frame + int neg_buf_length;//the available buffer length to store header ahead of audio data pointer + unsigned int seq_num;//init to 0 + unsigned long long granule_position;//init to 0 + } ogg_mux_context; + + /* + * p_buf: audio data pointer + * frame_num: audio frame number + * p_length: length of each audio frame + * last_flag: 0 if not last page + * return: length of page header + */ + int ogg_generate_opus_audio_page(unsigned char* p_buf, short* p_length, int frame_num, ogg_mux_context* p_ctx, int last_flag); + +#ifdef __cplusplus +} +#endif +#endif /* AIC_OGG_H */ \ No newline at end of file diff --git a/2.code/aicos/app/AI_AMP_2_5/opus/guixin/libogg.a b/2.code/aicos/app/AI_AMP_2_5/opus/guixin/libogg.a new file mode 100644 index 0000000..58a72d3 Binary files /dev/null and b/2.code/aicos/app/AI_AMP_2_5/opus/guixin/libogg.a differ diff --git a/2.code/aicos/app/AI_AMP_2_5/opus/guixin/libogg_dsp.a b/2.code/aicos/app/AI_AMP_2_5/opus/guixin/libogg_dsp.a new file mode 100644 index 0000000..da299b1 Binary files /dev/null and b/2.code/aicos/app/AI_AMP_2_5/opus/guixin/libogg_dsp.a differ diff --git a/2.code/aicos/app/AI_AMP_2_5/opus/guixin/opus_test.c b/2.code/aicos/app/AI_AMP_2_5/opus/guixin/opus_test.c new file mode 100644 index 0000000..61d2564 --- /dev/null +++ b/2.code/aicos/app/AI_AMP_2_5/opus/guixin/opus_test.c @@ -0,0 +1,35 @@ +static u16 g_pcm[320] = { +}; +static u8 g_bitstream[1500]; + +int opus(int argc, char **argv) +{ + int ret = aic_opus_init_encoder(16000, 1); + + if (ret) { + alog_error("init encoder failed"); + return -1; + } + ret = aic_opus_init_decoder(16000, 1); + if (ret) { + alog_error("init decoder failed"); + return -1; + } + /*input g_pcm, input sample:320, output:g_bitstream, ouput_buf size:1500 + ret is ouput size of encoded data*/ + ret = aic_opus_encode(g_pcm, 320, g_bitstream, 1500); + if (ret > 0) { + /*g_pcm: output pcm data + 640: output buffer size + g_bitstream: input encoded data + ret input: the valid length for g_bitstrream + ret return value: the sample count of output pcm data*/ + ret = aic_opus_decode(g_pcm, 640, g_bitstream, ret); + } + + + ret = aic_opus_deinit_encoder(); + ret = aic_opus_deinit_decoder(); + + return 0; +} \ No newline at end of file diff --git a/2.code/aicos/app/AI_AMP_2_5/opus/opus.zip b/2.code/aicos/app/AI_AMP_2_5/opus/opus.zip new file mode 100644 index 0000000..537f055 Binary files /dev/null and b/2.code/aicos/app/AI_AMP_2_5/opus/opus.zip differ