69 lines
2.5 KiB
Python
69 lines
2.5 KiB
Python
import sounddevice as sd
|
|
from vosk import Model, KaldiRecognizer
|
|
import json
|
|
import sys
|
|
import numpy as np
|
|
|
|
# 1. Настройки
|
|
MODEL_PATH = r"D:\Work\Software_Development\Projects\vosk\vosk-model-small-ru-0.22"
|
|
# Попробуйте 48000, если снова будет ошибка -9997
|
|
SAMPLERATE = 48000
|
|
|
|
model = Model(MODEL_PATH)
|
|
|
|
# 2. Поиск ID (Potato использует имена B1 и B2)
|
|
def find_devices():
|
|
id_gm = None # VoiceMeeter B1
|
|
id_pcs = None # VoiceMeeter B2
|
|
for i, d in enumerate(sd.query_devices()):
|
|
if "Voicemeeter Out B1" in d['name']: id_gm = i
|
|
if "Voicemeeter Out B2" in d['name']: id_pcs = i
|
|
return id_gm, id_pcs
|
|
|
|
id_gm, id_pcs = find_devices()
|
|
|
|
if id_gm is None or id_pcs is None:
|
|
print("Ошибка: Устройства B1 или B2 не найдены!")
|
|
sys.exit()
|
|
|
|
# 3. Распознаватели
|
|
rec_gm = KaldiRecognizer(model, SAMPLERATE)
|
|
rec_pcs = KaldiRecognizer(model, SAMPLERATE)
|
|
|
|
def create_callback(rec, role):
|
|
def callback(indata, frames, time, status):
|
|
# Если звук тихий, не мучаем Vosk
|
|
if np.max(np.abs(indata)) < 0.001:
|
|
return
|
|
|
|
if rec.AcceptWaveform(bytes(indata)):
|
|
text = json.loads(rec.Result())['text']
|
|
if text:
|
|
print(f"[{role}]: {text}")
|
|
'''else:
|
|
# Частичный результат для динамики
|
|
partial = json.loads(rec.PartialResult())['partial']
|
|
if partial:
|
|
# Используем \b для удаления "слышит" при финальном результате
|
|
sys.stdout.write(f"\r[{role} говорит...]: {partial}".ljust(60))
|
|
sys.stdout.flush()'''
|
|
return callback
|
|
|
|
# 4. Параллельный запуск
|
|
print(f"--- ЗАПУСК ТРАНСКРИБАЦИИ TTRPG ---")
|
|
print(f"GM (Микрофон B1) ID: {id_gm}")
|
|
print(f"PCs (Система B2) ID: {id_pcs}")
|
|
|
|
try:
|
|
with sd.RawInputStream(samplerate=SAMPLERATE, blocksize=8000, device=id_gm,
|
|
dtype='int16', channels=1, callback=create_callback(rec_gm, "GM")), \
|
|
sd.RawInputStream(samplerate=SAMPLERATE, blocksize=8000, device=id_pcs,
|
|
dtype='int16', channels=1, callback=create_callback(rec_pcs, "PCs")):
|
|
|
|
print("\nСистема готова. GM может начинать сессию, PCs могут перебивать.")
|
|
while True:
|
|
sd.sleep(1000)
|
|
|
|
except Exception as e:
|
|
print(f"\nОшибка: {e}")
|