LISHUZUOXUN_yangjiang/Speaker/_speak_base_linux.py

129 lines
3.7 KiB
Python
Raw Normal View History

2024-09-23 14:54:15 +08:00
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