123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #ifndef _SFXFMODDEVICE_H_
- #define _SFXFMODDEVICE_H_
- #ifndef _SFXDEVICE_H_
- #include "sfx/sfxDevice.h"
- #endif
- #ifndef _SFXFMODVOICE_H_
- #include "sfx/fmod/sfxFMODVoice.h"
- #endif
- #ifndef _SFXFMODBUFFER_H_
- #include "sfx/fmod/sfxFMODBuffer.h"
- #endif
- #ifndef _SFXFMODPLUGIN_H_
- #include "sfx/fmod/sfxFMODPlugin.h"
- #endif
- #include "core/util/tDictionary.h"
- // Disable warning for unused static functions.
- #ifdef TORQUE_COMPILER_VISUALC
- #pragma warning( disable : 4505 )
- #endif
- #if defined( TORQUE_OS_XENON ) || defined( TORQUE_OS_PS3 )
- #define TORQUE_FMOD_STATIC
- #define TORQUE_FMOD_NO_EVENTS //TEMP
- #endif
- #include "fmod.h"
- #include "fmod_errors.h"
- #include "fmod_event.h"
- #include "platform/platformDlibrary.h"
- #include "platform/threads/mutex.h"
- // This doesn't appear to exist in some contexts, so let's just add it.
- #if defined(TORQUE_OS_WIN) || defined(TORQUE_OS_XENON)
- #ifndef WINAPI
- #define WINAPI __stdcall
- #endif
- #else
- #define WINAPI
- #endif
- #define FModAssert(x, msg) \
- { FMOD_RESULT result = ( x ); \
- AssertISV( result == FMOD_OK, String::ToString( "%s: %s", msg, FMOD_ErrorString( result ) ) ); }
- #define FMOD_FN_FILE "sfx/fmod/fmodFunctions.h"
- // Typedefs
- #define FMOD_FUNCTION(fn_name, fn_args) \
- typedef FMOD_RESULT (WINAPI *FMODFNPTR##fn_name)fn_args;
- #define FMOD_EVENT_FUNCTION(fn_name, fn_args) \
- typedef FMOD_RESULT (WINAPI *FMODFNPTR##fn_name)fn_args;
- #include FMOD_FN_FILE
- #undef FMOD_FUNCTION
- #undef FMOD_EVENT_FUNCTION
- /// FMOD API function table.
- ///
- /// FMOD doesn't want to be called concurrently so in order to
- /// not force everything to the main thread (where sound updates
- /// would just stall during loading), we thunk all the API
- /// calls and lock all API entry points to a single mutex.
- struct FModFNTable
- {
- FModFNTable()
- : isLoaded( false ),
- eventIsLoaded( false ),
- dllRef( NULL ),
- eventDllRef( NULL )
- {
- AssertFatal( mutex == NULL,
- "FModFNTable::FModFNTable() - this should be a singleton" );
- mutex = new Mutex;
- }
- ~FModFNTable()
- {
- eventDllRef = NULL;
- dllRef = NULL;
- delete mutex;
- }
- bool isLoaded;
- bool eventIsLoaded;
- DLibraryRef dllRef;
- DLibraryRef eventDllRef;
- static Mutex* mutex;
- template< typename FN >
- struct Thunk
- {
- FN fn;
- template< typename A >
- FMOD_RESULT operator()( A a )
- {
- mutex->lock();
- FMOD_RESULT result = fn( a );
- mutex->unlock();
- return result;
- }
- template< typename A, typename B >
- FMOD_RESULT operator()( A a, B b )
- {
- mutex->lock();
- FMOD_RESULT result = fn( a, b );
- mutex->unlock();
- return result;
- }
- template< typename A, typename B, typename C >
- FMOD_RESULT operator()( A a, B b, C c )
- {
- mutex->lock();
- FMOD_RESULT result = fn( a, b, c );
- mutex->unlock();
- return result;
- }
- template< typename A, typename B, typename C, typename D >
- FMOD_RESULT operator()( A a, B b, C c, D d )
- {
- mutex->lock();
- FMOD_RESULT result = fn( a, b, c, d );
- mutex->unlock();
- return result;
- }
- template< typename A, typename B, typename C, typename D, typename E >
- FMOD_RESULT operator()( A a, B b, C c, D d, E e )
- {
- mutex->lock();
- FMOD_RESULT result = fn( a, b, c, d, e );
- mutex->unlock();
- return result;
- }
- template< typename A, typename B, typename C, typename D, typename E, typename F >
- FMOD_RESULT operator()( A a, B b, C c, D d, E e, F f )
- {
- mutex->lock();
- FMOD_RESULT result = fn( a, b, c, d, e, f );
- mutex->unlock();
- return result;
- }
- template< typename A, typename B, typename C, typename D, typename E, typename F, typename G >
- FMOD_RESULT operator()( A a, B b, C c, D d, E e, F f, G g )
- {
- mutex->lock();
- FMOD_RESULT result = fn( a, b, c, d, e, f, g );
- mutex->unlock();
- return result;
- }
- template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
- FMOD_RESULT operator()( A a, B b, C c, D d, E e, F f, G g, H h )
- {
- mutex->lock();
- FMOD_RESULT result = fn( a, b, c, d, e, f, g, h );
- mutex->unlock();
- return result;
- }
- };
- #define FMOD_FUNCTION(fn_name, fn_args) \
- Thunk< FMODFNPTR##fn_name > fn_name;
- #define FMOD_EVENT_FUNCTION(fn_name, fn_args) \
- Thunk< FMODFNPTR##fn_name > fn_name;
- #include FMOD_FN_FILE
- #undef FMOD_FUNCTION
- #undef FMOD_EVENT_FUNCTION
- };
- inline void TorqueVectorToFMODVector( const Point3F& torque, FMOD_VECTOR& fmod )
- {
- fmod.x = torque.x;
- fmod.y = torque.z;
- fmod.z = torque.y;
- }
- inline void TorqueTransformToFMODVectors( const MatrixF& transform, FMOD_VECTOR& position, FMOD_VECTOR& forward, FMOD_VECTOR& up )
- {
- Point3F _pos, _fwd, _up;
-
- transform.getColumn( 3, &_pos );
- transform.getColumn( 1, &_fwd );
- transform.getColumn( 2, &_up );
- TorqueVectorToFMODVector( _pos, position );
- TorqueVectorToFMODVector( _fwd, forward );
- TorqueVectorToFMODVector( _up, up );
- }
- inline int TorquePriorityToFMODPriority( F32 priority )
- {
- // Map [-2,2] to [256,0].
-
- F32 n = mClampF( priority, -2.0f, 2.0f ) + 2.0f;
- return ( n * 256.0f / 4.0f );
- }
- inline String FMODEventPathToTorqueName( const String& path )
- {
- String p = path;
- p.replace( '/', '_' );
- p.replace( '-', '_' );
- p.replace( ' ', '_' );
- p.replace( '(', '_' );
- p.replace( ')', '_' );
- p.replace( '%', '_' );
- p.replace( '$', '_' );
- return p;
- }
- inline String FMODEventPathToTorqueName( const String& projectName, const String& path )
- {
- return String::ToString( "%s_%s", projectName.c_str(), FMODEventPathToTorqueName( path ).c_str() );
- }
- extern String FMODResultToString( FMOD_RESULT result );
- class SFXProvider;
- class SFXFMODPlugin;
- class SFXFMODDevice : public SFXDevice
- {
- public:
- typedef SFXDevice Parent;
- friend class SFXFMODProvider; // _init
- friend class SFXFMODEventSource; // smStatNumEventSources
- explicit SFXFMODDevice();
- SFXFMODDevice( SFXProvider* provider, FModFNTable *fmodFnTbl, int deviceIdx, String name );
- virtual ~SFXFMODDevice();
- protected:
- FMOD_MODE m3drolloffmode;
- int mDeviceIndex;
-
- /// The FMOD SFXSystemPlugin instance.
- SFXFMODPlugin mPlugin;
-
- /// @name Console Variables
- /// @{
-
- /// Current core FMOD memory usage in bytes.
- static U32 smStatMemUsageCore;
-
- /// Current FMOD Event DLL memory usage in bytes.
- static U32 smStatMemUsageEvents;
-
- /// Current number of SFXFMODEventSource instances.
- static U32 smStatNumEventSources;
-
- ///
- static bool smPrefDisableSoftware;
-
- ///
- static bool smPrefUseSoftwareOcclusion;
-
- ///
- static bool smPrefUseSoftwareHRTF;
-
- ///
- static bool smPrefEnableProfile;
-
- ///
- static bool smPrefGeometryUseClosest;
-
- ///
- static const char* smPrefDSoundHRTF;
-
- ///
- static const char* smPrefPluginPath;
-
- /// @}
-
- bool _init();
-
- static SFXFMODDevice* smInstance;
-
- public:
-
- static SFXFMODDevice* instance() { return smInstance; }
-
- FMOD_MODE get3dRollOffMode() { return m3drolloffmode; }
- static FMOD_SYSTEM* smSystem;
- static FMOD_EVENTSYSTEM* smEventSystem;
- static FModFNTable* smFunc;
-
- // Update memory usage stats for metrics display.
- void updateMemUsageStats();
- // SFXDevice.
- virtual SFXBuffer* createBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description );
- virtual SFXBuffer* createBuffer( const String& filename, SFXDescription* description );
- virtual SFXVoice* createVoice( bool is3D, SFXBuffer* buffer );
- virtual void update();
- virtual void setNumListeners( U32 num );
- virtual void setListener( U32 index, const SFXListenerProperties& listener );
- virtual void setDistanceModel( SFXDistanceModel model );
- virtual void setDopplerFactor( F32 factor );
- virtual void setRolloffFactor( F32 factor );
- virtual void setReverb( const SFXReverbProperties& reverb );
- virtual void resetReverb();
- };
- #endif // _SFXFMODDEVICE_H_
|