/*
* Audio - Audio allows sound to be played during a animation.
*
* Author: Phillip Piper
* Date: 18/01/2010 5:29 PM
*
* Change log:
* 2010-01-18 JPP - Initial version
*
* To do:
*
* Copyright (C) 2010 Phillip Piper
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* If you wish to use this code in a closed source application, please contact phillip_piper@bigfoot.com.
*/
using System;
using System.Collections.Generic;
using System.Media;
using System.IO;
using System.Reflection;
using System.Threading;
namespace BrightIdeasSoftware
{
///
/// Instances of this class allow sound to be played at specified
/// points within a animation.
///
///
///
/// This class uses the SoundPlayer class internally, and thus can
/// only handle system sounds and WAV sound files.
///
/// A sound that is already playing cannot be paused.
///
public class Audio : Animateable
{
#region Life and death
///
/// Load a sound from a named resource.
///
/// The name of the resource including the trailing ".wav"
/// To embed a wav file, simple add it to the project, and change "Build Action"
/// to "Embedded Resource".
///
public static Audio FromResource(string resourceName) {
Audio sound = new Audio();
sound.ResourceName = resourceName;
return sound;
}
///
/// Create an empty Audio object
///
public Audio() {
}
///
/// Creates an Audio object that will play the given "wav" file
///
///
public Audio(string fileName) {
this.FileName = fileName;
}
///
/// Creates an Audio object that will play the given system sound
///
///
public Audio(SystemSound sound) {
this.SystemSound = sound;
}
#endregion
#region Implementation properties
///
/// Gets or sets the name of the audio file that will be played.
///
protected string FileName ;
protected SoundPlayer Player ;
protected string ResourceName ;
protected SystemSound SystemSound ;
#endregion
#region Animation methods
///
/// Start the sound playing
///
public override void Start() {
// If we are supposed to play an application resource, try to load it
if (!String.IsNullOrEmpty(this.ResourceName)) {
Assembly executingAssembly = Assembly.GetExecutingAssembly();
string assemblyName = executingAssembly.GetName().Name;
Stream stream = executingAssembly.GetManifestResourceStream(assemblyName + "." + this.ResourceName);
if (stream != null)
this.Player = new SoundPlayer(stream);
}
if (!String.IsNullOrEmpty(this.FileName)) {
this.Player = new SoundPlayer(this.FileName);
}
// We could just use Play() and let the player handle the threading for us, but:
// - there is no builtin way to know when the sound has finished
// - on XP (at least), using Play() on a Stream gives noise -- but PlaySync() works fine.
this.done = false;
Thread newThread = new Thread((ThreadStart)delegate {
if (this.SystemSound != null)
this.SystemSound.Play();
else {
if (this.Player != null)
this.Player.PlaySync();
}
this.done = true;
});
newThread.Start();
}
bool done;
///
/// Advance the audio and return if it is done.
///
///
///
public override bool Tick(long elapsed) {
return !this.done;
}
///
/// Stop the sound
///
public override void Stop() {
if (this.SystemSound != null)
return;
if (this.Player != null) {
this.Player.Stop();
this.Player.Dispose();
this.Player = null;
}
}
#endregion
}
}