import os import threading import time import sounddevice as sd import numpy as np def beep(duration=700, freq=640): # 生成蜂鸣声的时间序列 t = np.linspace(0, duration / 1000, int(44100 * duration / 1000), False) signal = 0.5 * np.sin(2 * np.pi * freq * t) # 播放蜂鸣声 sd.play(signal, samplerate=44100) sd.wait() class SpeakServer: thread = None # background thread that reads frames from camera engine = None __flag = threading.Event() # 用于暂停线程的标识 __flag.clear() # 设置为True __running = threading.Event() # 用于停止线程的标识 __running.set() # 将running设置为True __had_data = threading.Event() __had_data.clear() speak_list = [] is_pause = True BASE_SPEED = 50 MAX_SPEED = 100 speed = BASE_SPEED speed_set = BASE_SPEED speed_now = BASE_SPEED volume = 100 pitch = 10 def __new__(cls): if not cls.thread: # start background frame thread cls.thread = threading.Thread(target=cls._thread, daemon=True) cls.thread.start() return super().__new__(cls) def start(self): pass @staticmethod def add_speak(data): SpeakServer.speak_list.append(data) SpeakServer.__had_data.set() @classmethod def check_list(cls): if not cls.speak_list: return True else: return False @classmethod def wait_4_speak(cls): while not cls.check_list(): time.sleep(0.1) @staticmethod def speed_control(rate): SpeakServer.speed = rate @staticmethod def set_temp_speed(rate): try: SpeakServer.speed = rate SpeakServer.speed_now = rate except: return @staticmethod def volume_control(volume): SpeakServer.volume = volume @classmethod def _thread(cls): while SpeakServer.__running.is_set(): SpeakServer.__had_data.wait() while cls.speak_list: try: temp_speak = cls.speak_list[0] # 语速控制 if len(cls.speak_list) >= 2: speak_len = len("".join([str(s) for s in cls.speak_list])) if speak_len > 10: speak_speed = cls.BASE_SPEED + min(speak_len, 30) / 30 * (cls.MAX_SPEED - cls.BASE_SPEED) cls.set_temp_speed(speak_speed) else: if cls.speed_now != cls.speed_set: cls.speed_control(cls.speed_set) else: cls.speed_control(cls.speed_set) os.popen(f"ekho " f"-v Mandarin " f"-p {SpeakServer.pitch} " f"-a {SpeakServer.volume} " f"-s {SpeakServer.speed} " f"{temp_speak}").read() cls.speak_list.pop(0) except Exception as e: print('speak machine error:', e) time.sleep(0.1) SpeakServer.__had_data.clear() SpeakServer.thread = None @classmethod def wait(cls): cls.__flag.wait() @classmethod def pause(cls): if not cls.is_pause: cls.__flag.clear() # 设置为False, 让线程阻塞 cls.is_pause = True @classmethod def resume(cls): if cls.is_pause: cls.__flag.set() # 设置为True, 让线程停止阻塞 cls.is_pause = False @classmethod def stop(cls): return