using System; using System.IO; using Vosk; using System.Text.Json; using NAudio.Wave; using Avalonia.Controls; using Avalonia.Threading; namespace VisionAsist.Models; public class TrigerCore { private WaveInEvent? _waveIn; private Model? _model; private VoskRecognizer? _rec; private readonly object _voskLock = new(); public string RecognizedText { get; private set; } = ""; public TrigerCore() { string VoskPath = Path.Combine(AppContext.BaseDirectory, "models/Vosk/"); if (!Directory.Exists(VoskPath)) throw new DirectoryNotFoundException($"Модель не найдена по пути: {VoskPath}"); _model = new Model(VoskPath); _rec = new VoskRecognizer(_model, 16000.0f); } public void StartRecording() { if (_waveIn != null || _rec == null) return; _waveIn = new WaveInEvent { WaveFormat = new WaveFormat(16000, 1) }; _waveIn.DataAvailable += OnDataAvailable; _waveIn.StartRecording(); } public void StopRecording() { _waveIn?.StopRecording(); _waveIn?.Dispose(); _waveIn = null; } public event Action? OnRecognized; private void OnDataAvailable(object? sender, WaveInEventArgs e) { lock (_voskLock) { if (_rec != null && _rec.AcceptWaveform(e.Buffer, e.BytesRecorded)) { var json = _rec.Result(); using var doc = JsonDocument.Parse(json); var result = doc.RootElement.GetProperty("text").GetString(); if (!string.IsNullOrWhiteSpace(result)) { RecognizedText += result + " "; OnRecognized?.Invoke(result); // уведомляем подписчиков } } } } protected void Stop() { StopRecording(); _rec?.Dispose(); _model?.Dispose(); } }