using Microsoft.Xna.Framework.Audio; using MrGameEng.Core; namespace MrGameEng.Audio; /// /// Sound-effect playback with a module-level volume, plus the player. /// Registered as a service via context.UseAudio(). /// public sealed class AudioManager : IDisposable { /// The streaming music player. public MusicPlayer Music { get; } = new(); /// Volume multiplier applied to every sound effect, 0..1. public float SoundVolume { get => _soundVolume; set => _soundVolume = Math.Clamp(value, 0f, 1f); } /// /// Master volume 0..1 applied on top of for sound effects and /// mirrored onto , so a single knob (e.g. a settings /// slider) controls both effects and music. /// public float MasterVolume { get => _masterVolume; set { _masterVolume = Math.Clamp(value, 0f, 1f); Music.Volume = _masterVolume; } } private float _soundVolume = 1f; private float _masterVolume = 1f; /// Plays a sound effect (fire and forget). /// The loaded sound effect. /// Per-play volume 0..1, multiplied with . /// Pitch offset in octaves, -1..1. /// Stereo pan, -1 (left) .. 1 (right). public void Play(SoundEffect sound, float volume = 1f, float pitch = 0f, float pan = 0f) => sound.Play(Math.Clamp(volume, 0f, 1f) * _soundVolume * _masterVolume, pitch, pan); /// public void Dispose() => Music.Dispose(); } /// Wires the audio module into the engine. public static class AudioEngineExtensions { /// Creates the and registers it as a service. Call once at startup. public static AudioManager UseAudio(this EngineContext context) { var manager = new AudioManager(); context.Services.Add(manager); return manager; } }