You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

175 lines
4.5 KiB
C#

using SFML.Audio;
using System;
using System.Collections.Generic;
using System.IO;
namespace Otter {
/// <summary>
/// Class used to load and play music files. Music is streamed from the file source, or an IO stream.
/// </summary>
public class Music : IDisposable {
#region Static Fields
static float globalVolume = 1f;
internal static List<Music> musics = new List<Music>();
#endregion
#region Static Properties
/// <summary>
/// The global volume to play all music at.
/// </summary>
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
/// <summary>
/// The local volume to play this music at.
/// </summary>
public float Volume {
get {
return volume;
}
set {
volume = value;
music.Volume = Util.Clamp(GlobalVolume * volume, 0f, 1f) * 100f;
}
}
/// <summary>
/// Adjust the pitch of the music. Default value is 1.
/// </summary>
public float Pitch {
set { music.Pitch = value; }
get { return music.Pitch; }
}
/// <summary>
/// Set the playback offset of the music in milliseconds.
/// </summary>
public int Offset {
set { music.PlayingOffset = SFML.System.Time.FromMilliseconds(value); }
get { return (int)music.PlayingOffset.AsMilliseconds(); }
}
/// <summary>
/// Determines if the music should loop or not.
/// </summary>
public bool Loop {
set { music.Loop = value; }
get { return music.Loop; }
}
/// <summary>
/// The duration in milliseconds of the music.
/// </summary>
public int Duration {
get { return (int)music.Duration.AsMilliseconds(); }
}
/// <summary>
/// Check if the Music is currently playing.
/// </summary>
public bool IsPlaying { get { return music.Status == SoundStatus.Playing; } }
#endregion
#region Constructors
/// <summary>
/// Load a music file from a file path.
/// </summary>
/// <param name="source"></param>
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();
}
/// <summary>
/// Load a music stream from an IO stream.
/// </summary>
/// <param name="stream"></param>
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
/// <summary>
/// Play the music.
/// </summary>
public void Play() {
music.Volume = Util.Clamp(GlobalVolume * Volume, 0f, 1f) * 100f;
music.Play();
}
/// <summary>
/// Stop the music!
/// </summary>
public void Stop() {
music.Stop();
}
/// <summary>
/// Pause the music.
/// </summary>
public void Pause() {
music.Pause();
}
/// <summary>
/// Dispose the music. (I don't think this works right now.)
/// </summary>
public void Dispose() {
musics.Remove(this);
music.Dispose();
music = null;
}
#endregion
}
}