sfxFMODDevice.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _SFXFMODDEVICE_H_
  23. #define _SFXFMODDEVICE_H_
  24. #ifndef _SFXDEVICE_H_
  25. #include "sfx/sfxDevice.h"
  26. #endif
  27. #ifndef _SFXFMODVOICE_H_
  28. #include "sfx/fmod/sfxFMODVoice.h"
  29. #endif
  30. #ifndef _SFXFMODBUFFER_H_
  31. #include "sfx/fmod/sfxFMODBuffer.h"
  32. #endif
  33. #ifndef _SFXFMODPLUGIN_H_
  34. #include "sfx/fmod/sfxFMODPlugin.h"
  35. #endif
  36. #include "core/util/tDictionary.h"
  37. // Disable warning for unused static functions.
  38. #ifdef TORQUE_COMPILER_VISUALC
  39. #pragma warning( disable : 4505 )
  40. #endif
  41. #if defined( TORQUE_OS_XENON ) || defined( TORQUE_OS_PS3 )
  42. #define TORQUE_FMOD_STATIC
  43. #define TORQUE_FMOD_NO_EVENTS //TEMP
  44. #endif
  45. #include "fmod.h"
  46. #include "fmod_errors.h"
  47. #include "fmod_event.h"
  48. #include "platform/platformDlibrary.h"
  49. #include "platform/threads/mutex.h"
  50. // This doesn't appear to exist in some contexts, so let's just add it.
  51. #if defined(TORQUE_OS_WIN) || defined(TORQUE_OS_XENON)
  52. #ifndef WINAPI
  53. #define WINAPI __stdcall
  54. #endif
  55. #else
  56. #define WINAPI
  57. #endif
  58. #define FModAssert(x, msg) \
  59. { FMOD_RESULT result = ( x ); \
  60. AssertISV( result == FMOD_OK, String::ToString( "%s: %s", msg, FMOD_ErrorString( result ) ) ); }
  61. #define FMOD_FN_FILE "sfx/fmod/fmodFunctions.h"
  62. // Typedefs
  63. #define FMOD_FUNCTION(fn_name, fn_args) \
  64. typedef FMOD_RESULT (WINAPI *FMODFNPTR##fn_name)fn_args;
  65. #define FMOD_EVENT_FUNCTION(fn_name, fn_args) \
  66. typedef FMOD_RESULT (WINAPI *FMODFNPTR##fn_name)fn_args;
  67. #include FMOD_FN_FILE
  68. #undef FMOD_FUNCTION
  69. #undef FMOD_EVENT_FUNCTION
  70. /// FMOD API function table.
  71. ///
  72. /// FMOD doesn't want to be called concurrently so in order to
  73. /// not force everything to the main thread (where sound updates
  74. /// would just stall during loading), we thunk all the API
  75. /// calls and lock all API entry points to a single mutex.
  76. struct FModFNTable
  77. {
  78. FModFNTable()
  79. : isLoaded( false ),
  80. eventIsLoaded( false ),
  81. dllRef( NULL ),
  82. eventDllRef( NULL )
  83. {
  84. AssertFatal( mutex == NULL,
  85. "FModFNTable::FModFNTable() - this should be a singleton" );
  86. mutex = new Mutex;
  87. }
  88. ~FModFNTable()
  89. {
  90. eventDllRef = NULL;
  91. dllRef = NULL;
  92. delete mutex;
  93. }
  94. bool isLoaded;
  95. bool eventIsLoaded;
  96. DLibraryRef dllRef;
  97. DLibraryRef eventDllRef;
  98. static Mutex* mutex;
  99. template< typename FN >
  100. struct Thunk
  101. {
  102. FN fn;
  103. template< typename A >
  104. FMOD_RESULT operator()( A a )
  105. {
  106. mutex->lock();
  107. FMOD_RESULT result = fn( a );
  108. mutex->unlock();
  109. return result;
  110. }
  111. template< typename A, typename B >
  112. FMOD_RESULT operator()( A a, B b )
  113. {
  114. mutex->lock();
  115. FMOD_RESULT result = fn( a, b );
  116. mutex->unlock();
  117. return result;
  118. }
  119. template< typename A, typename B, typename C >
  120. FMOD_RESULT operator()( A a, B b, C c )
  121. {
  122. mutex->lock();
  123. FMOD_RESULT result = fn( a, b, c );
  124. mutex->unlock();
  125. return result;
  126. }
  127. template< typename A, typename B, typename C, typename D >
  128. FMOD_RESULT operator()( A a, B b, C c, D d )
  129. {
  130. mutex->lock();
  131. FMOD_RESULT result = fn( a, b, c, d );
  132. mutex->unlock();
  133. return result;
  134. }
  135. template< typename A, typename B, typename C, typename D, typename E >
  136. FMOD_RESULT operator()( A a, B b, C c, D d, E e )
  137. {
  138. mutex->lock();
  139. FMOD_RESULT result = fn( a, b, c, d, e );
  140. mutex->unlock();
  141. return result;
  142. }
  143. template< typename A, typename B, typename C, typename D, typename E, typename F >
  144. FMOD_RESULT operator()( A a, B b, C c, D d, E e, F f )
  145. {
  146. mutex->lock();
  147. FMOD_RESULT result = fn( a, b, c, d, e, f );
  148. mutex->unlock();
  149. return result;
  150. }
  151. template< typename A, typename B, typename C, typename D, typename E, typename F, typename G >
  152. FMOD_RESULT operator()( A a, B b, C c, D d, E e, F f, G g )
  153. {
  154. mutex->lock();
  155. FMOD_RESULT result = fn( a, b, c, d, e, f, g );
  156. mutex->unlock();
  157. return result;
  158. }
  159. template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
  160. FMOD_RESULT operator()( A a, B b, C c, D d, E e, F f, G g, H h )
  161. {
  162. mutex->lock();
  163. FMOD_RESULT result = fn( a, b, c, d, e, f, g, h );
  164. mutex->unlock();
  165. return result;
  166. }
  167. };
  168. #define FMOD_FUNCTION(fn_name, fn_args) \
  169. Thunk< FMODFNPTR##fn_name > fn_name;
  170. #define FMOD_EVENT_FUNCTION(fn_name, fn_args) \
  171. Thunk< FMODFNPTR##fn_name > fn_name;
  172. #include FMOD_FN_FILE
  173. #undef FMOD_FUNCTION
  174. #undef FMOD_EVENT_FUNCTION
  175. };
  176. inline void TorqueVectorToFMODVector( const Point3F& torque, FMOD_VECTOR& fmod )
  177. {
  178. fmod.x = torque.x;
  179. fmod.y = torque.z;
  180. fmod.z = torque.y;
  181. }
  182. inline void TorqueTransformToFMODVectors( const MatrixF& transform, FMOD_VECTOR& position, FMOD_VECTOR& forward, FMOD_VECTOR& up )
  183. {
  184. Point3F _pos, _fwd, _up;
  185. transform.getColumn( 3, &_pos );
  186. transform.getColumn( 1, &_fwd );
  187. transform.getColumn( 2, &_up );
  188. TorqueVectorToFMODVector( _pos, position );
  189. TorqueVectorToFMODVector( _fwd, forward );
  190. TorqueVectorToFMODVector( _up, up );
  191. }
  192. inline int TorquePriorityToFMODPriority( F32 priority )
  193. {
  194. // Map [-2,2] to [256,0].
  195. F32 n = mClampF( priority, -2.0f, 2.0f ) + 2.0f;
  196. return ( n * 256.0f / 4.0f );
  197. }
  198. inline String FMODEventPathToTorqueName( const String& path )
  199. {
  200. String p = path;
  201. p.replace( '/', '_' );
  202. p.replace( '-', '_' );
  203. p.replace( ' ', '_' );
  204. p.replace( '(', '_' );
  205. p.replace( ')', '_' );
  206. p.replace( '%', '_' );
  207. p.replace( '$', '_' );
  208. return p;
  209. }
  210. inline String FMODEventPathToTorqueName( const String& projectName, const String& path )
  211. {
  212. return String::ToString( "%s_%s", projectName.c_str(), FMODEventPathToTorqueName( path ).c_str() );
  213. }
  214. extern String FMODResultToString( FMOD_RESULT result );
  215. class SFXProvider;
  216. class SFXFMODPlugin;
  217. class SFXFMODDevice : public SFXDevice
  218. {
  219. public:
  220. typedef SFXDevice Parent;
  221. friend class SFXFMODProvider; // _init
  222. friend class SFXFMODEventSource; // smStatNumEventSources
  223. explicit SFXFMODDevice();
  224. SFXFMODDevice( SFXProvider* provider, FModFNTable *fmodFnTbl, int deviceIdx, String name );
  225. virtual ~SFXFMODDevice();
  226. protected:
  227. FMOD_MODE m3drolloffmode;
  228. int mDeviceIndex;
  229. /// The FMOD SFXSystemPlugin instance.
  230. SFXFMODPlugin mPlugin;
  231. /// @name Console Variables
  232. /// @{
  233. /// Current core FMOD memory usage in bytes.
  234. static U32 smStatMemUsageCore;
  235. /// Current FMOD Event DLL memory usage in bytes.
  236. static U32 smStatMemUsageEvents;
  237. /// Current number of SFXFMODEventSource instances.
  238. static U32 smStatNumEventSources;
  239. ///
  240. static bool smPrefDisableSoftware;
  241. ///
  242. static bool smPrefUseSoftwareOcclusion;
  243. ///
  244. static bool smPrefUseSoftwareHRTF;
  245. ///
  246. static bool smPrefEnableProfile;
  247. ///
  248. static bool smPrefGeometryUseClosest;
  249. ///
  250. static const char* smPrefDSoundHRTF;
  251. ///
  252. static const char* smPrefPluginPath;
  253. /// @}
  254. bool _init();
  255. static SFXFMODDevice* smInstance;
  256. public:
  257. static SFXFMODDevice* instance() { return smInstance; }
  258. FMOD_MODE get3dRollOffMode() { return m3drolloffmode; }
  259. static FMOD_SYSTEM* smSystem;
  260. static FMOD_EVENTSYSTEM* smEventSystem;
  261. static FModFNTable* smFunc;
  262. // Update memory usage stats for metrics display.
  263. void updateMemUsageStats();
  264. // SFXDevice.
  265. virtual SFXBuffer* createBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description );
  266. virtual SFXBuffer* createBuffer( const String& filename, SFXDescription* description );
  267. virtual SFXVoice* createVoice( bool is3D, SFXBuffer* buffer );
  268. virtual void update();
  269. virtual void setNumListeners( U32 num );
  270. virtual void setListener( U32 index, const SFXListenerProperties& listener );
  271. virtual void setDistanceModel( SFXDistanceModel model );
  272. virtual void setDopplerFactor( F32 factor );
  273. virtual void setRolloffFactor( F32 factor );
  274. virtual void setReverb( const SFXReverbProperties& reverb );
  275. virtual void resetReverb();
  276. };
  277. #endif // _SFXFMODDEVICE_H_