# -*- coding: utf-8 -*- import wave import pyaudio import subprocess import numpy as np import time import cn2an import os from model_ASR import * from mesh_ASR import * from CAD_ASR import * from model_operator import * from file_operation import * #-------关联C++库--------------- import ctypes import platform from ctypes import * system = platform.system() if system == "Windows": pre = "./" suff = ".dll" else: pre = "./lib" suff = ".so" libfile = ctypes.cdll.LoadLibrary filename = pre+"MainWindow"+suff mw = libfile(filename) class Recorder: def __init__(self, chunk=16, volume=600, gap=600, wait_time=3): self.CHUNK = chunk self.FORMAT = pyaudio.paInt16 self.CHANNELS = 1 self.RATE = 16000 self.WAIT_TIME = wait_time self._frames = [] self.VOLUME = volume self.GAP = gap self.running = True def __recording(self): p = pyaudio.PyAudio() stream = p.open(format=self.FORMAT, channels=self.CHANNELS, rate=self.RATE, input=True, frames_per_buffer=self.CHUNK) count_small = 0 count_loop = 0 end_flag = 0 begin = time.time() overtime_flag = 0 while True: final = time.time() elapse = final - begin if elapse >= self.WAIT_TIME: overtime_flag = 1 break data_check = stream.read(self.CHUNK) audio_data = np.frombuffer(data_check, dtype=np.short) temp = np.max(audio_data) if temp > self.VOLUME: print("开始录音: ", temp) frames = self._frames frames.append(data_check) while True: data_record = stream.read(self.CHUNK) frames.append(data_record) audio_data = np.frombuffer(data_record, dtype=np.short) count_one_loop = np.sum(audio_data > self.VOLUME / 2) if count_one_loop < self.CHUNK / 2: count_small = count_small + 1 if count_small > self.GAP: print("录音结束") end_flag = 1 break else: count_small = 0 self.GAP = self.GAP + 0.1 count_loop = count_loop + 1 if count_loop > 10000: break if end_flag == 1: break stream.stop_stream() stream.close() p.terminate() return overtime_flag def __save(self, filename): p = pyaudio.PyAudio() if not filename.endswith(".wav"): filename = filename + ".wav" wf = wave.open(filename, 'wb') wf.setsampwidth(2) wf.setnchannels(self.CHANNELS) wf.setframerate(self.RATE) wf.writeframes(b''.join(self._frames)) wf.close() def __obtain_vol(self, vol): vl = vol volume_system = 100 if 10 < vl <= 20: volume_system = 200 if 20 <= vl < 40: volume_system = 500 if 40 <= vl < 60: volume_system = 700 if 60 <= vl < 80: volume_system = 1000 if 80 <= vl < 90: volume_system = 1600 if 90 <= vl: volume_system = 1800 self.VOLUME = volume_system def run_thread(self, volume): print("音量:", volume) self.__obtain_vol(volume) flag_asr = 0 model_param = [] model_name = [] model_param_str = '' model_name_str = '' model_op_str = '' err_message = '' model_op = [0] overtime_flag = self.__recording() # 录音结束, 开始识别 if overtime_flag == 0: if "asr" not in os.getcwd(): os.chdir("pyScripts/asr") self.__save("command.wav") begin = time.time() subprocess.run( "decoder_main.exe --chunk_size 16 --wav_path command.wav --model_path final.zip --dict_path words.txt --result result.txt", shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) end = time.time() print("识别时间:", end - begin) #修改易错词 with open('result.txt', encoding='utf-8') as f: content = f.read().strip() print(content) err_dict = {"武": '五', "酒": '九', "幺": "一", "山式": "三十", "山石": "三十", "高木": "高五", "围角": "为九", "士": "十", "一致": "移至", "伍": "五", "为期": "为七", "闪色": "散射"} for i in err_dict.keys(): if i in content: content = content.replace(i, err_dict[i]) content = cn2an.transform(content, "cn2an") print("识别结果:", content) # 判断是否选择了模型(某号或某个模型) flag_asr = file_operation(content, flag_asr) if flag_asr == 0: model_name, flag_asr = choose_model(content, flag_asr) # 如果选择了模型,则进行模型求解识别和CAD操作识别, 目前CAD只能识别一种操作 if flag_asr == 100: content = cn2an.transform(content, "cn2an") model_op = Operator(content) model_param, flag_asr, err_message = Move(content, flag_asr) if flag_asr == 100: model_param, flag_asr, err_message = Rotation(content, flag_asr) if flag_asr == 100: model_param, flag_asr, err_message = Mirror(content, flag_asr) # 如果选择的模型大于1个,则进行模型求和求差等多模型CAD交互操作识别 if len(model_name) > 1: flag_asr = Summation(content, flag_asr) if flag_asr == 100: flag_asr = Difference(content, flag_asr) if flag_asr == 100: flag_asr = Intersection(content, flag_asr) # 如果没有选择模型,则进行模型创建以及生成网格识别,同时识别是否对生成的模型进行散射等求解操作,目前只能生成一个模型 if flag_asr == 0: err_dict = {"-": " ", "块": "宽", "凹": "高", "常": "长", "花": "宽", "搞": "高", "矿": "宽", "超": "长", "匡": "宽", "昂": "长", "半斤": "半径", "伴君": "半径", "半军": "半径", "搬进": "半径", "阿维": "高为", "散烁": "散射", "反射": "散射", "散车": "散射"} for i in err_dict.keys(): if i in content: content = content.replace(i, err_dict[i]) model_param, flag_asr, model_op = Cube(content, model_param, flag_asr) if flag_asr == 0: model_param, flag_asr, model_op = Cylinder(content, model_param, flag_asr) if flag_asr == 0: model_param, flag_asr, model_op = Sphere(content, model_param, flag_asr) if flag_asr == 0: model_param, flag_asr, model_op = Cone(content, model_param, flag_asr) if flag_asr == 0: flag_asr = SurfaceMesh(content, flag_asr) flag_asr = VolumeMesh(content, flag_asr) flag_asr = import_mesh(content, flag_asr) flag_asr = output_mesh(content, flag_asr) # 转换list至byte str, 方便传参 for i in model_param: temp = i model_param_str = model_param_str + temp + ',' model_param_str = list(model_param_str) if model_param_str: model_param_str.pop(-1) model_param_str = ''.join(model_param_str) model_param_str = '[' + model_param_str + ']' model_param_str = bytes(model_param_str, encoding='utf-8') for i in model_name: temp = i model_name_str = model_name_str + temp + ',' model_name_str = list(model_name_str) if model_name_str: model_name_str.pop(-1) model_name_str = ''.join(model_name_str) model_name_str = '[' + model_name_str + ']' model_name_str = bytes(model_name_str, encoding='utf-8') for i in model_op: temp = str(i) model_op_str = model_op_str + temp + ',' model_op_str = list(model_op_str) print(model_op_str) if model_op_str: model_op_str.pop(-1) model_op_str = ''.join(model_op_str) model_op_str = '[' + model_op_str + ']' model_op_str = bytes(model_op_str, encoding='utf-8') if err_message: err_message = bytes(err_message, encoding='utf-8') print(flag_asr, model_param_str, model_name_str, model_op_str, err_message) # model_name为选择的模型名称,bytes str; # model_param_str为模型参数,bytes str; # model_op为模型操作,bytes str; # flag_asr为操作类型, int # err_message为错误信息, bytes str mw.voiceControlASR(flag_asr, model_param_str, model_name_str, model_op_str, err_message) else: mw.voiceControlASR(flag_asr, model_param_str, model_name_str, model_op_str, err_message)