using SFML.Audio; using System; using System.Collections.Generic; using System.IO; namespace Otter { /// /// Class used to load and play music files. Music is streamed from the file source, or an IO stream. /// public class Music : IDisposable { #region Static Fields static float globalVolume = 1f; internal static List musics = new List(); #endregion #region Static Properties /// /// The global volume to play all music at. /// public static float GlobalVolume { get { return globalVolume; } set { globalVolume = Util.Clamp(value, 0, 1); foreach (var m in musics) { m.Volume = m.Volume; //update music volume } } } #endregion #region Private Fields SFML.Audio.Music music; float volume = 1f; #endregion #region Public Properties /// /// The local volume to play this music at. /// public float Volume { get { return volume; } set { volume = value; music.Volume = Util.Clamp(GlobalVolume * volume, 0f, 1f) * 100f; } } /// /// Adjust the pitch of the music. Default value is 1. /// public float Pitch { set { music.Pitch = value; } get { return music.Pitch; } } /// /// Set the playback offset of the music in milliseconds. /// public int Offset { set { music.PlayingOffset = SFML.System.Time.FromMilliseconds(value); } get { return (int)music.PlayingOffset.AsMilliseconds(); } } /// /// Determines if the music should loop or not. /// public bool Loop { set { music.Loop = value; } get { return music.Loop; } } /// /// The duration in milliseconds of the music. /// public int Duration { get { return (int)music.Duration.AsMilliseconds(); } } /// /// Check if the Music is currently playing. /// public bool IsPlaying { get { return music.Status == SoundStatus.Playing; } } #endregion #region Constructors /// /// Load a music file from a file path. /// /// public Music(string source, bool loop = true) { if (!File.Exists(source)) { music = new SFML.Audio.Music(Files.LoadFileBytes(source)); } else { music = new SFML.Audio.Music(source); } music.Loop = loop; Initialize(); } /// /// Load a music stream from an IO stream. /// /// public Music(Stream stream) { music = new SFML.Audio.Music(stream); music.Loop = true; Initialize(); } #endregion #region Private Methods void Initialize() { music.RelativeToListener = false; music.Attenuation = 100; musics.Add(this); } #endregion #region Public Methods /// /// Play the music. /// public void Play() { music.Volume = Util.Clamp(GlobalVolume * Volume, 0f, 1f) * 100f; music.Play(); } /// /// Stop the music! /// public void Stop() { music.Stop(); } /// /// Pause the music. /// public void Pause() { music.Pause(); } /// /// Dispose the music. (I don't think this works right now.) /// public void Dispose() { musics.Remove(this); music.Dispose(); music = null; } #endregion } }