sfxXAudioProvider.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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. // Note: This must be defined before platform.h so that
  23. // CoInitializeEx is properly included.
  24. #define _WIN32_DCOM
  25. #include <xaudio2.h>
  26. #include "sfx/xaudio/sfxXAudioDevice.h"
  27. #include "sfx/sfxProvider.h"
  28. #include "core/util/safeRelease.h"
  29. #include "core/strings/unicode.h"
  30. #include "core/strings/stringFunctions.h"
  31. #include "console/console.h"
  32. #include "core/module.h"
  33. class SFXXAudioProvider : public SFXProvider
  34. {
  35. public:
  36. SFXXAudioProvider()
  37. : SFXProvider( "XAudio" ) {}
  38. virtual ~SFXXAudioProvider();
  39. protected:
  40. /// Extended SFXDeviceInfo to also store some
  41. /// extra XAudio specific data.
  42. struct XADeviceInfo : SFXDeviceInfo
  43. {
  44. UINT32 deviceIndex;
  45. XAUDIO2_DEVICE_ROLE role;
  46. WAVEFORMATEXTENSIBLE format;
  47. };
  48. /// Helper for creating the XAudio engine.
  49. static bool _createXAudio( IXAudio2 **xaudio );
  50. public:
  51. // SFXProvider
  52. void init();
  53. SFXDevice* createDevice( const String& deviceName, bool useHardware, S32 maxBuffers );
  54. };
  55. MODULE_BEGIN( XAudio )
  56. MODULE_INIT_BEFORE( SFX )
  57. MODULE_SHUTDOWN_AFTER( SFX )
  58. SFXXAudioProvider* mProvider;
  59. MODULE_INIT
  60. {
  61. mProvider = new SFXXAudioProvider;
  62. }
  63. MODULE_SHUTDOWN
  64. {
  65. delete mProvider;
  66. }
  67. MODULE_END;
  68. SFXXAudioProvider::~SFXXAudioProvider()
  69. {
  70. }
  71. void SFXXAudioProvider::init()
  72. {
  73. // Create a temp XAudio object for device enumeration.
  74. IXAudio2 *xAudio = NULL;
  75. if ( !_createXAudio( &xAudio ) )
  76. {
  77. Con::errorf( "SFXXAudioProvider::init() - XAudio2 failed to load!" );
  78. return;
  79. }
  80. // Add the devices to the info list.
  81. UINT32 count = 0;
  82. xAudio->GetDeviceCount( &count );
  83. for ( UINT32 i = 0; i < count; i++ )
  84. {
  85. XAUDIO2_DEVICE_DETAILS details;
  86. HRESULT hr = xAudio->GetDeviceDetails( i, &details );
  87. if ( FAILED( hr ) )
  88. continue;
  89. // Add a device to the info list.
  90. XADeviceInfo* info = new XADeviceInfo;
  91. info->deviceIndex = i;
  92. info->driver = String( "XAudio" );
  93. info->name = String( details.DisplayName );
  94. info->hasHardware = false;
  95. info->maxBuffers = 64;
  96. info->role = details.Role;
  97. info->format = details.OutputFormat;
  98. mDeviceInfo.push_back( info );
  99. }
  100. // We're done with XAudio for now.
  101. SAFE_RELEASE( xAudio );
  102. // If we have no devices... we're done.
  103. if ( mDeviceInfo.empty() )
  104. {
  105. Con::errorf( "SFXXAudioProvider::init() - No valid XAudio2 devices found!" );
  106. return;
  107. }
  108. // If we got this far then we should be able to
  109. // safely create a device for XAudio.
  110. regProvider( this );
  111. }
  112. bool SFXXAudioProvider::_createXAudio( IXAudio2 **xaudio )
  113. {
  114. // In debug builds enable the debug version
  115. // of the XAudio engine.
  116. #ifdef TORQUE_DEBUG
  117. #define XAUDIO_FLAGS XAUDIO2_DEBUG_ENGINE
  118. #else
  119. #define XAUDIO_FLAGS 0
  120. #endif
  121. // This must be called first... it doesn't hurt to
  122. // call it more than once.
  123. CoInitialize( NULL );
  124. // Try creating the xaudio engine.
  125. HRESULT hr = XAudio2Create( xaudio, XAUDIO_FLAGS, XAUDIO2_DEFAULT_PROCESSOR );
  126. return SUCCEEDED( hr ) && (*xaudio);
  127. }
  128. SFXDevice* SFXXAudioProvider::createDevice( const String& deviceName, bool useHardware, S32 maxBuffers )
  129. {
  130. String devName;
  131. devName = deviceName;
  132. XADeviceInfo* info = dynamic_cast< XADeviceInfo* >( _findDeviceInfo( devName ) );
  133. // Do we find one to create?
  134. if ( info )
  135. {
  136. // Create the XAudio object to pass to the device.
  137. IXAudio2 *xAudio = NULL;
  138. if ( !_createXAudio( &xAudio ) )
  139. {
  140. Con::errorf( "SFXXAudioProvider::createDevice() - XAudio2 failed to load!" );
  141. return NULL;
  142. }
  143. return new SFXXAudioDevice( this,
  144. devName,
  145. xAudio,
  146. info->deviceIndex,
  147. info->format.dwChannelMask,
  148. maxBuffers );
  149. }
  150. // We didn't find a matching valid device.
  151. return NULL;
  152. }