modify project structure and add download_models.py
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
import json
|
||||
import os
|
||||
import struct
|
||||
import time
|
||||
|
||||
import noisereduce as nr
|
||||
import pvporcupine
|
||||
import vosk
|
||||
import yaml
|
||||
from fuzzywuzzy import fuzz
|
||||
from pvrecorder import PvRecorder
|
||||
|
||||
from data import config
|
||||
from utils import download_models, execute_cmd, play
|
||||
|
||||
|
||||
class Jarvis:
|
||||
def __init__(self):
|
||||
download_models.install_vosk_model()
|
||||
self.recorder = None
|
||||
self.CDIR = os.getcwd()
|
||||
self.VA_CMD_LIST = yaml.safe_load(open('data/commands.yaml', encoding='utf8'))
|
||||
self.porcupine = pvporcupine.create(
|
||||
access_key=config.PICOVOICE_TOKEN,
|
||||
keywords=['jarvis'],
|
||||
sensitivities=[1]
|
||||
)
|
||||
self.kaldi_rec = vosk.KaldiRecognizer(vosk.Model("data/model_small"), 16000)
|
||||
|
||||
def main(self):
|
||||
self.recorder = PvRecorder(
|
||||
device_index=config.MICROPHONE_INDEX,
|
||||
frame_length=self.porcupine.frame_length
|
||||
)
|
||||
self.recorder.start()
|
||||
self.play("run")
|
||||
time.sleep(0.5)
|
||||
ltc = time.time() - 1000
|
||||
while True:
|
||||
try:
|
||||
pcm = self.recorder.read()
|
||||
reduced_audio = nr.reduce_noise(
|
||||
y=pcm,
|
||||
sr=16000,
|
||||
prop_decrease=0.6
|
||||
)
|
||||
if self.porcupine.process(reduced_audio) >= 0:
|
||||
self.recorder.stop()
|
||||
self.play("greet", True)
|
||||
self.recorder.start()
|
||||
ltc = time.time()
|
||||
while time.time() - ltc <= 10:
|
||||
pcm = self.recorder.read()
|
||||
sp = struct.pack("h" * len(pcm), *pcm)
|
||||
if self.kaldi_rec.AcceptWaveform(sp):
|
||||
if self.va_respond(json.loads(self.kaldi_rec.Result())["text"]):
|
||||
ltc = time.time()
|
||||
break
|
||||
except Exception as err:
|
||||
print(f"Unexpected {err=}, {type(err)=}")
|
||||
raise
|
||||
|
||||
def va_respond(self, voice: str):
|
||||
print(f"Распознано: {voice}")
|
||||
for x in config.VA_ALIAS + config.VA_TBR:
|
||||
voice = voice.replace(x, "").strip()
|
||||
rc = {'cmd': '', 'percent': 0}
|
||||
for c, v in self.VA_CMD_LIST.items():
|
||||
for x in v:
|
||||
vrt = fuzz.partial_ratio(voice.lower(), x.lower())
|
||||
if vrt > rc['percent']:
|
||||
rc['cmd'] = c
|
||||
rc['percent'] = vrt
|
||||
if len(rc['cmd'].strip()) <= 0:
|
||||
return False
|
||||
elif rc['percent'] < 70 or rc['cmd'] not in self.VA_CMD_LIST.keys():
|
||||
self.play("not_found")
|
||||
time.sleep(1)
|
||||
return False
|
||||
else:
|
||||
execute_cmd.execute_cmd(self, rc['cmd'])
|
||||
return True
|
||||
|
||||
def play(self, phrase, wait_done=True):
|
||||
play.play(self, phrase, wait_done)
|
||||
Reference in New Issue
Block a user