| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494 |
- #region File Description
- //-----------------------------------------------------------------------------
- // SoundManager.cs
- //
- // Microsoft XNA Community Game Platform
- // Copyright (C) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- #endregion
- #region Using Statements
- using System;
- using System.Collections.Generic;
- using System.Text;
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Audio;
- using RobotGameData.Camera;
- #endregion
- namespace RobotGameData.Sound
- {
- #region SoundElement
- /// <summary>
- /// a sound structure with sound cue and emitter for 3D playback.
- /// </summary>
- public class SoundElement
- {
- public Cue cue = null;
- public AudioEmitter emitter = null;
- public string Name
- {
- get { return cue.Name; }
- }
- }
- #endregion
- /// <summary>
- /// It reads sound data and plays sound and supports 3D positional sound.
- /// When playing sound, it creates SoundElement class internally and
- /// manages a sound pool.
- /// In order to load sound data, the files, which have been created by
- /// Microsoft Cross-Platform Audio Creation Tool (XACT), such as .xgs,
- /// .xwb, and .xsb, are needed.
- /// </summary>
- public class SoundManager
- {
- #region Fields
- /// <summary>
- /// If set to false, all of the related functions get turned off.
- /// </summary>
- bool soundOn = true;
- static AudioEngine audioEngine = null;
- static WaveBank waveBank = null;
- static SoundBank soundBank = null;
- static Dictionary<string, AudioCategory> audioCategories =
- new Dictionary<string, AudioCategory>();
- // Keep track of all the 3D sounds that are currently playing.
- static List<SoundElement> activeSounds = new List<SoundElement>();
- // Keep track of spare SoundObject instances, so we can reuse them.
- // Otherwise we would have to allocate new instances each time
- // a sound was played, which would create unnecessary garbage.
- static Stack<SoundElement> soundPool = new Stack<SoundElement>();
- // The listener describes the ear which is hearing 3D sounds.
- // This is usually set to match the camera.
- AudioListener listener = new AudioListener();
- // The emitter describes an entity which is making a 3D sound.
- AudioEmitter emitter = new AudioEmitter();
-
- static bool pauseAll = false;
- #endregion
- #region Properties
- public static AudioEngine AudioEngine
- {
- get { return audioEngine; }
- }
- public static WaveBank WaveBank
- {
- get { return waveBank; }
- }
- public static SoundBank SoundBank
- {
- get { return soundBank; }
- }
- public static bool PauseAll
- {
- get { return pauseAll; }
- }
- #endregion
- /// <summary>
- /// Constructor.
- /// </summary>
- public SoundManager()
- {
- audioCategories.Clear();
- pauseAll = false;
- }
- /// <summary>
- /// applies 3D sound to the listener.
- /// </summary>
- /// <param name="position">listener position</param>
- /// <param name="direction">listener direction</param>
- /// <param name="up">listener up vector</param>
- /// <param name="velocity">listener velocity</param>
- public void ApplyEmitter(Vector3 position, Vector3 direction, Vector3 up,
- Vector3 velocity)
- {
- // Update listener by the current camera
- this.listener.Position = position;
- this.listener.Forward = direction;
- this.listener.Up = up;
- this.listener.Velocity = velocity;
- }
- /// <summary>
- /// processes the sound pool and the 3D sound playback.
- /// XNA's AudioEngine is updated here.
- /// </summary>
- public void Update()
- {
- if (soundOn == false)
- return;
- // Loop over all the currently playing 3D sounds.
- int index = 0;
- while (index < activeSounds.Count)
- {
- SoundElement sound = activeSounds[index];
- if (sound.cue.IsStopped)
- {
- // If the cue has stopped playing, dispose it.
- //sound.cue.Dispose();
- sound.cue = null;
- sound.emitter = null;
- // Store the SoundElement instance for future reuse.
- soundPool.Push(sound);
- // Remove it from the active list.
- activeSounds.RemoveAt(index);
- }
- else
- {
- if (sound.emitter != null)
- {
- // If the cue is still playing, update its 3D settings.
- Apply3D(sound);
- }
- index++;
- }
- }
- // Update the XACT engine.
- AudioEngine.Update();
- }
- /// <summary>
- /// stops every sound and removes every sound member.
- /// </summary>
- public void Dispose()
- {
- if (soundOn == false)
- return;
- StopSound();
- audioCategories.Clear();
- SoundBank.Dispose();
- WaveBank.Dispose();
- AudioEngine.Dispose();
- }
- /// <summary>
- /// initialize all sound members.
- /// creates and initializes the XNA's AudioEndgine.
- /// </summary>
- /// <param name="globalSettingsFileName"></param>
- /// <param name="waveBankFileName"></param>
- /// <param name="soundBankFileName"></param>
- public void Initialize( string globalSettingsFileName,
- string waveBankFileName,
- string soundBankFileName)
- {
- if (soundOn == false)
- return;
- // Create audio engine
- audioEngine = new AudioEngine(globalSettingsFileName);
- if (audioEngine == null)
- {
- throw new ArgumentException(
- "The audio engine could not be created.");
- }
- // Create wave bank
- waveBank = new WaveBank(audioEngine, waveBankFileName);
- if (waveBank == null)
- {
- throw new ArgumentException(
- "The wave bank could not be created.");
- }
- // Create sound bank
- soundBank = new SoundBank(audioEngine, soundBankFileName);
- if (soundBank == null)
- {
- throw new ArgumentException(
- "The sound bank could not be created.");
- }
- }
- /// <summary>
- /// adds a sound category.
- /// </summary>
- /// <param name="categoryName">name</param>
- public void AddSoundCategory(string categoryName)
- {
- if (soundOn == false)
- return;
- AudioCategory audioCategory = AudioEngine.GetCategory(categoryName);
-
- audioCategories.Add(categoryName, audioCategory);
- }
- /// <summary>
- /// plays the sound for 3D.
- /// </summary>
- /// <param name="soundName">entried sound name</param>
- /// <param name="emitter">3D emitter</param>
- /// <returns>playing sound cue</returns>
- public Cue PlaySound3D(string soundName, AudioEmitter emitter)
- {
- SoundElement sound;
- if (soundPool.Count > 0)
- {
- // If possible, reuse an existing Cue3D instance.
- sound = soundPool.Pop();
- }
- else
- {
- // Otherwise we have to allocate a new one.
- sound = new SoundElement();
- }
- // Fill in the cue and emitter fields.
- sound.cue = soundBank.GetCue(soundName);
- sound.emitter = emitter;
- // Set the 3D position of this cue, and then play it.
- Apply3D(sound);
- sound.cue.Play();
- // Remember that this cue is now active.
- activeSounds.Add(sound);
- return sound.cue;
- }
- /// <summary>
- /// plays the sound.
- /// </summary>
- /// <param name="soundName">entried sound name</param>
- /// <returns>playing sound cue</returns>
- public static Cue PlaySound(string soundName)
- {
- SoundElement sound = null;
- if (soundPool.Count > 0)
- {
- // If possible, reuse an existing Cue3D instance.
- sound = soundPool.Pop();
- }
- else
- {
- // Otherwise we have to allocate a new one.
- sound = new SoundElement();
- }
- // Fill in the cue and emitter fields.
- sound.cue = soundBank.GetCue(soundName);
- sound.cue.Play();
- // Remember that this cue is now active.
- activeSounds.Add(sound);
- return sound.cue;
- }
- /// <summary>
- /// pauses the sound.
- /// </summary>
- public void PauseSound()
- {
- if (soundOn == false || pauseAll )
- return;
- for (int i = 0; i < activeSounds.Count; i++)
- PauseSound(activeSounds[i]);
- pauseAll = true;
- }
- /// <summary>
- /// resumes the sound
- /// </summary>
- public void ResumeSound()
- {
- if (soundOn == false || pauseAll == false)
- return;
- for (int i = 0; i < activeSounds.Count; i++)
- ResumeSound(activeSounds[i]);
- pauseAll = false;
- }
- /// <summary>
- /// stops the sound
- /// </summary>
- /// <param name="cue">playing sound</param>
- public bool StopSound(Cue cue)
- {
- if (soundOn == false || cue == null)
- return false;
- if (cue.IsPaused || cue.IsPlaying)
- {
- cue.Stop(AudioStopOptions.Immediate);
- return true;
- }
- return false;
- }
- /// <summary>
- /// stop all sounds.
- /// </summary>
- public void StopSound()
- {
- if (soundOn == false)
- return;
- for (int i = 0; i < activeSounds.Count; i++)
- StopSound(activeSounds[i]);
- }
- /// <summary>
- /// sets volume.
- /// </summary>
- /// <param name="categoryName"></param>
- /// <param name="volume"></param>
- public void SetVolume(string categoryName, float volume)
- {
- if (soundOn == false)
- return;
- if (!audioCategories.ContainsKey(categoryName))
- {
- throw new InvalidOperationException("Cannot find the category : "
- + categoryName);
- }
- audioCategories[categoryName].SetVolume(
- MathHelper.Clamp(volume, 0.0f, 1.0f));
- }
- /// <summary>
- /// determines whether a sound is being played.
- /// </summary>
- /// <param name="cue">playing sound cue</param>
- /// <returns>true or false</returns>
- public bool IsPlaying(Cue cue)
- {
- if (soundOn == false)
- return false;
- if (cue != null)
- return cue.IsPlaying;
- return false;
- }
- /// <summary>
- /// determines whether a sound is being played.
- /// </summary>
- /// <param name="cue">playing sound cue</param>
- /// <returns>true or false</returns>
- public bool IsPause(Cue cue)
- {
- if (soundOn == false)
- return false;
- if (cue != null)
- return cue.IsPaused;
- return false;
- }
- /// <summary>
- /// applies 3D position to sound element.
- /// </summary>
- /// <param name="element"></param>
- private void Apply3D(SoundElement element)
- {
- emitter.Position = element.emitter.Position;
- emitter.Forward = element.emitter.Forward;
- emitter.Up = element.emitter.Up;
- emitter.Velocity = element.emitter.Velocity;
- element.cue.Apply3D(listener, emitter);
- }
- /// <summary>
- /// pauses the sound.
- /// </summary>
- /// <param name="sound">playing sound element</param>
- private bool PauseSound(SoundElement sound)
- {
- if (soundOn == false || sound == null || sound.cue == null)
- return false;
- if (sound.cue.IsPlaying)
- {
- sound.cue.Pause();
- return true;
- }
- return false;
- }
- /// <summary>
- /// resumes the sound.
- /// </summary>
- /// <param name="sound">paused sound element</param>
- private bool ResumeSound(SoundElement sound)
- {
- if (soundOn == false || sound == null || sound.cue == null)
- return false;
- if (sound.cue.IsPaused)
- {
- sound.cue.Resume();
- return true;
- }
- return false;
- }
- /// <summary>
- /// stops the sound.
- /// </summary>
- /// <param name="sound">playing sound element</param>
- private bool StopSound(SoundElement sound)
- {
- if (soundOn == false || sound == null || sound.cue == null)
- return false;
- if (sound.cue.IsPaused || sound.cue.IsPlaying)
- {
- sound.cue.Stop(AudioStopOptions.Immediate);
- return true;
- }
- return false;
- }
- }
- }
|