Initial commit
This commit is contained in:
+135
@@ -0,0 +1,135 @@
|
||||
# app/core/vad.py
|
||||
from fastapi import Request
|
||||
import os
|
||||
from app.core.config import get_settings
|
||||
from typing import Tuple, Dict, Any, Optional
|
||||
import logging
|
||||
from app.core.status import status_tracker, SystemStatus # Добавлено
|
||||
from app.core.history import add_recognized_phrase
|
||||
logger = logging.getLogger('VADApp')
|
||||
|
||||
def get_vad_instance(request: Request):
|
||||
"""Получение экземпляра VAD из состояния приложения"""
|
||||
return getattr(request.app.state, 'vad_instance', None)
|
||||
|
||||
def get_stt_instance(request: Request):
|
||||
"""Получение экземпляра STT из состояния приложения"""
|
||||
return getattr(request.app.state, 'stt_instance', None)
|
||||
|
||||
def get_commands(request: Request):
|
||||
"""Получение команд из состояния приложения"""
|
||||
return getattr(request.app.state, 'commands', None)
|
||||
|
||||
def init_vad_and_stt(request: Request = None) -> Tuple[Any, Any, Dict[str, Any], Any]:
|
||||
"""Инициализация VAD и STT"""
|
||||
logger.debug("Инициализация VAD и STT")
|
||||
status_tracker.set_status(SystemStatus.INITIALIZATION) # Добавлено
|
||||
try:
|
||||
# Импортируем здесь, чтобы избежать циклических импортов
|
||||
from vad_core import VADPolling
|
||||
from vosk_local_STT import VoskSTT # Исправлено с vosk_stt на vosk_local_STT
|
||||
from commands import handle_command
|
||||
from session_manager import SessionManager
|
||||
from volume import set_volume
|
||||
|
||||
config = get_settings()
|
||||
commands = {}
|
||||
|
||||
# Инициализация громкости аудиоустройств
|
||||
try:
|
||||
# Устанавливаем громкость для устройства воспроизведения
|
||||
set_volume(config.audio_settings.playback_device, config.audio_settings.playback_volume, mixer_type='Playback')
|
||||
# Устанавливаем громкость для устройства записи
|
||||
set_volume(config.audio_settings.capture_device, config.audio_settings.capture_volume, mixer_type='Capture')
|
||||
logger.info(f"Громкость устройств инициализирована: воспроизведение={config.audio_settings.playback_volume}%, запись={config.audio_settings.capture_volume}%")
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка при инициализации громкости: {e}")
|
||||
|
||||
# Загружаем команды из файла
|
||||
if config.commands.commands_file and os.path.exists(config.commands.commands_file):
|
||||
from ruamel.yaml import YAML
|
||||
yaml = YAML()
|
||||
with open(config.commands.commands_file, 'r', encoding='utf-8') as f:
|
||||
commands = yaml.load(f) or {}
|
||||
|
||||
# Инициализируем SessionManager
|
||||
session_manager = SessionManager(config.session.session_timeout_seconds)
|
||||
logger.info(f"SessionManager инициализирован с таймаутом {config.session.session_timeout_seconds} секунд")
|
||||
|
||||
# Инициализируем STT
|
||||
stt_instance = VoskSTT(
|
||||
model_path=config.stt.model_path,
|
||||
commands_file=config.commands.commands_file,
|
||||
sample_rate=config.vad.sample_rate
|
||||
)
|
||||
|
||||
# Функция обработки распознанной речи
|
||||
def process_speech(audio_data, sample_rate):
|
||||
try:
|
||||
status_tracker.set_status(SystemStatus.RECOGNITION) # Добавлено
|
||||
recognized = stt_instance.recognize(audio_data)
|
||||
if recognized:
|
||||
logger.info(f"Команда распознана: {recognized}")
|
||||
status_tracker.set_status(SystemStatus.COMMAND_PROCESSING) # Добавлено
|
||||
action = handle_command(recognized, commands, session_manager)
|
||||
status_tracker.set_status(SystemStatus.RESPONSE) # Добавлено (предполагая, что здесь происходит ответ; если нет, удалите)
|
||||
|
||||
# Добавляем распознанную фразу в историю
|
||||
|
||||
if action:
|
||||
add_recognized_phrase(recognized, action=action)
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка обработки речи: {e}")
|
||||
status_tracker.set_status(SystemStatus.LISTENING) # Добавлено (возврат к прослушиванию)
|
||||
|
||||
# Инициализируем VAD
|
||||
vad_config = config.vad.dict()
|
||||
vad_config['polling_interval_ms'] = config.system.polling_interval_ms
|
||||
vad_config['history_maxlen'] = config.system.history_maxlen
|
||||
vad_instance = VADPolling(vad_config, on_speech_end_callback=process_speech)
|
||||
|
||||
logger.info("VAD и STT инициализированы")
|
||||
status_tracker.set_status(SystemStatus.LISTENING) # Добавлено
|
||||
return vad_instance, stt_instance, commands, session_manager
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка инициализации VAD/STT: {e}", exc_info=True)
|
||||
raise
|
||||
|
||||
def cleanup_vad_and_stt(vad_instance, stt_instance):
|
||||
"""Завершение работы VAD и STT"""
|
||||
logger.debug("Завершение работы VAD и STT")
|
||||
try:
|
||||
if vad_instance:
|
||||
logger.info("Завершаем VAD...")
|
||||
vad_instance.close()
|
||||
if stt_instance:
|
||||
logger.info("Завершаем STT...")
|
||||
stt_instance = None
|
||||
logger.info("VAD и STT завершены")
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка завершения VAD/STT: {e}")
|
||||
|
||||
def restart_vad_and_stt(request: Request):
|
||||
"""Перезапуск VAD и STT с новыми настройками"""
|
||||
logger.info("Перезапуск VAD и STT")
|
||||
status_tracker.set_status(SystemStatus.INITIALIZATION) # Добавлено
|
||||
try:
|
||||
# Завершаем текущие экземпляры
|
||||
vad_instance = get_vad_instance(request)
|
||||
stt_instance = get_stt_instance(request)
|
||||
cleanup_vad_and_stt(vad_instance, stt_instance)
|
||||
|
||||
# Инициализируем новые экземпляры
|
||||
vad_instance, stt_instance, commands = init_vad_and_stt()
|
||||
|
||||
# Обновляем состояние приложения
|
||||
request.app.state.vad_instance = vad_instance
|
||||
request.app.state.stt_instance = stt_instance
|
||||
request.app.state.commands = commands
|
||||
|
||||
logger.info("VAD и STT перезапущены")
|
||||
status_tracker.set_status(SystemStatus.LISTENING) # Добавлено
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка перезапуска VAD/STT: {e}", exc_info=True)
|
||||
raise
|
||||
Reference in New Issue
Block a user