using System.Media; namespace VoiceCat.App.Notifications; /// /// Plays short event cues from the app's sounds\ folder. Each WAV is loaded once into a /// cached (built into the Windows Desktop framework — no extra /// dependency). is non-blocking ( renders on a /// background thread). /// /// Note: exposes no gain control, so volume is honoured only as a mute /// gate (volume == 0 → silent). If finer control or reliable overlapping playback is needed /// later, swap this for NAudio. /// public sealed class SoundPlayerPool : IDisposable { private static readonly string SoundsDir = Path.Combine(AppContext.BaseDirectory, "sounds"); private readonly Dictionary _players = []; /// Resolve, load and cache the player for an event. Returns null if the file is /// missing or fails to load — playback then silently no-ops. private SoundPlayer? Get(SoundEvent ev) { if (_players.TryGetValue(ev, out var cached)) return cached; SoundPlayer? player = null; try { string path = Path.Combine(SoundsDir, ev.FileName()); if (File.Exists(path)) { player = new SoundPlayer(path); player.Load(); } } catch { player = null; // unreadable/invalid WAV — degrade to silence } _players[ev] = player; return player; } public void Play(SoundEvent ev) { try { Get(ev)?.Play(); } catch { /* never let a notification sound surface as an error */ } } public void Dispose() { foreach (var p in _players.Values) p?.Dispose(); _players.Clear(); } }