/*
* SoundManager.cs
* Authors: Karl Orosz, Bradley Blankenship, Adam Nabinger
* based on code by Shawn Chen, August Zinsser
* Copyright (c) 2007-2008 Cornell University
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 2
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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
namespace SoundManager
{
///
/// Loads the soundbank, giving client classes the ability to play each loaded sound by name. Also stores volume settings.
///
public static class SoundManager
{
#region Fields
///
/// Main interface to the sound drivers
///
private static AudioEngine mEngine;
///
/// Holds raw sound effect waves
///
private static WaveBank mWaveBank;
///
/// Music Wave Bank
///
private static WaveBank mMusicWaveBank;
///
/// Holds Cues
///
private static SoundBank mSoundBank;
///
/// False if there are problems interfacing with the hardware,
/// or if the audio files are omitted.
///
private static bool mHaveSound;
///
/// If there is a audio project currently loaded.
///
private static bool mLoaded;
///
/// Prevent music cues from being played - unimplemented
///
private static bool mMuteMusic = false;
///
/// Prevent sound cues from being played - unimplemented
///
private static bool mMuteSoundEffects = false;
///
/// All sound effects
///
private static AudioCategory mSoundEffectsCategory;
///
/// All music tracks
///
private static AudioCategory mMusicCategory;
///
/// The current sound effect level
///
private static float mEffectVolume = 1.0f;
///
/// The current music level
///
private static float mMusicVolume = 1.0f;
///
/// The currently active music cue
///
private static Cue mMusicCue;
#endregion
#region Properties
///
/// Gets whether or not the Sound Manager is capable of playing sounds.
///
public static bool HaveSound { get { return mHaveSound; } }
///
/// Gets/Sets the current sound effect volume.
///
public static float EffectVolume
{
get { return mEffectVolume; }
set
{
// Set the volume value
mEffectVolume = MathHelper.Clamp(value, 0.0f, 2.0f);
// If there is a sound effect category
if (mSoundEffectsCategory != null && HaveSound)
{
// Set the volume
mSoundEffectsCategory.SetVolume(mEffectVolume);
}
}
}
///
/// Gets/Sets the current music volume.
///
public static float MusicVolume
{
get { return mMusicVolume; }
set
{
mMusicVolume = MathHelper.Clamp(value, 0.0f, 2.0f);
mMusicCategory.SetVolume(mMusicVolume);
}
}
///
/// Sets whether music is muted or not
///
public static bool MuteMusic { set { mMuteMusic = value; } }
///
/// Sets whether sound effects are muted or not
///
public static bool MuteSoundEffects { set { mMuteSoundEffects = value; } }
#endregion
#region Content Managment
///
/// Load the current audio project into memory.
///
/// The directory of the stored content
/// The given audio project.
public static void LoadAudioProject( string contentDirectory, string audioProject)
{
if (mLoaded)
{
throw new InvalidOperationException("An audio project is already loaded in");
}
try
{
mEngine = new AudioEngine(contentDirectory + @"\Audio\" + audioProject);
mSoundBank = new SoundBank(mEngine, contentDirectory + @"\Audio\Sound Bank.xsb");
mWaveBank = new WaveBank(mEngine, contentDirectory + @"\Audio\Wave Bank.xwb");
mMusicWaveBank = new WaveBank(mEngine, contentDirectory + @"\Audio\MusicWaveBank.xwb");
mSoundEffectsCategory = mEngine.GetCategory("Default");
mMusicCategory = mEngine.GetCategory("Music");
mSoundEffectsCategory.SetVolume(mEffectVolume);
mMusicCategory.SetVolume(mMusicVolume);
mLoaded = true;
mHaveSound = true;
}
catch
#if DEBUG
// If we're debugging, catch and print the exception
(Exception e)
#endif
{
#if DEBUG
// Print the exception
Console.WriteLine("SoundManager Error Loading Audio Project: " + e);
#endif
}
}
///
/// Unload the current audio project.
///
public static void UnloadAudioProject()
{
if (mLoaded)
{
mLoaded = false;
mHaveSound = false;
try
{
mMusicCue.Dispose();
mMusicCue = null;
// Dispose all of the engine and sound infor
mEngine.Dispose();
mEngine = null;
mSoundBank.Dispose();
mSoundBank = null;
mWaveBank.Dispose();
mWaveBank = null;
mMusicWaveBank.Dispose();
mMusicWaveBank = null;
}
catch
#if DEBUG
// If we're debugging, catch and print the exception
(Exception e)
#endif
{
#if DEBUG
// Print the exception
Console.WriteLine("SoundManager Error Unloading Audio Project: " + e);
#endif
}
}
}
#endregion
#region Sound Managment
///
/// Play the given music file.
///
/// The file to play.
public static void PlayMusic(string musicName)
{
if (!mHaveSound || mMuteMusic)
{
return;
}
// If the current cue is not null
if (mMusicCue != null)
{
if (mMusicCue.Name == musicName && mMusicCue.IsPlaying)
{
// already playing
return;
}
// Stop the music first
mMusicCue.Stop(AudioStopOptions.Immediate);
mMusicCue.Dispose();
mMusicCue = null;
}
// Now get the new cue and try to play it
try
{
mMusicCue = mSoundBank.GetCue(musicName);
//mSoundBank.PlayCue(musicName);
mMusicCue.Play();
}
catch
#if DEBUG
// If we're debugging, catch and print the exception
(Exception e)
#endif
{
#if DEBUG
Console.WriteLine("SoundManager Error Playing Music: " + e);
#endif
}
}
///
/// Resume the current music, if we have it.
///
public static void ResumeMusic()
{
if (!mHaveSound)
{
return;
}
// If the music cue is not null, resume it
if (mMusicCue != null)
{
// Resume it
mMusicCue.Resume();
}
}
///
/// Stop the music from playing.
///
public static void StopMusic()
{
if (!mHaveSound)
{
return;
}
// If the current music is not null, stop it
if (mMusicCue != null)
{
// Stop the music
mMusicCue.Stop(AudioStopOptions.Immediate);
}
}
///
/// Play a given effect cue.
///
/// The name of the cue to play.
public static void PlayEffect(string effectName)
{
if (!mHaveSound || mMuteSoundEffects)
{
return;
}
try
{
// Try to Play the given effect
mSoundBank.PlayCue(effectName);
}
catch
#if DEBUG
// If we're debugging, catch and print the exception
(Exception e)
#endif
{
#if DEBUG
Console.WriteLine("SoundManager Error Playing Effect: " + e);
#endif
}
}
///
/// Gets the cue of the given effect name
///
/// The name of the effect
/// The cue of the given effect name
public static Cue GetEffectCue(string effectName)
{
if (!mHaveSound)
{
return null;
}
return mSoundBank.GetCue(effectName);
}
#endregion
#region Update
///
/// Performs periodic work required by the audio engine.
///
public static void Update()
{
if (!mHaveSound)
{
return;
}
// Update the engine
mEngine.Update();
}
#endregion
}
}