#include "bk_make_time.h"
// #include "opus/include/opus.h"
char FXH01_Version[100];
+
u8 current_card_id = 0;
u8 VC_TTS_PLAY_EVENT = 0;
typedef enum
attributes_format_OPUS,
}attributes_format_type;
attributes_format_type inbound_attributes_format = attributes_format_PCM;
-attributes_format_type outbound_attributes_format = attributes_format_OPUS;
+attributes_format_type outbound_attributes_format = attributes_format_PCM;
#define OPUS_ENCODER_PACK_MS 60 //多少ms一帧数据
static void AI_VC_record_task(void *thread_input);//录音线程
static void AI_client_VC_synthesis(char *str);
static void AI_VC_put_record_data(char *data,u32 len);
+//websocket 资源管控,防止不释放
+#define WEBSOCKET_MAX_NUM 12
+WebSocketClient* websocket_res[WEBSOCKET_MAX_NUM] = {0};
+
WebSocketClient *AI_client_VC = NULL;
static u32 close_timerout = 0;
static u32 VC_pingping_timerout = 0;
int get_AI_key_longstate(void);
-static void AI_VC_send_satrt(void);
+static void AI_VC_send_satrt(char is_greeting);
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];
{
vc_cfg.start_flag = 0xaaaa;
vc_cfg.end_flag = 0xaaaa;
- vc_cfg.dev_type = DEV_FX1_H;//产品
+ //vc_cfg.dev_type = DEV_FX1_H;//产品
//vc_cfg.dev_type = DEV_ADS;//奥德赛
vc_cfg.dev_type = DEV_JSWM;//金山完美
//vc_cfg.dev_type = DEV_ALY;//阿里云
free(json_str);
cJSON_Delete(root);
}
-//开始事件
-static void AI_VC_send_satrt(void)
+//开始事件 is_greeting//是否开启开场白
+static void AI_VC_send_satrt(char is_greeting)
{
// 创建根对象
cJSON *root = cJSON_CreateObject();
// 创建 greeting 对象
cJSON *greeting = cJSON_CreateObject();
- cJSON_AddBoolToObject(greeting, "enabled", FALSE);
- cJSON_AddStringToObject(greeting, "content", "123456789123456789");
- cJSON_AddItemToObject(dialog_cfg, "greeting", greeting);
+ if(is_greeting == 1)
+ {
+ cJSON_AddBoolToObject(greeting, "enabled", TRUE);//是否播放提示词
+ cJSON_AddStringToObject(greeting, "content", "你好");
+ cJSON_AddItemToObject(dialog_cfg, "greeting", greeting);
+ }else
+ {
+ cJSON_AddBoolToObject(greeting, "enabled", FALSE);//是否播放提示词
+
+ }
+
// 创建 bot_option 对象
cJSON *bot_option = cJSON_CreateObject();
if(vc_cfg.dev_type == DEV_ADS)
{
cJSON_AddBoolToObject(bot_option, "use_workflow", 0);//奥德赛
- cJSON_AddStringToObject(bot_option, "bot_id", "7507478798502625295");//奥德赛
+ cJSON_AddStringToObject(bot_option, "bot_id", "7525301449820291111");//奥德赛
cJSON_AddStringToObject(bot_option, "workflow_id", "");
}else
free(json_str);
cJSON_Delete(root);
}
-//打断
-static void AI_VC_send_cancel(void)
-{
- // 创建根对象
- cJSON *root = cJSON_CreateObject();
- if (root == NULL) {
- bk_printf("Failed to create root object.\n");
- return ;
- }
-
- // 设置 "event" 字段
- cJSON_AddStringToObject(root, "event", "cancel");
-
- // 创建 "payload" 对象
- cJSON *payload = cJSON_CreateObject();
- if (payload == NULL) {
- bk_printf("Failed to create payload object.\n");
- cJSON_Delete(root);
- return ;
- }
- // 将 "payload" 对象添加到根对象中
- cJSON_AddItemToObject(root, "payload", payload);
-
- // 将 JSON 对象转换为字符串
- char *json_str = cJSON_Print(root);
- if (json_str == NULL) {
- bk_printf("Failed to print JSON object.\n");
- cJSON_Delete(root);
+// //打断
+// static void AI_VC_send_cancel(void)
+// {
+// // 创建根对象
+// cJSON *root = cJSON_CreateObject();
+// if (root == NULL) {
+// bk_printf("Failed to create root object.\n");
+// return ;
+// }
+
+// // 设置 "event" 字段
+// cJSON_AddStringToObject(root, "event", "cancel");
+
+// // 创建 "payload" 对象
+// cJSON *payload = cJSON_CreateObject();
+// if (payload == NULL) {
+// bk_printf("Failed to create payload object.\n");
+// cJSON_Delete(root);
+// return ;
+// }
+// // 将 "payload" 对象添加到根对象中
+// cJSON_AddItemToObject(root, "payload", payload);
+
+// // 将 JSON 对象转换为字符串
+// char *json_str = cJSON_Print(root);
+// if (json_str == NULL) {
+// bk_printf("Failed to print JSON object.\n");
+// cJSON_Delete(root);
- }
- AI_VC_send_data(json_str,strlen(json_str),AIC_WEBSOCKET_OPCODE_TEXT_FRAME);//发送数据
+// }
+// AI_VC_send_data(json_str,strlen(json_str),AIC_WEBSOCKET_OPCODE_TEXT_FRAME);//发送数据
- // 释放内存
- free(json_str);
- cJSON_Delete(root);
-}
+// // 释放内存
+// free(json_str);
+// cJSON_Delete(root);
+// }
//TTS播放
static void VC_TTS_Play(const char *str)
{
//VC_record_End();
VC_Play_End();
websocket_deconnect_VC();
- AI_VC_start();
+ AI_VC_start(0);
}
//pinpin发送
void AI_VC_send_ping_ping(void)
{
int ret=0;
//bk_stream_play_start();
- AI_VC_audio_queue_t AI_VC_play_queue_data;
+ AI_VC_audio_queue_t AI_VC_play_queue_data = {0};
aos_status queue_ret = AOS_ERROR;
AI_VC_play_task_flag = 1;
bk_printf("AI_VC_play_task go......");
queue_ret = aos_recv_from_queue(AI_VC_play_queue,&AI_VC_play_queue_data,AOS_NO_WAIT);
if( queue_ret== AOS_SUCCESS)
{
+ if(AI_VC_play_queue_data.len> 32*1024)//数据太大,可能是出错了
+ {
+ bk_printf("AI_VC_play_queue 数据太大!!!!!!!!!!!");
+ break;
+ }
if( AI_VC_play_queue_data.data)
{
ret = app_audio_write(APP_AUDIO_TYPE_STREAM_DUPLEX,
}
+int add_websocket_res(WebSocketClient* websocket)
+{
+ //if(AI_client_VC->sockfd >=0)//做socket资源回收,防止socket占用
+
+ for(int i = 0;i<WEBSOCKET_MAX_NUM ;i++)
+ {
+ if(websocket_res[i] == NULL)
+ {
+ websocket_res[i] =websocket ;
+ break;
+ }
+ if(i == WEBSOCKET_MAX_NUM-1)
+ {
+ bk_printf("websocket资源用完了!!!!!!!!!!!!");
+ return -1;//满了出问题
+ }
+ }
+
+ return 0;
+}
+//正常关闭ws时调用
+void delete_websocket_res(WebSocketClient* websocket)
+{
+ for(int i = 0;i<WEBSOCKET_MAX_NUM ;i++)
+ {
+ if(websocket_res[i] == websocket)
+ {
+ websocket_res[i] = NULL;
+ break;
+ }
+ }
+}
+void free_all_websocket_res(void)
+{
+ bk_printf("释放所有websocket资源:");
+ for(int i = 0;i<WEBSOCKET_MAX_NUM;i++)
+ {
+ if(websocket_res[i] != NULL)
+ {
+ close_websocket_client(websocket_res[i]);
+ bk_printf("socket_id:%d",websocket_res[i]->sockfd);
+ websocket_res[i] = NULL;
+ }
+ }
+}
+//获取ws可以资源
+int get_websocket_res_num(void)
+{
+ int num = 0;
+ for(int i = 0;i<WEBSOCKET_MAX_NUM ;i++)
+ {
+ if(websocket_res[i] != NULL)
+ {
+ num++;
+ }
+ }
+ if(WEBSOCKET_MAX_NUM-num <= 0)
+ {
+ bk_printf("WS可用资源为0");
+ }
+ return WEBSOCKET_MAX_NUM-num;
+}
//连接websocket
static int websocket_connect_VC(void)
{
+ char *url = NULL;
+ int ret = 0;
//连接服务器
if(AI_client_VC == NULL)
{
//AI_client_VC = init_websocket_client("ws://118.145.158.207:22086/vc/coze?is_auth=0",NULL);
- char *url = aic_malloc(512);//[100] = "ws://118.145.158.207:22086/vc/chat?is_auth=0";
+ url = aic_malloc(512);//[100] = "ws://118.145.158.207:22086/vc/chat?is_auth=0";
int url_len = 0;
if(!url)
return -1;
{
bk_printf("设备登录失败 count:%d",count);
dev_authentication_MSG_put(NULL,0,AUT_LOGIN);
- return - 1;
+ ret = - 1;
+ goto CONNECT_RET;
}
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());
url[url_len] = 0;
bk_printf("连接服务器 url:%s",url);
+ int ws_res_num = get_websocket_res_num();
+ bk_printf("WS资源剩余量:%d",ws_res_num);
+ if(ws_res_num<=0)//资源不够,要释放资源
+ {
+ free_all_websocket_res();
+ }
+
AI_client_VC = init_websocket_client(url,NULL);
if(!AI_client_VC)
{
dev_authentication_MSG_put(NULL,0,AUT_LOGIN);
bk_printf("连接服务器 失败");
- return -1;
+ free_all_websocket_res();
+ ret = - 1;
+ goto CONNECT_RET;
}
- bk_printf("AI_client_VC:%d",AI_client_VC);
- aic_free(url);
+ //socket_id
+ if(add_websocket_res(AI_client_VC) == -1)//添加ws资源管控,如果用完了,释放所有资源
+ {
+ free_all_websocket_res();
+ ret = - 1;
+ goto CONNECT_RET;
+ }
+ bk_printf("AI_client_VC:%d",AI_client_VC->sockfd);
+
}
//创建发送线程
if(AI_VC_send_task_id == 0)
AOS_AUTO_START);
bk_printf("创建读线程 AI_VC_read_task_id:%d",AI_VC_read_task_id);
}
- return 0;
+ CONNECT_RET:
+ if(url)
+ aic_free(url);
+ return ret;
}
static void websocket_deconnect_VC(void)
// }
if(AI_client_VC)//先断开再关闭读线程
{
+ delete_websocket_res(AI_client_VC);//删除该对象ws资源管控
close_websocket_client(AI_client_VC);
AI_client_VC = NULL;
}
VC_state = VC_State_None;
VC_record_Start() ;
- if(AI_VC_start()==0)
+ if(AI_VC_start(0)==0)
{
play_file_stream_data("C:/chenggong.pcm");
//audio_play_tone(3,300);//播放提示音,测试用,位置不能变,和双向流有冲突
return 0;
}
char AI_VC_start_lock = 0;
-int AI_VC_start(void)
+//is_greeting,是否播放开场白
+int AI_VC_start(char is_greeting)
{
power_off_count = 6*60*24;//24小时倒计时
int ret = 0,status = 0;
conf.vad_log_level = 0;
int init_vad_ret = 0;
strcpy(conf.auth_info.dmp_token, get_token());
+ static int imsl_nn_init_flag = -1;
+ if (imsl_nn_init_flag != 0) {
+ extern imsl_nn_printf_func imsl_nn_printf;
+ imsl_nn_printf = bk_printf;
+ imsl_nn_init_flag = 0;
+ }
init_vad_ret = init_vad(&conf);
}
//aos_sleep(5);
- AI_VC_send_satrt();//
+ AI_VC_send_satrt(is_greeting);//
close_timerout = 0;
AI_VC_start_RET:
AI_VC_start_lock = 0;
// aic_gpio_output(GPIO_20,GPIO_OUTPUT_LVL_LOW );
bk_printf("AI_VC_Close!!!!!!!!!!!!");
-
+ websocket_deconnect_VC();//断开连接
//销毁录音线程
if(AI_VC_record_task_id != 0)
{
VC_Play_End();
bk_printf("AI_VC_Close2!!!!!!!!!!!!");
- websocket_deconnect_VC();
+
//销毁发送队列,不在websocket_deconnect_VC里调用,避免重连需要发指令
if(AI_VC_send_queue != NULL)
{
// aut_active();//没有密钥走激活
// //每小时登录一次
// aut_login();
+ static u8 chg_status_tmp = 0;
+ static u8 is_Low_power_warning = 0;
login_timer_count++;
if(login_timer_count>60*6)
{
}
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)
+ //bk_printf("充电状态:%d",psy_info.bat_chg_status);
+ if(psy_info.bat_chg_status == 2)//没在充电状态
{
- // 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);
+
+ if(psy_info.bat_capacity> 15 &&psy_info.bat_capacity<=25 && AI_VC_stata == 0 && is_Low_power_warning == 0 )//只响一次
+ {
+ play_audio_file("C:/Low_power_warning.mp3");
+ is_Low_power_warning =1;
+ }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);
+
+ }
+ }else if(psy_info.bat_chg_status == 1)//充电状态
+ {
+
}
+ if(chg_status_tmp != psy_info.bat_chg_status)//状态发生改变,清掉状态
+ {
+ is_Low_power_warning =0;
+ }
+ chg_status_tmp = psy_info.bat_chg_status;
// 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,
// {
// aos_sleep(1000);
// }
-
- VC_TTS_Play(vc_cfg.power_on_tone);//开启vc播放tts
+ if(vc_cfg.dev_type == DEV_JSWM)//金三完美使用dmp配置开场白
+ {
+ AI_VC_start(1);
+ }
+ else{
+ VC_TTS_Play(vc_cfg.power_on_tone);//开启vc播放tts
+ }
+
while (1) {
if(AI_AMP_task_queue)
{
VC_state = VC_State_None;
websocket_deconnect_VC();
websocket_connect_VC();//重连
- AI_VC_send_satrt();//发送开始
+ AI_VC_send_satrt(0);//发送开始
break;
AI_VC_Close();
break;
case VC_START:
- AI_VC_start();
+ AI_VC_start(0);
break;
case VC_PLAY_START:
VC_Play_Start();