modify project structure and add download_models.py

This commit is contained in:
2024-05-01 13:35:00 +07:00
parent 8504126d4a
commit a2375e6daf
19 changed files with 36 additions and 9 deletions
+85
View File
@@ -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)