From: p15692025051 <846603105@qq.com> Date: Tue, 8 Apr 2025 05:54:52 +0000 (+0800) Subject: 2.5接口备份 X-Git-Url: http://git.snicker.com.cn/Users/apple/Desktop/static/gitweb.css?a=commitdiff_plain;h=467d99481d3e9716bfaa3711978aa689c8e0897e;p=mirrors%2FASR1603_G5.git 2.5接口备份 --- diff --git a/2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC.py b/2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC.py index 82e7b17e..d6de76f4 100644 --- a/2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC.py +++ b/2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC.py @@ -30,13 +30,14 @@ import machine import dataCall import constants import versions -#import VAD +import VAD #dev_type = "G10" dev_type = "7PIN_BK"#小瑞 #dev_type = "7PIN"#柒牌 #dev_type = 'momo'#食梦貘 #dev_type = 'sjgq'#四季甘泉 #dev_type = 'szbst'#深圳百事通 + class AI_led(Abstract): def __init__(self): if dev_type == "G10": @@ -1159,7 +1160,7 @@ class AI_VC(Abstract): self.VC_30S_timer.start(30000, 1, self.VC_30S_timer_cb) self.get_config_timer_count = 0 self.record_data_save_flag = 0 #是否保存录音文件 - self.play_data_save_flag = 0 #是否保存tts数据到文件 + self.play_data_save_flag = 0#是否保存tts数据到文件 self.record_fd = None self.play_fd = None self.is_VC_ACK = 0 #是否开启ack应答模式 @@ -1172,7 +1173,7 @@ class AI_VC(Abstract): self.VC_mode = 0 self.is_up_error= 0 #是否上传错误id self.Close_flag =0 #=1时,连续对话播放完音频就退出 - self.is_llm_commands = 1#=1用大模型判断命令,=0用服务器本地插件判断命令 + self.error_data = [] self.asr_taskid = "" self.VC_taskid = "" @@ -1201,12 +1202,13 @@ class AI_VC(Abstract): self.server_ip="118.145.158.207:22082" if dev_type == 'momo':# self.server_ip="118.145.158.207:22080" - elif dev_type == "7PIN": - self.server_ip="sevenpin.qipai.com.cn" + # elif dev_type == "7PIN": + # self.server_ip="sevenpin.qipai.com.cn" elif dev_type == "sjgq": self.server_ip="118.145.158.207:22084" - + elif dev_type == "7PIN_BK": + self.server_ip="amp.raisound.com" #开机提示音 self.power_on_tone = EventMesh.publish("get_storage_config","power_on_tone")# if dev_type != "7PIN": @@ -1230,6 +1232,8 @@ class AI_VC(Abstract): self.VC_play_TYPE = VC_play_TYPE_PCM #0:PCM 1:mp3 self.VC_record_samplerate = 16000 self.VC_play_samplerate = 16000 + self.VAD_data_len = 640 #10ms数据 + self.is_VAD = 0#=1打开vad打断 # ARG_sample_rate, // 采样率 # ARG_channel, // 通道数 # ARG_frame_size, // 每帧字节数 @@ -1237,10 +1241,20 @@ class AI_VC(Abstract): # ARG_voice_time, // 语音持续时间阈值(ms) # ARG_silence_time, // 静音持续时间阈值(ms) # ARG_silence_start_threshold, // 静音开始阈值(ms) - #self.vad = VAD.VAD(self.VC_record_samplerate ,1,6400,300,50,300,100) + self.vad = None + if self.is_VAD == 1: + self.vad = VAD.VAD(self.VC_record_samplerate ,1,self.VAD_data_len,600,100,300,100) self.speech_rate = EventMesh.publish("get_storage_config","speech_rate")#语速配置 if self.speech_rate == None: self.speech_rate = 0 + + self.vad_silence = EventMesh.publish("get_storage_config","vad_silence")#语速配置 + if self.vad_silence == None: + if dev_type == "7PIN": + self.vad_silence = 1500 + else: + self.vad_silence = 300 + self.VC_TTS_voice_type = EventMesh.publish("get_storage_config","VC_TTS_voice_type")#音色配置 if self.VC_TTS_voice_type == None or ("男" in self.VC_TTS_voice_type) == False: if dev_type == "G10" or dev_type == "7PIN_BK"or dev_type == "szbst": @@ -1318,37 +1332,37 @@ class AI_VC(Abstract): self.VC_TTS_voice_type = { "女":{ "bot_name":"柒妹妹", - "voice":"huoshan::zh_female_wanwanxiaohe_moon_bigtts" , + "voice":"zh_female_wanwanxiaohe_moon_bigtts" , "lang":"zh-cn" }, "男":{ "bot_name":"柒先生", - "voice":"huoshan::zh_male_wennuanahu_moon_bigtts" , + "voice":"zh_male_wennuanahu_moon_bigtts" , "lang":"zh-cn" }, "ç«¥":{ "bot_name":"柒乐乐", - "voice":"huoshan::ICL_zh_female_huoponvhai_tob" , + "voice":"ICL_zh_female_huoponvhai_tob" , "lang":"zh-cn" }, "粤":{ "bot_name":"柒先生", - "voice":"huoshan::zh_female_wanqudashu_moon_bigtts" , + "voice":"zh_female_wanqudashu_moon_bigtts" , "lang":"zh-hk" }, "四川":{ "bot_name":"柒妹妹", - "voice":"huoshan::zh_female_daimengchuanmei_moon_bigtts", + "voice":"zh_female_daimengchuanmei_moon_bigtts", "lang":"&lang=zh-cn-sc" }, "个性":{ "bot_name":"柒先生", - "voice":"huoshan::zh_male_sunwukong_mars_bigtts" , + "voice":"zh_male_sunwukong_mars_bigtts" , "lang":"zh-cn" }, "英语":{ "bot_name":"柒先生", - "voice":"huoshan::en_male_smith_mars_bigtts" , + "voice":"en_male_smith_mars_bigtts" , "lang":"zh-cn" } @@ -1380,6 +1394,9 @@ class AI_VC(Abstract): except Exception as e: usys.print_exception(e) #配置词 + self.commands_mode = 2 #=1用大模型判断命令,=0用服务器本地插件判断命令 =2用设备本地判断方式 + if dev_type == "7PIN_BK": + self.commands_mode = 2 self.commands = [ { "command": "切换音色",#命令 @@ -1660,7 +1677,7 @@ class AI_VC(Abstract): usys.print_exception(e) #开机提示语,如果联网失败,直接提示信号弱 - #"voice":{"女":"柒妹妹-huoshan::zh_female_wanwanxiaohe_moon_bigtts","男":"柒先生-huoshan::zh_male_wennuanahu_moon_bigtts","ç«¥":"柒乐乐huoshan::ICL_zh_female_huoponvhai_tob","广东":"柒先生-huoshan::zh_female_wanqudashu_moon_bigtts","四川":"柒妹妹-huoshan::zh_female_daimengchuanmei_moon_bigtts","个性":"柒先生-zh_male_sunwukong_mars_bigtts"} + #EventMesh.publish("get_storage_config",["powerRestart",1]) powerRestart = EventMesh.publish("get_storage_config","powerRestart")#=1非正常重启 if powerRestart == None: @@ -1783,7 +1800,8 @@ class AI_VC(Abstract): self.get_config_timer_count = 0 self.key_state = 1 self.Close() - + # if dev_type == "7PIN" : + # self.aud.aud_tone_play(10,200)#播放按键音 #self.aud.aud_tone_play(10,200)#播放按键音 self.AI_TTS_str = ""#"你好,有什么吩咐" self.AI_ASR_str = "" @@ -1797,7 +1815,7 @@ class AI_VC(Abstract): self.VC_Speech_Start() self.AI_VC_start() - self.chenggong_tone() + #self.chenggong_tone() # self.Close() # self.AI_VC_start() self.AI_key_long_press_flag = 0 @@ -1844,8 +1862,17 @@ class AI_VC(Abstract): def VC_error(self, event, msg):#错误播报 self.websocket_error() #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error}) + def set_VC_record_state_flag(self,data): - #开始录音 + self.VC_record_state_flag = data + print("set_VC_record_state_flag:{}".format(self.VC_record_state_flag)) + #开始录音,不缓存,直接发 + def VC_Speech_Start_now(self): + self.VC_Speech_Start() + if self.VC_record_state_flag == 1: + self.VC_record_state_flag =2 + print("VC_Speech_Start_now:{}".format(self.VC_record_state_flag)) + #开始录音,先缓存到buf,等服务器响应再发 def VC_Speech_Start(self): try: @@ -1885,10 +1912,9 @@ class AI_VC(Abstract): # print("self.record_pcm.stream_read_start:ret:{}".format(ret)) except Exception as e: usys.print_exception(e) - if self.VC_mode == 1 : - self.VC_record_state_flag = 1 - else: - self.VC_record_state_flag = 2 + + self.VC_record_state_flag = 1 + except Exception as e: self.websocket_error() self.VC_record_state_flag = 1 @@ -1963,6 +1989,7 @@ class AI_VC(Abstract): ##return print("VC_record_thread start!!!!!!!!!!!!!!!!!!!!\r\n") count = 0 + RequestToSpeak_flag = 0 # try: # uos.remove('/usr/test.pcm') # except Exception as e: @@ -1974,6 +2001,10 @@ class AI_VC(Abstract): # h_data_b = bytes(h_data) # self.AI_client_VC_send(h_data_b) AI_record_tmp_queue_len = 0 + vad_buf = bytearray() + VAD_data_count = 0 + vad_state = 0 + self.VAD_count = 0 while True: try: if self.VC_record_thread_lock == 2: @@ -1997,8 +2028,76 @@ class AI_VC(Abstract): #print("VC_record_thread:{}".format(Record_len)) if Record_len > 0: read_buf = bytes(Record_read_buf[:Record_len]) - # ret = self.vad.custom_vad_process(Record_read_buf,Record_len) - # print("VAD检测:datalen:{},结果:{}".format(Record_len,ret)) + print("Record_len:{}".format(Record_len)) + #VAD检测 + if self.is_VAD == 1: + vad_state = 0 + tmp_c = 1000 + while True: + tmp_c -=1 + if tmp_c <=0: + break + #vad_buf_len = len(vad_buf) + if VAD_data_count == 0:#没数据的时候 + vad_buf = Record_read_buf[:self.VAD_data_len] + VAD_data_count = self.VAD_data_len + self.vad.custom_vad_reset()#重置vad + else:#有数据的时候 + if Record_len - VAD_data_count < self.VAD_data_len :#剩余长度不够一次填充,先保留,但不填算法 + vad_buf = Record_read_buf[VAD_data_count:Record_len] + VAD_data_count = 0 + break + else:#剩余长度够填一次数据 + vad_buf = Record_read_buf[VAD_data_count:VAD_data_count+self.VAD_data_len] + VAD_data_count += len(vad_buf) + #print("vad_buf_len:{},{}".format(len(vad_buf),VAD_data_count)) + + if len(vad_buf) >= self.VAD_data_len: + vad_state = self.vad.custom_vad_process(vad_buf,len(vad_buf))#给vad数据 + #print("vad_state:{}".format(vad_state)) + + if VAD_data_count >= Record_len: + VAD_data_count = 0 + break + if vad_state == 1: + print("检测到VAD=1!!!!!!!!!!!!!") + print("检测到VAD=1!!!!!!!!!!!!!") + print("检测到VAD=1!!!!!!!!!!!!!") + + EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_Pause,"data":1})#停止音频 + # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_RequestToSpeak})#打断 + # RequestToSpeak_flag = 1 + + self.VAD_count+=1 + if self.VAD_count >= 20: + EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_RequestToSpeak})#打断 + + else: + if self.VAD_count != 0: + EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_Pause,"data":0})#恢复音频播放 + self.VAD_count = 0 + if self.VC_state >= VC_State_TTSStart: + pass + if vad_state == 1: + self.AI_record_tmp_queue.put(read_buf)#入缓存队列 + AI_record_tmp_queue_len += len(read_buf) + + + else: + VAD_data_count = 0 + if self.VC_record_state_flag <=1 :#没发送前先存起来 + self.AI_record_tmp_queue.put(read_buf) + AI_record_tmp_queue_len += len(read_buf) + else: + AI_record_tmp_queue_len = 0 + while True: + if self.AI_record_tmp_queue.empty() == True: + break + else: + pass + self.AI_client_VC_send(self.AI_record_tmp_queue.get()) #发送之前存的数据 + self.AI_client_VC_send(read_buf) + if self.record_data_save_flag == 1: if self.record_fd == None: try: @@ -2015,18 +2114,7 @@ class AI_VC(Abstract): #self.record_fd = None - if self.VC_record_state_flag <=1 :#没发送前先存起来 - self.AI_record_tmp_queue.put(read_buf) - AI_record_tmp_queue_len += len(read_buf) - else: - AI_record_tmp_queue_len = 0 - while True: - if self.AI_record_tmp_queue.empty() == True: - break - else: - pass - self.AI_client_VC_send(self.AI_record_tmp_queue.get()) #发送之前存的数据 - self.AI_client_VC_send(read_buf) + #print("VC_record_thread:{}".format(len(read_buf))) #count+=len(read_buf) @@ -2403,7 +2491,7 @@ class AI_VC(Abstract): print("VC VC:recv_data:{}".format(recv_data)) jsload_data = ujson.loads(recv_data) #print("AI_client_VC_recv jsload_data = {}".format(jsload_data)) - #self.LocalRespondingEnded_timerout = 0 + if jsload_data["event"] == "started" :#会话开始 #payload = jsload_data["payload"] # self.VC_dialog_id = payload["dialog_id"] @@ -2411,11 +2499,17 @@ class AI_VC(Abstract): EventMesh.publish("open_led_blue") print("VC:Started!!!!!!!!\r\n") if self.AI_TTS_str == "": - #self.AI_client_VC_send_speech()#开始上传语音 - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send_speech}) + #开始上传语音 + + if self.VC_mode == 0 : + self.VC_record_state_flag =2 + else: + EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send_speech}) + + else: EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_synthesis}) - + self.VC_state = VC_State_None elif jsload_data["event"] == "asr.started" :#asr开始 self.VC_state = VC_State_SpeechStart if self.VC_mode == 1 : @@ -2423,13 +2517,30 @@ class AI_VC(Abstract): EventMesh.publish("open_led_blue") elif jsload_data["event"] == "asr.result" :#asr结果 self.AI_ASR_str = jsload_data["payload"]["content"] - if asr_led_flag == 0: - asr_led_flag = 1 - EventMesh.publish("close_led") - else : - asr_led_flag = 0 - EventMesh.publish("open_led_blue") - elif jsload_data["event"] == "asr.completed" :#asr 终止的标识 + + EventMesh.publish("open_led_blue") + elif jsload_data["event"] == "asr.completed" :#asr 终止的标识 + print("self.commands_mode:{}".format(self.commands_mode)) + if self.commands_mode ==2: + ret= self.check_text(self.AI_ASR_str) + if ret == 0:#配置指令 + + if self.AI_VC_send_data_queue.empty()!=True: + self.AI_VC_send_data_queue.clear() + if self.AI_ASR_send_data_queue.empty()!=True: + self.AI_ASR_send_data_queue.clear() + self.AI_ASR_send_buf_len = 0 + EventMesh.publish("open_led_all") + try: + + EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End}) + EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_VC}) + EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) + except Exception as e: + usys.print_exception(e) + continue + elif ret == 1:#不处理 + pass #self.VC_Speech_End() #EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End}) if self.record_data_save_flag == 1: @@ -2446,9 +2557,14 @@ class AI_VC(Abstract): self.VC_state = VC_State_Thinking # EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_Start}) pass + elif jsload_data["event"] == "llm.delta" :#llm返回数据 + if self.is_VAD == 0: + if self.VC_record_state_flag == 1:#llm返回数据还没停止,就先停止 + EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End}) elif jsload_data["event"] == "tts.started" :#tts开始 - - EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End}) + self.VC_state = VC_State_TTSStart + if self.is_VAD == 0: + EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End}) EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_Start}) #self.VC_Play_Start() @@ -2459,31 +2575,31 @@ class AI_VC(Abstract): self.LocalRespondingEnded_timerout = 8 self.VC_state = VC_State_TTSEnd pass - # self.AI_client_VC_send_speech()#开始上传语音 - # self.VC_record_state_flag = 2 + + elif jsload_data["event"] == "canceled" :#打断 + EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_Start_now})#开始录音 + self.VC_state = VC_State_None elif jsload_data["event"] == "completed" :#会话结束 #EventMesh.publish("open_led_green")#绿色 self.LocalRespondingEnded_timerout = 8 self.VC_state = VC_State_End pass - # self.AI_client_VC_send_speech()#开始上传语音 - # self.VC_record_state_flag = 2 elif jsload_data["event"] == "command" :#命令匹配 ret = -1 try: - if self.is_llm_commands ==1: + if self.commands_mode ==1: if len(jsload_data["payload"]["functions"])>0: cmd = jsload_data["payload"]["functions"][0]["function"]["arguments"] print("llm:cmd:{}".format(cmd)) cmd = ujson.loads(cmd) ret = self.check_text_llm(cmd) - else: + elif self.commands_mode ==0: cmd = jsload_data["payload"] print("server:cmd:{}".format(cmd)) - ret = self.check_text(cmd) + ret = self.check_text_server(cmd) except Exception as e: usys.print_exception(e) if ret == -1: @@ -2496,20 +2612,38 @@ class AI_VC(Abstract): else:#下发音频数据 #self.AI_ASR_str = ""#下发音频后清掉asr结果 - if tts_led_flag == 0: - tts_led_flag = 1 - EventMesh.publish("open_led_green")#绿色 - else: - tts_led_flag = 0 - EventMesh.publish("close_led")# + + EventMesh.publish("open_led_green")#绿色 + print("下发音频数据1:{}".format(len(recv_data))) if self.play_data_save_flag == 1: + if self.play_fd ==None: + try: + uos.remove('/usr/play_data.pcm') + except Exception as e: + usys.print_exception(e) + self.play_fd = open('/usr/play_data.pcm','w') if self.play_fd !=None: self.play_fd.write(recv_data) # print("下发音频数据2:{}".format(len(recv_data))) #if self.VC_state >= VC_State_TTSStart: #self.put_record_data([recv_data,""]) + if self.VC_play_TYPE == VC_play_TYPE_PCM: + if self.play_pcm != None: + try: + #print("play_pcm.stream_write !!!") + buf_len = self.play_pcm.stream_get_buf_len() + count_tmp = 1000 + while buf_len < len(recv_data): + utime.sleep_ms(1) + count_tmp-=1 + if count_tmp<=0: + break + buf_len = self.play_pcm.stream_get_buf_len() + #print("buf已满,等待释放:buf_len:{},count_tmp:{}".format(buf_len,count_tmp)) + except Exception as e: + usys.print_exception(e) EventMesh.publish("publish_AI_btnInfo",{"func":self.put_record_data,"data":[recv_data,""]}) utime.sleep_ms(1) except Exception as e: @@ -2537,7 +2671,7 @@ class AI_VC(Abstract): ret=self.AI_audio_queue.put(data) self.tts_in_data_len += len(data[0]) #print("下发音频数据2:{},{}".format(len(data[0]),self.tts_in_data_len)) - def check_text(self,cmd): + def check_text_server(self,cmd): # if len(text)>60: # return -1 try: @@ -2839,7 +2973,7 @@ class AI_VC(Abstract): self.speech_rate += 10 if self.speech_rate > 50: - self.AI_TTS_str = "语速已经是最快啦" + self.AI_TTS_str = "语速已经是最快了" self.speech_rate = 50 else: @@ -2854,7 +2988,7 @@ class AI_VC(Abstract): self.speech_rate = -50 #EventMesh.publish("audio_montage_play",["yinliangyizuixiao.mp3"]) #self.aud.play(1,0,'U:/static/yinliangyizuixiao.mp3')#音量已最小 - self.AI_TTS_str = "语速已经是最慢啦" + self.AI_TTS_str = "语速已经是最慢了" else: EventMesh.publish("set_storage_config",["speech_rate",self.speech_rate]) @@ -2927,6 +3061,245 @@ class AI_VC(Abstract): usys.print_exception(e) self.AI_TTS_str = cmd["command"]["fail_prompt"] return -1 + def check_text(self,text): + print("check_text:len:{}".format(len(text))) + if len(text)>60: + return -1 + try: + if isinstance(text, str): + if text.find("声音") != -1 and text.find("改") != -1: + try: + for key in self.VC_TTS_voice_type: + if text.find(key) != -1 : + self.VC_TTS_voice_key = key + EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key]) + self.AI_TTS_str = "更改成功" + return 0 + except Exception as e: + usys.print_exception(e) + if text.find("男") != -1 : + if "男" in self.VC_TTS_voice_type: + self.VC_TTS_voice_key = "男" + EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key]) + # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) + #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 + self.AI_TTS_str = "更改成功" + return 0 + if text.find("女") != -1 : + if "女" in self.VC_TTS_voice_type: + self.VC_TTS_voice_key = "女" + EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key]) + # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) + #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 + self.AI_TTS_str = "更改成功" + return 0 + if text.find("同声") != -1 or text.find("ç«¥") != -1 : + if "ç«¥" in self.VC_TTS_voice_type: + self.VC_TTS_voice_key = "ç«¥" + EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key]) + # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) + #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 + self.AI_TTS_str = "更改成功" + return 0 + if text.find("粤") != -1 or text.find("越野") != -1 or text.find("广东话") != -1: + if "粤" in self.VC_TTS_voice_type: + self.VC_TTS_voice_key = "粤" + EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key]) + # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) + #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 + self.AI_TTS_str = "更改成功" + return 0 + if text.find("四川") != -1 : + if "四川" in self.VC_TTS_voice_type: + self.VC_TTS_voice_key = "四川" + EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key]) + # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) + #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 + self.AI_TTS_str = "更改成功" + return 0 + if text.find("个性") != -1 : + if "个性" in self.VC_TTS_voice_type: + self.VC_TTS_voice_key = "个性" + EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key]) + # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) + #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 + self.AI_TTS_str = "更改成功" + return 0 + if text.find("英语") != -1 : + if "英语" in self.VC_TTS_voice_type: + self.VC_TTS_voice_key = "英语" + EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key]) + # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) + #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 + self.AI_TTS_str = "更改成功" + return 0 + self.AI_TTS_str = "更改失败,没找到对应声音" + return 0 + if text.find("切换对话模式") != -1: + if self.VC_mode == 0: + self.VC_mode = 1 + self.AI_TTS_str = "已切换到单对话模式" + else: + self.VC_mode = 0 + self.AI_TTS_str = "已切换到长对话模式" + EventMesh.publish("set_storage_config",["VC_mode",self.VC_mode]) + # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) + #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 + + return 0 + if text.find("音量") != -1: + if text.find("加") != -1 : + self.VC_TTS_volume += 10 + if self.VC_TTS_volume > 100: + #EventMesh.publish("audio_montage_play",["yinliangyizuida.mp3"]) + #self.aud.play(1,0,'U:/static/yinliangyizuida.mp3')#音量已最大 + self.AI_TTS_str = "音量已最大" + self.VC_TTS_volume = 100 + else: + self.aud.setVolume(self.VC_TTS_volume //10) + EventMesh.publish("set_storage_config",["VC_TTS_volume",self.VC_TTS_volume]) + #EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) + #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#配置成功 + self.AI_TTS_str = "配置成功,当前音量 {}".format(self.VC_TTS_volume) + + return 0 + if text.find("减") != -1: + self.VC_TTS_volume -= 10 + if self.VC_TTS_volume < 0: + self.VC_TTS_volume = 0 + #EventMesh.publish("audio_montage_play",["yinliangyizuixiao.mp3"]) + #self.aud.play(1,0,'U:/static/yinliangyizuixiao.mp3')#音量已最小 + self.AI_TTS_str = "音量已最小" + else: + self.aud.setVolume(self.VC_TTS_volume //10) + EventMesh.publish("set_storage_config",["VC_TTS_volume",self.VC_TTS_volume]) + #EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) + #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#配置成功 + self.AI_TTS_str = "配置成功,当前音量 {}".format(self.VC_TTS_volume) + return 0 + + if text.find("进入工厂模式") != -1 : + self.factory_mode() + return 1 + if text.find("查询") != -1: + + if text.find("信号") != -1 : + signal = net.csqQueryPoll() + + self.AI_TTS_str = "当前信号{}".format(signal) + return 0 + if text.find("电量") != -1 : + battery = EventMesh.publish("get_battery") + print("电量查询:{}".format(battery)) + #EventMesh.publish("audio_montage_play",["dianliangshengyu{}.mp3".format(battery)]) + #self.aud.play(1,0,'U:/static/dianliangshengyu{}.mp3'.format(battery))#电量剩余 + self.AI_TTS_str = "电量剩余百分之{}".format(battery) + return 0 + if text.find("电压") != -1 : + Vbatt = Power.getVbatt() + #EventMesh.publish("audio_montage_play",["dianliangshengyu{}.mp3".format(battery)]) + #self.aud.play(1,0,'U:/static/dianliangshengyu{}.mp3'.format(battery))#电量剩余 + self.AI_TTS_str = "当前电池电压{}".format(Vbatt) + return 0 + + if text.find("卡号") != -1 : + iccid = sim.getIccid() + if iccid != -1 and len(iccid) > 5: + print("iccid{}".format(iccid)) + self.AI_TTS_str = "当前卡号为:{}".format(iccid) + else: + self.AI_TTS_str = "卡号查询失败" + return 0 + if text.find("设备号") != -1 : + imei = modem.getDevImei() + if imei != -1 and len(imei) > 5: + print("IMEI:{}".format(imei)) + self.AI_TTS_str = "当前设备号为:{}".format(imei) + else: + self.AI_TTS_str = "设备号查询失败" + return 0 + if text.find("版本") != -1 : + sourceVersion = versions.Build_Time + self.AI_TTS_str ="Mr-Seven-"+sourceVersion + return 0 + if text.find("服务器地址") != -1 : + self.AI_TTS_str ="服务器地址"+self.server_ip + return 0 + + if text.find("讲话") != -1: + if text.find("å¿«") != -1 and text.find("太") == -1 : + self.speech_rate += 10 + if self.speech_rate > 50: + + self.AI_TTS_str = "语速已经是最快了" + self.speech_rate = 50 + else: + + EventMesh.publish("set_storage_config",["speech_rate",self.speech_rate]) + + self.AI_TTS_str = "明白,语速已经调快了,当前语速是{}".format(self.speech_rate) + + return 0 + if text.find("慢") != -1 and text.find("太") == -1 : + self.speech_rate -= 10 + if self.speech_rate < -50: + self.speech_rate = -50 + #EventMesh.publish("audio_montage_play",["yinliangyizuixiao.mp3"]) + #self.aud.play(1,0,'U:/static/yinliangyizuixiao.mp3')#音量已最小 + self.AI_TTS_str = "语速已经是最慢了" + else: + EventMesh.publish("set_storage_config",["speech_rate",self.speech_rate]) + + self.AI_TTS_str = "明白,语速已经调慢了,当前语速是{}".format(self.speech_rate) + return 0 + if text.find("聆听") != -1: + if text.find("å¿«") != -1 and text.find("太") == -1 : + self.vad_silence -= 200 + if self.vad_silence < 100: + + self.AI_TTS_str = "已经是最快了" + self.vad_silence = 100 + else: + self.AI_TTS_str = "配置成功,当前语音断句速度是{}毫秒".format(self.vad_silence) + EventMesh.publish("set_storage_config",["speech_rate",self.vad_silence]) + return 0 + if text.find("慢") != -1 and text.find("太") == -1 : + self.vad_silence += 200 + if self.vad_silence > 2000: + self.vad_silence = 2000 + #EventMesh.publish("audio_montage_play",["yinliangyizuixiao.mp3"]) + #self.aud.play(1,0,'U:/static/yinliangyizuixiao.mp3')#音量已最小 + self.AI_TTS_str = "已经是最慢了" + else: + self.AI_TTS_str = "配置成功,当前语音断句速度是{}毫秒".format(self.vad_silence) + EventMesh.publish("set_storage_config",["speech_rate",self.vad_silence]) + return 0 + if text.find("升级") != -1 and (text.find("OTA") != -1 or text.find("ota") != -1): + if self.ai_OTA.min_sys_ota()==1: + self.AI_TTS_str = "有新版本,准备开始升级,升级过程会多次重启设备,请保证流量充足及电量充足" + else: + self.AI_TTS_str = "当前已是最新版本" + return 0 + + if len(text)<16 and (text.find("再见") != -1 or text.find("拜拜") != -1 or text.find("关闭对话") != -1): + #EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) + if dev_type != "7PIN":#柒牌 + self.AI_TTS_str = "好嘞,再见,我们下次再聊" + self.Close_flag = 1 + return 0 + else: + EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) + return 1 + if len(text)<12 and (text.find("关机") != -1 ): + if dev_type == "7PIN":#柒牌 + EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) + return 1 + EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) + EventMesh.publish("Power_off") + return 1 + except Exception as e: + usys.print_exception(e) + return -1 #获取trace_id def get_trace_id(self): t = utime.mktime(utime.localtime()) @@ -2980,8 +3353,15 @@ class AI_VC(Abstract): except Exception as e: self.VC_Play_End() usys.print_exception(e) - - + #暂停/继续声音播放 Pause_flag = 1暂停 + def VC_Play_Pause(self,Pause_flag): + try: + if self.VC_play_TYPE == VC_play_TYPE_PCM: + if self.play_pcm != None: + self.play_pcm.stream_pause(Pause_flag) + except Exception as e: + self.VC_Play_End() + usys.print_exception(e) #停止播放声音 def VC_Play_End(self): self.VC_Play_flag = 0 @@ -3003,7 +3383,10 @@ class AI_VC(Abstract): elif self.VC_play_TYPE == VC_play_TYPE_MP3: self.aud.stopPlayStream() self.aud.stopAll() - + if self.AI_audio_queue.empty()!=True: + self.AI_audio_queue.clear() + + def _1S_timer_cb(self,*argc): EventMesh.publish("publish_AI_btnInfo",{"func":self._1S_timer_cb_}) @@ -3036,7 +3419,8 @@ class AI_VC(Abstract): #utime.sleep_ms(1000) EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_End}) #EventMesh.publish("publish_AI_btnInfo",{"func":self.chenggong_tone}) - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send_speech})#开始录音 + EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_Start_now})#开始录音 + self.VC_state = VC_State_None #通知服务器播放结束 #self.AI_client_VC_LocalRespondingEnded() @@ -3079,24 +3463,7 @@ class AI_VC(Abstract): #utime.sleep_ms(50) else: print("self.VC_state :{}".format(self.VC_state )) - # if self.VC_state > VC_State_SpeechStart: - # #客户端打断对话 - # print("打断对话") - # # self.websocket_deconnect_VC() - # # self.websocket_connect_VC()#连接服务器 - # # self.AI_client_VC_start_requset() - # #self.AI_client_VC_RequestToSpeak() - # elif self.VC_state == VC_State_Listening: - # #直接chat - # print("直接chat") - # # self.AI_client_VC_RequestToRespond() - # return - # else: - # print("异常状态") - #self.AI_client_VC_RequestToSpeak() - # self.websocket_deconnect_VC() - # self.websocket_connect_VC()#连接服务器 - # self.AI_client_VC_start_requset() + if self.AI_client_VC_isconnect == 0: return self.AI_client_VC_start_requset() @@ -3105,11 +3472,9 @@ class AI_VC(Abstract): self.VC_state = VC_State_None if self.AI_TTS_str == "":#没有tts要播放的时候才开始录音 #开始asr录音 - if self.VC_mode == 1:#单对话模式 - self.VC_Speech_Start()#开启线程获取录音数据 - else : - self.VC_Speech_Start()#开启线程获取录音数据 - self.VC_record_state_flag = 2 + self.VC_Speech_Start()#开启线程获取录音数据 + + # pass print("AI_VC_start4") #self.VC_Play_Start() @@ -3135,12 +3500,12 @@ class AI_VC(Abstract): print("AI_VC_start5") #开始会话 def AI_client_VC_start_requset(self): - voice="huoshan::zh_male_wennuanahu_moon_bigtts" + voice="zh_male_wennuanahu_moon_bigtts" try: voice = self.VC_TTS_voice_type[self.VC_TTS_voice_key]["voice"] except Exception as e: usys.print_exception(e) - #voice="huoshan::zh_female_dongmanxiaoyang_moon_bigtts" + #voice="zh_female_dongmanxiaoyang_moon_bigtts" json_data = \ { @@ -3160,18 +3525,16 @@ class AI_VC(Abstract): "custom_variables": { "name": self.bot_name, }, - # "greeting":{ - # "enabled":True, - # "content":"小瑞来陪你聊天了!" - # } + "greeting":{ + "enabled":False, + "content":"" + }, "bot_option": { "use_workflow": True, - "bot_id":"7481164663863459850",#鸭子 - "workflow_id":"7480485093845991443", - # "bot_id":"7462617881076351002",#语言助手 - # "workflow_id":"7462621757327196187", - # "bot_id":"7469964258592931852",#深圳百事通 - # "workflow_id":"7469968083063603241", + + "bot_id":"7462617881076351002",#语言助手 + "workflow_id":"7462621757327196187", + } } }, @@ -3184,15 +3547,16 @@ class AI_VC(Abstract): "channel": 1, "volume": self.VC_TTS_volume, #"voice": "7426720361732980745", - "voice": voice, + "voice": voice,#音色 "speech_rate": self.speech_rate,#语速 + "chunk_interval_ms": 100, # 配置每段音频入队间隔时间 100ms } }, "inbound_attributes": { - #"provider": "xun-fei",# - "provider": "volcengine", + "provider": "xun-fei",# + #"provider": "volcengine", "disable_vad":True, - "vad_silence":300, + "vad_silence":self.vad_silence, "interrupt_options":{ "concatenate_results":True, "thinking_time_only": True, @@ -3201,13 +3565,46 @@ class AI_VC(Abstract): "format": "pcm", "sample_rate": self.VC_record_samplerate, "bit_rate": 16, - "channel": 1 + "channel": 1, + "enable_punctuation": True, + "enable_itn":True } }, "commands":self.commands, } } - if self.is_llm_commands ==1: + # "bot_id":"7481164663863459850",#鸭子 + # "workflow_id":"7480485093845991443", + # "bot_id":"7462617881076351002",#语言助手 + # "workflow_id":"7462621757327196187", + # "bot_id":"7469964258592931852",#深圳百事通 + # "workflow_id":"7469968083063603241", + # "bot_id":"7411071327182438412",#柒牌 + # "workflow_id":"7469049680291610636", + if dev_type == "7PIN_BK":#小瑞 + # json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["bot_id"]="7462617881076351002"#语言助手 + # json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["workflow_id"]="7462621757327196187" + json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["bot_id"]="7486697248416989193"#极简 + json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["workflow_id"]="7486698347416649778" + #json_data["payload"]["dialog_attributes"]["provider"]="doubao"#豆包 + json_data["payload"]["inbound_attributes"]["provider"]="volcengine"#火山 + #json_data["payload"]["inbound_attributes"]["vad_silence"] = 200 + + elif dev_type == "7PIN":#柒牌 + json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["bot_id"]="7411071327182438412"# + json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["workflow_id"]="7469049680291610636" + #json_data["payload"]["inbound_attributes"]["vad_silence"] = 1000 + # + elif dev_type == 'momo':#食梦貘 + pass + elif dev_type == 'sjgq':#四季甘泉 + json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["bot_id"]="7472201279826690111" + json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["workflow_id"]="472203898494500914" + pass + elif dev_type == 'szbst':#深圳百事通 + json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["bot_id"]="7469964258592931852" + json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["workflow_id"]="7469968083063603241" + if self.commands_mode !=0: json_data["payload"]["commands"] = [] if self.VC_mode == 0:#长对话模式打开vad json_data["payload"]["inbound_attributes"]["disable_vad"] = False @@ -3226,14 +3623,9 @@ class AI_VC(Abstract): if self.VC_mode == 1:#单对话模式 self.AI_client_VC_send(ujson.dumps(json_data)) - EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_Start}) - #self.VC_Speech_Start()#开启线程获取录音数据 - else : - #EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_End}) - EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_Start}) + - # self.VC_Play_End() - # self.VC_Speech_Start()#开启线程获取录音数据 + @@ -3255,19 +3647,18 @@ class AI_VC(Abstract): def AI_client_VC_RequestToSpeak(self): json_data = \ { - "header":{ - "trace_id":self.get_trace_id(), - "event":"RequestToSpeak" - }, - "payload":{ - "dialog_id":self.VC_dialog_id, - "session_id": self.session_id , - } + "event": "cancel", + "payload": {} } print("AI_client_VC_RequestToSpeak!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_init}) - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)}) + # EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_init}) + # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)}) # utime.sleep_ms(1) + self.websocket_deconnect_VC() + self.AI_audio_queue_thread_close() + self.VC_state = VC_State_None + #self.Close() + self.AI_VC_start() #TTS播放 def AI_client_VC_synthesis(self): json_data = \ @@ -3355,13 +3746,13 @@ class AI_VC(Abstract): # tmp= self.aud.playStream(1,data[0] ) # else: write_buf = bytearray(data[0]) - print("play_pcm.stream_write1 len:{}".format(len(write_buf))) + #print("play_pcm.stream_write1 len:{}".format(len(write_buf))) if self.play_pcm != None: #print("play_pcm.stream_write !!!") ret = self.play_pcm.stream_write(write_buf,len(write_buf)) #ret= self.aud.playStream(1, data[0])#播放音频流 self.tts_out_data_len += ret - #print("play_pcm.stream_write:{}".format(self.tts_out_data_len)) + #print("play_pcm.stream_write2:{}".format(self.tts_out_data_len)) elif self.VC_play_TYPE == VC_play_TYPE_MP3: tmp= self.aud.playStream(3, data[0])#播放音频流 @@ -3463,6 +3854,7 @@ class AI_VC(Abstract): if self.play_data_save_flag == 1: if self.play_fd !=None: self.play_fd.close() + self.play_fd = None print("ai_VC Close3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n") if self.AI_VC_send_data_queue.empty()!=True: