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;
}
}