diff --git a/_stt.py b/_stt.py index efa903d..870cc09 100644 --- a/_stt.py +++ b/_stt.py @@ -13,6 +13,7 @@ model, decoder, utils = torch.hub.load(repo_or_dir='snakers4/silero-models', (read_batch, split_into_batches, read_audio, prepare_model_input) = utils + def callback(_r, audio): try: # CONVERT raw wav data to NumPy array diff --git a/pv_custom_keywords/A-Knocks_en_windows_v2_1_0.ppn b/pv_custom_keywords/A-Knocks_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..42a6564 Binary files /dev/null and b/pv_custom_keywords/A-Knocks_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/Can-finger_en_windows_v2_1_0.ppn b/pv_custom_keywords/Can-finger_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..f9ec755 Binary files /dev/null and b/pv_custom_keywords/Can-finger_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/Conceal_en_windows_v2_1_0.ppn b/pv_custom_keywords/Conceal_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..bf11a66 Binary files /dev/null and b/pv_custom_keywords/Conceal_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/Disillusion_en_windows_v2_1_0.ppn b/pv_custom_keywords/Disillusion_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..4e9bbd6 Binary files /dev/null and b/pv_custom_keywords/Disillusion_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/Expellee-aramus_en_windows_v2_1_0.ppn b/pv_custom_keywords/Expellee-aramus_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..58d4a3d Binary files /dev/null and b/pv_custom_keywords/Expellee-aramus_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/In-St-Your_en_windows_v2_1_0.ppn b/pv_custom_keywords/In-St-Your_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..f4a1980 Binary files /dev/null and b/pv_custom_keywords/In-St-Your_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/Lady-also_en_windows_v2_1_0.ppn b/pv_custom_keywords/Lady-also_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..b2d8aa1 Binary files /dev/null and b/pv_custom_keywords/Lady-also_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/Lumas_en_windows_v2_1_0.ppn b/pv_custom_keywords/Lumas_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..c3977d2 Binary files /dev/null and b/pv_custom_keywords/Lumas_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/Proud-to-go_en_windows_v2_1_0.ppn b/pv_custom_keywords/Proud-to-go_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..cab1453 Binary files /dev/null and b/pv_custom_keywords/Proud-to-go_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/R-Vail-leo_en_windows_v2_1_0.ppn b/pv_custom_keywords/R-Vail-leo_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..7ade6b0 Binary files /dev/null and b/pv_custom_keywords/R-Vail-leo_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/The-pool-so_en_windows_v2_1_0.ppn b/pv_custom_keywords/The-pool-so_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..f44fcfb Binary files /dev/null and b/pv_custom_keywords/The-pool-so_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/aloha-mora_en_windows_v2_1_0.ppn b/pv_custom_keywords/aloha-mora_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..19945ec Binary files /dev/null and b/pv_custom_keywords/aloha-mora_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/terrifical-status_en_windows_v2_1_0.ppn b/pv_custom_keywords/terrifical-status_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..0ed6f7b Binary files /dev/null and b/pv_custom_keywords/terrifical-status_en_windows_v2_1_0.ppn differ diff --git a/stt.py b/stt.py index 90631a0..e4aa125 100644 --- a/stt.py +++ b/stt.py @@ -6,7 +6,7 @@ import json model = vosk.Model("model_small") samplerate = 16000 -device = 1 +device = 2 q = queue.Queue() diff --git a/stt_google.py b/stt_google.py new file mode 100644 index 0000000..c1413d4 --- /dev/null +++ b/stt_google.py @@ -0,0 +1,34 @@ +import speech_recognition as sr +from rich import print +from utils.benchmark import Benchmark + +# import speech_recognition as sr +# for index, name in enumerate(sr.Microphone.list_microphone_names()): +# print("Microphone with name \"{1}\" found for `Microphone(device_index={0})`".format(index, name)) +# exit(1) + +# obtain audio from the microphone +r = sr.Recognizer() +r.pause_threshold = 0.5 +with sr.Microphone(device_index=2) as source: + print("Say something!") + audio = r.listen(source) + +bench = Benchmark() + +# recognize speech using Google Speech Recognition +try: + # for testing purposes, we're just using the default API key + # to use another API key, use `r.recognize_google(audio, key="GOOGLE_SPEECH_RECOGNITION_API_KEY")` + # instead of `r.recognize_google(audio)`\ + while True: + bench.start() + recognized_text = r.recognize_google(audio) + end_time = bench.end() + print(f"[light_sea_green]Google Speech Recognition thinks you said[/]: [dodger_blue1]{recognized_text}[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + print() +except sr.UnknownValueError: + print("Google Speech Recognition could not understand audio") +except sr.RequestError as e: + print("Could not request results from Google Speech Recognition service; {0}".format(e)) \ No newline at end of file diff --git a/stt_picovoice.py b/stt_picovoice.py new file mode 100644 index 0000000..f3fbf02 --- /dev/null +++ b/stt_picovoice.py @@ -0,0 +1,146 @@ +import time + +import pvporcupine +from pvrecorder import PvRecorder +from rich import print +from utils.benchmark import Benchmark +import keyboard +from utils.time import sleep + +porcupine = pvporcupine.create( + access_key='H2JhXpfLdGYG2wMqvc61tipo0uKZQvwkEfA26CAQQe5n1y7zfZGneQ==', + # keywords=['picovoice', 'bumblebee', 'aloha mora'], + keyword_paths=["./pv_custom_keywords/aloha-mora_en_windows_v2_1_0.ppn", + "./pv_custom_keywords/Expellee-aramus_en_windows_v2_1_0.ppn", + "./pv_custom_keywords/Lumas_en_windows_v2_1_0.ppn", + + "./pv_custom_keywords/Proud-to-go_en_windows_v2_1_0.ppn", + "./pv_custom_keywords/A-Knocks_en_windows_v2_1_0.ppn", + "./pv_custom_keywords/In-St-Your_en_windows_v2_1_0.ppn", + + "./pv_custom_keywords/The-pool-so_en_windows_v2_1_0.ppn", + "./pv_custom_keywords/Lady-also_en_windows_v2_1_0.ppn", + "./pv_custom_keywords/R-Vail-leo_en_windows_v2_1_0.ppn", + + "./pv_custom_keywords/Conceal_en_windows_v2_1_0.ppn", + "./pv_custom_keywords/terrifical-status_en_windows_v2_1_0.ppn", + "./pv_custom_keywords/Disillusion_en_windows_v2_1_0.ppn", + + "./pv_custom_keywords/Can-finger_en_windows_v2_1_0.ppn" + ], + sensitivities=[1] * 13 +) + +# `-1` is the default input audio device. +recorder = PvRecorder(device_index=0, frame_length=porcupine.frame_length) +recorder.start() +print('Using device: %s' % recorder.selected_device) + +bench = Benchmark() + +while True: + bench.start() + pcm = recorder.read() + keyword_index = porcupine.process(pcm) + end_time = bench.end() + + if keyword_index == 0: + print("[gold1]Aloha mora[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("f") + elif keyword_index == 1: + print("[bright_red]Expelliarmus[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("F1") + sleep(0.05) + keyboard.press_and_release("2") + elif keyword_index == 2: + print("[gold1]Lumos[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("F1") + sleep(0.05) + keyboard.press_and_release("1") + + elif keyword_index == 3: + print("[dodger_blue2]Protego[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press("q") + sleep(1/2) + keyboard.release("q") + + elif keyword_index == 4: + print("[gold1]Nox[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("F1") + sleep(0.05) + keyboard.press_and_release("1") + + elif keyword_index == 5: + print("[bright_red]Incendio[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("F2") + sleep(0.05) + keyboard.press_and_release("1") + + elif keyword_index == 6: + print("[dodger_blue2]Depulso[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("F1") + sleep(0.05) + keyboard.press_and_release("4") + + elif keyword_index == 7: + print("[gold1]Levioso[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("F1") + sleep(0.05) + keyboard.press_and_release("3") + + elif keyword_index == 8: + print("[dodger_blue2]Revelio[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("R") + + elif keyword_index == 9: + print("[dodger_blue2]Accio[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("F2") + sleep(0.05) + keyboard.press_and_release("3") + + elif keyword_index == 10: + print("[bright_red]Petrificus Totalus[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("f") + + elif keyword_index == 11: + print("[dodger_blue2]Disillusionment Spell[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("F2") + sleep(0.05) + keyboard.press_and_release("2") + + elif keyword_index == 12: + print("[bright_red]Confringo Spell[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("F2") + sleep(0.05) + keyboard.press_and_release("4") + + #if keyword_index >= 0: + # break + +porcupine.delete() diff --git a/stt_vosk.py b/stt_vosk.py new file mode 100644 index 0000000..eef8f63 --- /dev/null +++ b/stt_vosk.py @@ -0,0 +1,50 @@ +import vosk +import queue +import json +import sys +import sounddevice as sd +from rich import print +from utils.benchmark import Benchmark + +# import speech_recognition as sr +# for index, name in enumerate(sr.Microphone.list_microphone_names()): +# print("Microphone with name \"{1}\" found for `Microphone(device_index={0})`".format(index, name)) +# exit(1) + +bench = Benchmark() + + +def va_respond(voice: str): + print(f"[light_sea_green]Vosk thinks you said[/]: [dodger_blue1]{voice}[/]") + + +model = vosk.Model("model_small") +samplerate = 16000 +device = 2 + +q = queue.Queue() + + +def q_callback(indata, frames, time, status): + if status: + print(status, file=sys.stderr) + q.put(bytes(indata)) + + +def va_listen(callback): + with sd.RawInputStream(samplerate=samplerate, blocksize=8000, device=device, dtype='int16', + channels=1, callback=q_callback): + + rec = vosk.KaldiRecognizer(model, samplerate) + while True: + bench.start() + data = q.get() + if rec.AcceptWaveform(data): + callback(json.loads(rec.Result())["text"]) + end_time = bench.end() + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + #else: + # print(rec.PartialResult()) + +# начать прослушивание команд +va_listen(va_respond) \ No newline at end of file diff --git a/utils/benchmark.py b/utils/benchmark.py new file mode 100644 index 0000000..008ab36 --- /dev/null +++ b/utils/benchmark.py @@ -0,0 +1,27 @@ +import time + + +class Benchmark: + __marks = {} # {0: [result, point1, point2, ...]} + + def start(self, point_name=None) -> float: + if point_name is None: + point_name = 0 + + self.__marks[point_name] = [0, ((time.time_ns() / 1000000) / 1000)%60, 0] + # print(f"start: {self.__marks}") + + return self.__marks[point_name] + + def end(self, point_name=None) -> tuple: + if point_name is None: + point_name = 0 + + # print(self.__marks) + self.__marks[point_name][2] = ((time.time_ns() / 1000000) / 1000)%60 + self.__marks[point_name][0] = self.__marks[point_name][2] - self.__marks[point_name][1] + + return self.__marks[point_name][0], f"{int(1E3 * self.__marks[point_name][0])}ms" + + def clear_points(self): + self.__marks = {} diff --git a/utils/time.py b/utils/time.py new file mode 100644 index 0000000..a93bde0 --- /dev/null +++ b/utils/time.py @@ -0,0 +1,15 @@ +import time + + +def sleep(duration, get_now=time.perf_counter): + """ + Custom sleep function that works more accurate then time.sleep does. + Taken from: https://stackoverflow.com/a/60185893/3684575 + :param duration: Duration to sleep (in seconds). + :param get_now: Function to retrieve current time (time.perf_counter by default) + :return: + """ + now = get_now() + end = now + duration + while now < end: + now = get_now()