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}")
