import json
import os
import struct
import time
import pvporcupine
import simpleaudio as sa
import vosk
from pvrecorder import PvRecorder
import config
import tts
from llm_models.mini_4o_model import ModelClient
import noisereduce as nr

# some consts
CDIR = os.getcwd()

# PORCUPINE
porcupine = pvporcupine.create(
    access_key=config.PICOVOICE_TOKEN,
    keyword_paths=['Sonya_en_windows_v3_0_0.ppn'],
    sensitivities=[1]
)
# print(pvporcupine.KEYWORDS)

# VOSK
model = vosk.Model("model_small")
samplerate = 16000
device = config.MICROPHONE_INDEX
kaldi_rec = vosk.KaldiRecognizer(model, samplerate)

client = ModelClient()


def play(phrase, wait_done=True):
    global recorder
    filename = f"{CDIR}\\sound\\"

    if phrase == "greet":
        filename += f"start.wav"
    if phrase == "cancel":
        filename += f"cancel.wav"

    if wait_done:
        recorder.stop()

    wave_obj = sa.WaveObject.from_wave_file(filename)
    play_obj = wave_obj.play()

    if wait_done:
        play_obj.wait_done()
        # time.sleep((len(wave_obj.audio_data) / wave_obj.sample_rate) + 0.5)
        # print("END")
        # time.sleep(0.5)
        recorder.start()


def va_respond(voice: str):
    if voice:
        print(f"Распознано: {voice}")

        response_generator = client.get_response(
            message=voice,
            history=[],
            sys_prompt="Ты голосовой ассистент"
        )

        full_response = []  # Список для хранения частей ответа
        last = ''

        for response in response_generator:
            part = response.replace(last, '')
            print(part, end='', flush=True)
            full_response.append(part)  # Добавляем часть ответа в список
            last = response

        print()

        # Объединяем все части в одну строку
        complete_response = ''.join(full_response)
        tts.va_speak(complete_response)
        return True

    return False


recorder = PvRecorder(device_index=config.MICROPHONE_INDEX, frame_length=porcupine.frame_length)
recorder.start()
print('Using device: %s' % recorder.selected_device)

print(f"Sonya (v1.0) к твоим услугам ...")

ltc = time.time() - 1000

listening = False
while True:
    try:
        pcm = recorder.read()
        keyword_index = porcupine.process(pcm)

        # Для улучшения звука с микрофона:
        # Применение усиления к каждому PCM образцу
        # pcm = [int(sample * 2) for sample in pcm]
        # Устранение фонового шума
        # pcm = nr.reduce_noise(y=pcm, sr=samplerate)

        if keyword_index >= 0:
            recorder.stop()
            play("greet", True)
            print("Yes, sir.")
            recorder.start()
            ltc = time.time()
            listening = True

        while time.time() - ltc <= 10:

            pcm = recorder.read()
            sp = struct.pack("h" * len(pcm), *pcm)

            if kaldi_rec.AcceptWaveform(sp):
                if va_respond(json.loads(kaldi_rec.Result())["text"]):
                    ltc = time.time()
                break

        if listening and time.time() - ltc > 10:
            play("cancel", True)
            listening = False

    except KeyboardInterrupt:
        print("Программа завершена пользователем.")
        break  # Выход из цикла
    except Exception as err:
        print(f"Unexpected {err=}, {type(err)=}")
        raise

import time

import sounddevice as sd
import torch

language = 'ru'
model_id = 'ru_v3'  # ru_v3 / v4_ru
sample_rate = 48000  # 48000
speaker = 'baya'  # aidar, baya, kseniya, xenia, random
put_accent = True
put_yo = True
device = torch.device('cuda')  # cpu или gpu
text = "Хауди Хо, друзья!!!"

model, _ = torch.hub.load(repo_or_dir='snakers4/silero-models',
                          model='silero_tts',
                          language=language,
                          speaker=model_id)
model.to(device)


# воспроизводим
def va_speak(what: str):
    # audio = model.apply_tts(text=what + "..",
    #                         speaker=speaker,
    #                         sample_rate=sample_rate,
    #                         put_accent=put_accent,
    #                         put_yo=put_yo)

    audio = model.apply_tts(text=what,
                            speaker=speaker,
                            sample_rate=sample_rate)

    sd.play(audio, sample_rate * 1.05)
    time.sleep((len(audio) / sample_rate) + 0.5)
    sd.stop()

# sd.play(audio, sample_rate)
# time.sleep(len(audio) / sample_rate)
# sd.stop()

Мне надо замерять время на разных этапах, распознования речи, ответ нейронной сети, генерация аудио