//---------------------------------------------------------------------------------------------------------------------------------------------------
//
// Copyright (C)2007 DarkWynter Studios. All rights reserved.
//
//---------------------------------------------------------------------------------------------------------------------------------------------------
// {Contact : darkwynter.com for licensing information
//---------------------------------------------------------------------------------------------------------------------------------------------------
namespace DarkWynter.Engine.Audio
{
#region Using Statements
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using System.Xml;
#endregion
using Globals;
using Physics;
using GameObjects;
using System.ComponentModel;
using DarkWynter.Stream.UIInterfacing;
#region Game Audio
///
/// Supports 2D and 3D audio.
/// Functions are named after the effect they use in simple functions that
/// wrap the audio file name, making it easy to change sounds that are
/// scattered throughout the engine by changing a single reference.
///
public class Audio
{
#region Properties
///
/// XNA audio engine API
///
[EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))]
public AudioEngine _audioEngine { get { return audioEngine; } set { audioEngine = value; } }
static AudioEngine audioEngine;
///
/// Background Music
///
[EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))]
public WaveBank _music { get { return music; } set { music = value; } }
static WaveBank music;
///
/// Sound Effects
///
[EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))]
public WaveBank _effects { get { return effects; } set { effects = value; } }
static WaveBank effects;
///
/// Provides access to WaveBank entries
///
[EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))]
public SoundBank _soundBank { get { return soundBank; } set { soundBank = value; } }
public static SoundBank soundBank;
///
/// Holds the xml branch contatining music data.
///
[EditorAttribute(typeof(ObjectPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))]
public XmlNode _backgoundAudioNode { get { return backgoundAudioNode; } set { backgoundAudioNode = value; } }
static XmlNode backgoundAudioNode;
///
/// Background music queue. Effects don't need queues b/c they aren't looped.
///
public List _cues { get { return cues; } set { cues = value; } }
static List cues;
///
/// True if background music is playing.
///
public bool _musicPlaying { get { return musicPlaying; } set { musicPlaying = value; } }
static bool musicPlaying = true;
///
/// Used for 3D sound.. don't play if out of range.. wastes proccesses
///
public float _SOUND_CUTOFF_DISTANCE { get { return SOUND_CUTOFF_DISTANCE; } set { SOUND_CUTOFF_DISTANCE = value; } }
public static float SOUND_CUTOFF_DISTANCE = 1500;
#endregion
///
/// Loads audioEngine, soundBank, music waveBank, and effects waveBank.
///
public Audio()
{
// Load Audio Engine Files
audioEngine = new AudioEngine("Content/_audio/Elemental.xgs");
soundBank = new SoundBank(audioEngine, "Content/_audio/Sound Bank.xsb");
music = new WaveBank(audioEngine, "Content/_audio/Music.xwb");
effects = new WaveBank(audioEngine, "Content/_audio/Effects.xwb");
if (backgoundAudioNode != null)
{
backgoundAudioNode.RemoveAll();
}
// Clear music cue list
cues = new List();
}
///
/// Loads xml data for audio tag and play's level song.
///
/// Audio xml node.
public static void LoadXML(XmlNode musicNode)
{
// Save for later
backgoundAudioNode = musicNode;
if (backgoundAudioNode.Name == "Music")
{
try
{
PlayLevelSong(backgoundAudioNode.Attributes["background"].Value);
}
catch
{
System.Diagnostics.Debug.WriteLine("Error reading music filename");
return;
}
}
}
///
/// Play's a song in the background.
///
/// Song Name contained in the loaded SoundBank.
public static void PlayLevelSong(string songName)
{
// Kill everthing
for (int i = 0; i < cues.Count; i++)
{
cues[i].Stop(AudioStopOptions.Immediate);
}
// Unload all the cues
cues.Clear();
// Start new theme
Cue playCue = soundBank.GetCue(songName);
musicPlaying = true;
cues.Add(playCue);
if (Statics_Engine.SystemSettings.music)
{
playCue.Play();
}
}
///
/// Update XNA audio engine.
/// See if user has requested to mute or unmute music.
///
public static void Update()
{
if (Statics_Engine.SystemSettings.music && !musicPlaying)
{
for (int i = 0; i < cues.Count; i++)
{
cues[i].Resume();
musicPlaying = true;
}
}
else if (!Statics_Engine.SystemSettings.music && musicPlaying)
{
for (int i = 0; i < cues.Count; i++)
{
cues[i].Pause();
musicPlaying = false;
}
}
if (audioEngine != null)
{
audioEngine.Update();
}
}
#region 3D Sounds
///
/// Sound coming from a particle on the board, used in attacks.
/// Sound is attached to the particle itself.
///
/// Sound wrapper containing particle-based sounds.
/// Particle emmitting sound.
/// Player listening to sounds.
/// Used to cut off sound after a given time.
public static void Play3D_LoopTrack_TimedKill(Cue3D pSound, Mass emitter, Mass listener, float timestep)
{
//check the distance first!
if (Vector3.Distance(emitter.currentPosition, listener.currentPosition) > SOUND_CUTOFF_DISTANCE)
{return;}
if (timestep < 1000){timestep = 1.0f;}
else{timestep /= 1000.0f;}
pSound.emitter.Position = emitter.currentPosition * timestep;
pSound.emitter.Velocity = emitter.velocity;
pSound.listener.Position = listener.currentPosition * timestep;
pSound.listener.Velocity = listener.velocity;
pSound.cue.Apply3D(pSound.listener, pSound.emitter);
if (!pSound.cue.IsPlaying)
{
pSound.cue = Audio.soundBank.GetCue(pSound.name);
pSound.cue.Apply3D(pSound.listener, pSound.emitter);
pSound.cue.Play();
}
}
///
/// Sound used when Player terrainMods.
///
/// Class containing cues for Player-based sounds.
/// Location of the Attacker.
/// Location of the Listener.
public static void Play3D_LoopTrack(Cue3D pSound, Vector3 emitterPosition, Vector3 listenerPosition)
{
int loopDelay = 900;
//check the distance first!
if (Vector3.Distance(emitterPosition, listenerPosition) > SOUND_CUTOFF_DISTANCE)
{
return;
}
//pSound.cue.Apply3D(pSound.listener, pSound.emitter);
//if (pSound.terrainModSoundTimer.ElapsedMilliseconds > loopDelay)
{
//pSound.cue = soundBank.GetCue(pSound.name);
pSound.emitter.Position = emitterPosition;
pSound.listener.Position = listenerPosition;
pSound.cue.Apply3D(pSound.listener, pSound.emitter);
pSound.cue.Play();
pSound.terrainModSoundTimer.Reset();
pSound.terrainModSoundTimer.Start();
}
}
///
/// Sound used when Player jumps.
///
/// Class containing cues for Player-based sounds.
/// Location of the Attacker.
/// Location of the Listener.
public static void Play3D_OneTimeTrack(Cue3D pSound, Vector3 emitterPosition, Vector3 listenerPosition)
{
//check the distance first!
if (Vector3.Distance(emitterPosition, listenerPosition) > SOUND_CUTOFF_DISTANCE)
{
return;
}
pSound.cue = soundBank.GetCue(pSound.name);
pSound.emitter.Position = emitterPosition;
pSound.listener.Position = listenerPosition;
pSound.cue.Apply3D(pSound.listener, pSound.emitter);
pSound.cue.Play();
}
#endregion
//Audio.soundBank.GetCue("EarthBurst");
//Audio.soundBank.GetCue("WaterBurst");
//Audio.soundBank.GetCue("AirBurst");
//Audio.soundBank.GetCue("Jump");
//Audio.soundBank.GetCue("Hit");
//Audio.soundBank.GetCue("Walking");
//Audio.soundBank.GetCue("TerrainMod");
//Audio.soundBank.GetCue("FireBurst");
#region 2D Sounds
///
/// Base function called by all 2D sounds.
///
/// Name of cue to play
public static void PlayCue2D(string cueName)
{
if (Statics_Engine.SystemSettings.soundFX)
{
soundBank.PlayCue(cueName);
}
}
///
/// Sound played when player finds a Key.
///
public static void KeyFound() { PlayCue2D("KeyFound"); }
///
/// Sound played when Start button is pressed in menu system.
///
public static void MenuStart() { PlayCue2D("Tin"); }
///
/// Sound played when Back button is pressed in menu system.
///
public static void MenuBack() { PlayCue2D("Tin"); }
///
/// Sound played when Up button is pressed in menu system.
///
public static void MenuUp() { PlayCue2D("Tin"); }
///
/// Sound played when Down button is pressed in menu system.
///
public static void MenuDown() { PlayCue2D("Tin"); }
///
/// Sound played when Left button is pressed in menu system.
///
public static void MenuLeft() { PlayCue2D("Tin"); }
///
/// Sound played when Right button is pressed in menu system.
///
public static void MenuRight() { PlayCue2D("Tin"); }
///
/// Sound played when Player selection is changed in menu system.
///
public static void MenuPlayerShuffleRight() { PlayCue2D("Tin"); }
///
/// Sound played when Player selection is changed in menu system.
///
public static void MenuPlayerShuffleLeft() { PlayCue2D("Tin"); }
///
/// Sound played when Dpad button is pressed in Game.
///
public static void MenuDPad() { PlayCue2D("Tin"); }
#endregion
}
#endregion
}