// =================== Copyright (C) 2007 Odorless Entertainment =================== // // // // This source file was written by the collective efforts of Odorless Entertainment: // // // // Nauful 'Cade' Shaikh [co-owner, lead technical director] // // Jonathan 'Blade' Bastnagel [co-owner, co-technical director] // // Maciek 'ManTis' Kozlowski [co-owner, lead toolset developer] // // Mats 'RBurn' Soderlund [co-owner, lead art director/lead designer] // // // // File: Audio.cs // Purpose: [Write a brief description here] // // // 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., // // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // // // ================================================================================== // using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using System.IO; using System.Threading; using KillShit.Engine.Audio.FMOD; namespace KillShit.Engine.Audio { public static class AudioManager { public static FMOD.System AudioEngine = null; private static List SoundPool = new List ( ); public static bool bDisposed = false; public static Game.Audio.MusicManager MusicManager = new Game.Audio.MusicManager ( ); public static Thread MusicThread; private static Stopwatch AudioTimer; // Used for DeltaTime private static float AudioDeltaTime; public static Queue MessageQueue; public static void Init ( ) { MessageQueue = new Queue ( ); Engine.Renderer.Driver.Debug.AddText ( "Creating FMOD System...", System.Drawing.Color.Green.ToArgb ( ) ); FMOD.Factory.System_Create ( ref AudioEngine ); Engine.Renderer.Driver.Debug.AddText ( "FMOD System Created!", System.Drawing.Color.Green.ToArgb ( ) ); System.Threading.Thread.Sleep ( 2000 ); Engine.Renderer.Driver.Debug.AddText ( "Initializing FMOD System...", System.Drawing.Color.Green.ToArgb ( ) ); AudioEngine.init ( 32, FMOD.INITFLAG.NORMAL, System.IntPtr.Zero ); Engine.Renderer.Driver.Debug.AddText ( "FMOD System Initialized!", System.Drawing.Color.Green.ToArgb ( ) ); Engine.Renderer.Driver.Debug.AddText ( "Setting 3D Audio Settings...", System.Drawing.Color.Green.ToArgb ( ) ); AudioEngine.set3DSettings ( 1, 15, 1 ); Engine.Renderer.Driver.Debug.AddText ( "3D Audio Settings Set!", System.Drawing.Color.Green.ToArgb ( ) ); Engine.Renderer.Driver.Debug.AddText ( "Loading Music Manager...", System.Drawing.Color.Green.ToArgb ( ) ); MusicManager.Init ( ); AudioTimer = new Stopwatch ( ); AudioTimer.Start ( ); } public static void Dispose ( ) { foreach ( preCachedSound preCachedSound in SoundPool ) { if ( preCachedSound != null ) { preCachedSound.Dispose ( ); } } SoundPool.Clear ( ); if ( AudioEngine != null ) { AudioEngine.close ( ); } bDisposed = true; } public static void ClearPool ( TYPE Type ) { foreach ( preCachedSound preCachedSound in SoundPool ) { if ( preCachedSound != null && preCachedSound.enType == Type ) { preCachedSound.Dispose ( ); } } SoundPool.Clear ( ); } private static FMOD.VECTOR Vector3ToFMOD ( Microsoft.DirectX.Vector3 V ) { VECTOR V2; V2.x = V.X; V2.y = V.Y; V2.z = V.Z; return V2; } public static void SendMessage( string Message ) { MessageQueue.Enqueue ( Message ); } public static void Update ( Engine.Rendering.Camera Camera ) { if ( !bDisposed ) { if ( AudioTimer.IsRunning ) { AudioTimer.Stop ( ); AudioDeltaTime = ( float ) AudioTimer.ElapsedMilliseconds; AudioTimer.Reset ( ); } VECTOR Pos = Vector3ToFMOD ( Camera.Position ); VECTOR Vel = Vector3ToFMOD ( new Microsoft.DirectX.Vector3 ( 0, 0, 0 ) ); VECTOR ViewDir = Vector3ToFMOD ( Camera.ViewDirection ); VECTOR Up = Vector3ToFMOD ( Camera.Up ); AudioEngine.set3DListenerAttributes ( 0, ref Pos, ref Vel, ref ViewDir, ref Up ); AudioEngine.update ( ); MusicManager.Update ( MessageQueue, AudioDeltaTime ); MessageQueue.Clear ( ); AudioTimer.Start ( ); } } public static void Render ( ) { if ( MusicManager.bSongLoaded ) MusicManager.Render ( ); } public static void addSound ( string Path, TYPE Type, Engine.Audio.FMOD.MODE Mode ) { preCachedSound tempSound = new preCachedSound ( Path, Type, Mode ); foreach ( preCachedSound preCachedSound in SoundPool ) { if ( tempSound.Equals ( preCachedSound ) ) { tempSound.Dispose ( ); tempSound = null; return; } } if ( !Path.Contains ( "http:" ) ) { DirectoryInfo diPath = new DirectoryInfo ( Path ); Engine.Renderer.Driver.Debug.AddText ( "Audio[Status] : '" + diPath.Parent + "/" + diPath.Name + "' pre-cached.", ( int ) Engine.Debug.MESSAGE_TYPE.INFORMATION ); diPath = null; } else { Engine.Renderer.Driver.Debug.AddText ( "Audio[Status] : Shoutcast stream added.", ( int ) Engine.Debug.MESSAGE_TYPE.INFORMATION ); } SoundPool.Add ( tempSound ); Engine.Renderer.Driver.Debug.AddText ( "Audio[Status] : The sound pool contains '" + SoundPool.Count + "' pre-cached audio files.", System.Drawing.Color.Green.ToArgb ( ) ); } public static void playSound ( FMOD.CHANNELINDEX channelid, string Path, bool paused, ref FMOD.Channel Channel ) { AudioManager.AudioEngine.playSound ( channelid, getPreCachedSound ( Path ).sdSound, paused, ref Channel ); } public static void destroySound ( string Path ) { int Index = SoundPool.IndexOf ( getPreCachedSound ( Path ) ); if ( Index != -1 && !SoundPool [ Index ].bDisposed ) { SoundPool [ Index ].Dispose ( ); SoundPool.RemoveAt ( Index ); } } public static preCachedSound getPreCachedSound ( string Path ) { foreach ( preCachedSound preCachedSound in SoundPool ) { if ( Path == preCachedSound.strPath ) return preCachedSound; } return ( preCachedSound ) ( null ); } } public enum TYPE { Map, Music, Effect, Custom, } public class preCachedSound : IDisposable { public string strPath = null; public TYPE enType; public bool bDisposed = false; public FMOD.MODE enMode; public FMOD.Sound sdSound = null; public preCachedSound ( string Path, TYPE Type, FMOD.MODE Mode ) { strPath = Path; enType = Type; enMode = Mode; preCache ( ); } public override bool Equals ( object o ) { preCachedSound Clone = ( preCachedSound ) o; if ( Clone.strPath == this.strPath ) { Clone = null; return true; } else { Clone = null; return false; } } public void preCache ( ) { AudioManager.AudioEngine.createSound ( strPath, enMode, ref sdSound ); } public void Dispose ( ) { if ( sdSound != null ) { sdSound.release ( ); sdSound = null; } bDisposed = true; } public override int GetHashCode ( ) { return base.GetHashCode ( ); } } }