import webrtcvad
+from pprint import pprint
+
@contextmanager
def _pyaudio() -> Generator[PyAudio, None, None]:
p = PyAudio()
except:
pass
-def Silence(speaker, seconds):
- buf = bytes(speaker._frames_per_buffer)
- bufs = int((seconds)*speaker._rate/speaker._frames_per_buffer)
- for i in range(bufs):
- speaker.write(buf)
-
def PlayBack(pyaud, text, mic = None):
global config, last_time
decoder = MP3Decoder(req)
speaker = pyaud.open(output=True, format=paInt16, channels=decoder.num_channels, rate=decoder.sample_rate)
- Silence(speaker, 0.3)
+ pprint(speaker)
for chunk in decoder:
speaker.write(chunk)
last_time = time()
if mic:
- SkipSource(mic, elapsed + 0.5)
+ SkipSource(mic, elapsed + 0.2)
return elapsed
raise
except:
- pass
+ raise
else:
return 0
sz = int(mic._rate*frame)
sp = int(pause/frame)
- try:
-
- phrase = ""
- voice = False
+ phrase = ""
+ voice = False
- while not phrase:
- data = mic.read(sz)
- if len(data) == 0:
- break
- vd = vad.is_speech(data, mic._rate)
- if vd and not voice:
- voice = True
- if config["debug"]:
- print("+", end="")
+ while not phrase:
+ data = mic.read(sz)
+ if len(data) == 0:
+ break
+ vd = vad.is_speech(data, mic._rate)
+ if vd and not voice:
+ voice = True
+ if config["debug"]:
+ print("+", end="")
+ cnt = 0
+ if voice and not vd:
+ cnt = cnt + 1
+ if cnt > sp:
cnt = 0
- if voice and not vd:
- cnt = cnt + 1
- if cnt > sp:
- cnt = 0
- voice = False
- if config["debug"]:
- print("-")
- if voice:
- print("*",end="")
- await server.send(data)
- datatxt = await server.recv()
- data = json.loads(datatxt)
- try:
- phrase = data["text"]
- confidence = min(map(lambda x: x["conf"], data["result"]))
- except:
- pass
+ voice = False
+ if config["debug"]:
+ print("-")
+ if voice:
+ print("*",end="")
+ await server.send(data)
+ datatxt = await server.recv()
+ data = json.loads(datatxt)
+ try:
+ phrase = data["text"]
+ except:
+ pass
- last_time = time()
-
- return phrase, confidence
-
- except KeyboardInterrupt:
- raise
- except websockets.exceptions.ConnectionClosedError:
- raise
- except:
- return '',0
+ last_time = time()
+ return phrase
async def main_loop(uri):
global config, last_time
keyphrase = config["keyphrase"]
- confidence_treshold = config["confidence_treshold"]
rec_attempts = config["rec_attempts"]
commands = config["commands"]
with ExitStack() as audio_stack:
p = audio_stack.enter_context(_pyaudio())
+
s = audio_stack.enter_context(_pyaudio_open_stream(p,
format = paInt16,
channels = 1,
ws = await web_stack.enter_async_context(_polite_websocket(ws))
while True:
- phrase, confidence = await ListenPhrase(s, ws)
+ phrase = await ListenPhrase(s, ws)
if config["debug"]:
- print(phrase,confidence)
- if phrase == keyphrase and confidence>=confidence_treshold :
- PlayBack(p, "Я жду команду", mic=s)
+ print(phrase)
+ if phrase == keyphrase :
+ print("COMMAND!")
+ PlayBack(p, "Слушаю!", mic=s)
command = ""
for i in range(rec_attempts):
- phrase, confidence = await ListenPhrase(s, ws)
+ phrase = await ListenPhrase(s, ws)
if config["debug"]:
- print(phrase,confidence)
- if confidence > confidence_treshold:
- if (not commands) or (phrase in commands):
- if config["debug"]:
- print("Command: ", phrase)
- command = phrase
- RunCommand(command, p, s)
- break
- else:
- PlayBack(p, "Не знаю такой команды: "+phrase, mic=s)
+ print(phrase)
+ if (not commands) or (phrase in commands):
+ if config["debug"]:
+ print("Command: ", phrase)
+ command = phrase
+ RunCommand(command, p, s)
+ break
else:
- PlayBack(p, "Не поняла, слишком неразборчиво", mic=s)
+ PlayBack(p, "Не знаю такой команды: "+phrase, mic=s)
+ else:
+ PlayBack(p, "Не поняла, слишком неразборчиво", mic=s)
if not command:
PlayBack(p, "Так команду и не поняла...", mic=s)
except:
rec_attempts = 4
- try:
- confidence_treshold = float(config['vosk']['confidence_treshold'])
- except:
- confidence_treshold = 0.4
-
try:
vosk_server = config['vosk']['server']
except:
"asr_server": vosk_server,
"keyphrase": keyphrase,
"rec_attempts": rec_attempts,
- "confidence_treshold": confidence_treshold,
"tts_url": tts_url,
"tts_param": tts_param,
"api_attempts": api_attempts,
server = config['asr_server']
vad = webrtcvad.Vad(config['vad_mode'])
+last_time = time()
while True:
main_loop(f'ws://' + server))
except (Exception, KeyboardInterrupt) as e:
+ raise
loop.run_until_complete(
loop.shutdown_asyncgens())
if isinstance(e, KeyboardInterrupt):