namespace VoiceCat.App.Notifications; /// /// Combines the sound pool and the speech announcer behind the user's . /// MainForm calls / from inside its existing event /// handlers (which already resolve nicknames and channel membership), so this type only owns the /// "should I, and how" policy — not the event routing. /// public sealed class EventFeedback : IDisposable { private readonly SoundPlayerPool _sounds = new(); private readonly SpeechAnnouncer _speech = new(); public FeedbackSettings Settings { get; set; } public EventFeedback(FeedbackSettings settings) => Settings = settings; /// True when speech is both enabled and actually available on this machine. public bool SpeechAvailable => _speech.Available; public void PlaySound(SoundEvent ev) { if (!Settings.Sounds || Settings.Volume <= 0f) return; // The two opt-in categories are gated by their own flags. if ((ev is SoundEvent.VaStart or SoundEvent.VaStop) && !Settings.SelfTalkSounds) return; if (ev is SoundEvent.Ptt && !Settings.PttSound) return; _sounds.Play(ev); } /// Announce when spoken feedback is enabled. public void Speak(string text) { if (!Settings.Speech) return; _speech.Speak(text); } public void Dispose() { _sounds.Dispose(); _speech.Dispose(); } }