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":
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应答模式
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 = ""
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":
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, // 每帧字节数
# 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":
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"
}
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": "切换音色",#命令
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:
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 = ""
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
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:
# 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
##return
print("VC_record_thread start!!!!!!!!!!!!!!!!!!!!\r\n")
count = 0
+ RequestToSpeak_flag = 0
# try:
# uos.remove('/usr/test.pcm')
# except Exception as e:
# 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:
#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:
#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)
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"]
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 :
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:
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()
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:
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:
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:
self.speech_rate += 10
if self.speech_rate > 50:
- self.AI_TTS_str = "语速已经是最快啦"
+ self.AI_TTS_str = "语速已经是最快了"
self.speech_rate = 50
else:
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])
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())
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
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_})
#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()
#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()
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()
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 = \
{
"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",
+
}
}
},
"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,
"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
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()#开启线程获取录音数据
+
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 = \
# 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])#播放音频流
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: