xact3d3.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /*-========================================================================-_
  2. | - XACT3D3 - |
  3. | Copyright (c) Microsoft Corporation. All rights reserved. |
  4. |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
  5. |VERSION: 0.1 MODEL: Unmanaged User-mode |
  6. |CONTRACT: N / A EXCEPT: No Exceptions |
  7. |PARENT: N / A MINREQ: Win2000, Xbox360 |
  8. |PROJECT: XACT3D DIALECT: MS Visual C++ 7.0 |
  9. |>------------------------------------------------------------------------<|
  10. | DUTY: XACT 3D support |
  11. ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
  12. NOTES:
  13. 1. See X3DAudio.h for information regarding X3DAudio types. */
  14. #ifndef __XACT3D3_H__
  15. #define __XACT3D3_H__
  16. //--------------<D-E-F-I-N-I-T-I-O-N-S>-------------------------------------//
  17. #include <x3daudio.h>
  18. #include <xact3.h>
  19. #pragma warning(push)
  20. #pragma warning(disable: 4701) // disable "local variable may be used without having been initialized" compile warning
  21. // Supported speaker positions, represented as azimuth angles.
  22. //
  23. // Here's a picture of the azimuth angles for the 8 cardinal points,
  24. // seen from above. The emitter's base position is at the origin 0.
  25. //
  26. // FRONT
  27. // | 0 <-- azimuth
  28. // |
  29. // 7pi/4 \ | / pi/4
  30. // \ | /
  31. // LEFT \|/ RIGHT
  32. // 3pi/2-------0-------pi/2
  33. // /|\
  34. // / | \
  35. // 5pi/4 / | \ 3pi/4
  36. // |
  37. // | pi
  38. // BACK
  39. //
  40. #define LEFT_AZIMUTH (3*X3DAUDIO_PI/2)
  41. #define RIGHT_AZIMUTH (X3DAUDIO_PI/2)
  42. #define FRONT_LEFT_AZIMUTH (7*X3DAUDIO_PI/4)
  43. #define FRONT_RIGHT_AZIMUTH (X3DAUDIO_PI/4)
  44. #define FRONT_CENTER_AZIMUTH 0.0f
  45. #define LOW_FREQUENCY_AZIMUTH X3DAUDIO_2PI
  46. #define BACK_LEFT_AZIMUTH (5*X3DAUDIO_PI/4)
  47. #define BACK_RIGHT_AZIMUTH (3*X3DAUDIO_PI/4)
  48. #define BACK_CENTER_AZIMUTH X3DAUDIO_PI
  49. #define FRONT_LEFT_OF_CENTER_AZIMUTH (15*X3DAUDIO_PI/8)
  50. #define FRONT_RIGHT_OF_CENTER_AZIMUTH (X3DAUDIO_PI/8)
  51. //--------------<D-A-T-A---T-Y-P-E-S>---------------------------------------//
  52. // Supported emitter channel layouts:
  53. static const float aStereoLayout[] =
  54. {
  55. LEFT_AZIMUTH,
  56. RIGHT_AZIMUTH
  57. };
  58. static const float a2Point1Layout[] =
  59. {
  60. LEFT_AZIMUTH,
  61. RIGHT_AZIMUTH,
  62. LOW_FREQUENCY_AZIMUTH
  63. };
  64. static const float aQuadLayout[] =
  65. {
  66. FRONT_LEFT_AZIMUTH,
  67. FRONT_RIGHT_AZIMUTH,
  68. BACK_LEFT_AZIMUTH,
  69. BACK_RIGHT_AZIMUTH
  70. };
  71. static const float a4Point1Layout[] =
  72. {
  73. FRONT_LEFT_AZIMUTH,
  74. FRONT_RIGHT_AZIMUTH,
  75. LOW_FREQUENCY_AZIMUTH,
  76. BACK_LEFT_AZIMUTH,
  77. BACK_RIGHT_AZIMUTH
  78. };
  79. static const float a5Point1Layout[] =
  80. {
  81. FRONT_LEFT_AZIMUTH,
  82. FRONT_RIGHT_AZIMUTH,
  83. FRONT_CENTER_AZIMUTH,
  84. LOW_FREQUENCY_AZIMUTH,
  85. BACK_LEFT_AZIMUTH,
  86. BACK_RIGHT_AZIMUTH
  87. };
  88. static const float a7Point1Layout[] =
  89. {
  90. FRONT_LEFT_AZIMUTH,
  91. FRONT_RIGHT_AZIMUTH,
  92. FRONT_CENTER_AZIMUTH,
  93. LOW_FREQUENCY_AZIMUTH,
  94. BACK_LEFT_AZIMUTH,
  95. BACK_RIGHT_AZIMUTH,
  96. LEFT_AZIMUTH,
  97. RIGHT_AZIMUTH
  98. };
  99. //--------------<F-U-N-C-T-I-O-N-S>-----------------------------------------//
  100. ////
  101. // DESCRIPTION:
  102. // Initializes the 3D API's:
  103. //
  104. // REMARKS:
  105. // This method only needs to be called once.
  106. // X3DAudio will be initialized such that its speaker channel mask
  107. // matches the format of the given XACT engine's final mix.
  108. //
  109. // PARAMETERS:
  110. // pEngine - [in] XACT engine
  111. // X3DInstance - [out] X3DAudio instance handle
  112. //
  113. // RETURN VALUE:
  114. // HResult error code
  115. ////
  116. EXTERN_C HRESULT inline XACT3DInitialize (__in IXACT3Engine* pEngine, __in X3DAUDIO_HANDLE X3DInstance)
  117. {
  118. HRESULT hr = S_OK;
  119. if (pEngine == NULL) {
  120. hr = E_POINTER;
  121. }
  122. XACTVARIABLEVALUE nSpeedOfSound;
  123. if (SUCCEEDED(hr)) {
  124. XACTVARIABLEINDEX xactSpeedOfSoundID = pEngine->GetGlobalVariableIndex("SpeedOfSound");
  125. hr = pEngine->GetGlobalVariable(xactSpeedOfSoundID, &nSpeedOfSound);
  126. }
  127. if (SUCCEEDED(hr)) {
  128. WAVEFORMATEXTENSIBLE wfxFinalMixFormat;
  129. hr = pEngine->GetFinalMixFormat(&wfxFinalMixFormat);
  130. if (SUCCEEDED(hr)) {
  131. X3DAudioInitialize(wfxFinalMixFormat.dwChannelMask, nSpeedOfSound, X3DInstance);
  132. }
  133. }
  134. return hr;
  135. }
  136. ////
  137. // DESCRIPTION:
  138. // Calculates DSP settings with respect to 3D parameters:
  139. //
  140. // REMARKS:
  141. // Note the following flags are always specified for XACT3D calculation:
  142. // X3DAUDIO_CALCULATE_MATRIX | X3DAUDIO_CALCULATE_DOPPLER | X3DAUDIO_CALCULATE_EMITTER_ANGLE
  143. //
  144. // This means the caller must set at least the following fields:
  145. // X3DAUDIO_LISTENER.OrientFront
  146. // X3DAUDIO_LISTENER.OrientTop
  147. // X3DAUDIO_LISTENER.Position
  148. // X3DAUDIO_LISTENER.Velocity
  149. //
  150. // X3DAUDIO_EMITTER.OrientFront
  151. // X3DAUDIO_EMITTER.OrientTop, if emitter is multi-channel
  152. // X3DAUDIO_EMITTER.Position
  153. // X3DAUDIO_EMITTER.Velocity
  154. // X3DAUDIO_EMITTER.InnerRadius
  155. // X3DAUDIO_EMITTER.InnerRadiusAngle
  156. // X3DAUDIO_EMITTER.ChannelCount
  157. // X3DAUDIO_EMITTER.CurveDistanceScaler
  158. // X3DAUDIO_EMITTER.DopplerScaler
  159. //
  160. // X3DAUDIO_DSP_SETTINGS.pMatrixCoefficients, the caller need only allocate space for SrcChannelCount*DstChannelCount elements
  161. // X3DAUDIO_DSP_SETTINGS.SrcChannelCount
  162. // X3DAUDIO_DSP_SETTINGS.DstChannelCount
  163. //
  164. // If X3DAUDIO_EMITTER.pChannelAzimuths is left NULL for multi-channel emitters,
  165. // a default channel radius and channel azimuth array will be applied below.
  166. // Distance curves such as X3DAUDIO_EMITTER.pVolumeCurve should be
  167. // left NULL as XACT's native RPCs will be used to define DSP behaviour
  168. // with respect to normalized distance.
  169. //
  170. // See X3DAudio.h for information regarding X3DAudio types.
  171. //
  172. // PARAMETERS:
  173. // X3DInstance - [in] X3DAudio instance handle, returned from XACT3DInitialize()
  174. // pListener - [in] point of 3D audio reception
  175. // pEmitter - [in] 3D audio source
  176. // pDSPSettings - [out] receives calculation results, applied to an XACT cue via XACT3DApply()
  177. //
  178. // RETURN VALUE:
  179. // HResult error code
  180. ////
  181. EXTERN_C HRESULT inline XACT3DCalculate (__in X3DAUDIO_HANDLE X3DInstance, __in const X3DAUDIO_LISTENER* pListener, __inout X3DAUDIO_EMITTER* pEmitter, __inout X3DAUDIO_DSP_SETTINGS* pDSPSettings)
  182. {
  183. HRESULT hr = S_OK;
  184. if (pListener == NULL || pEmitter == NULL || pDSPSettings == NULL) {
  185. hr = E_POINTER;
  186. }
  187. if (SUCCEEDED(hr)) {
  188. if (pEmitter->ChannelCount > 1 && pEmitter->pChannelAzimuths == NULL) {
  189. pEmitter->ChannelRadius = 1.0f;
  190. switch (pEmitter->ChannelCount) {
  191. case 2: pEmitter->pChannelAzimuths = (float*)&aStereoLayout[0]; break;
  192. case 3: pEmitter->pChannelAzimuths = (float*)&a2Point1Layout[0]; break;
  193. case 4: pEmitter->pChannelAzimuths = (float*)&aQuadLayout[0]; break;
  194. case 5: pEmitter->pChannelAzimuths = (float*)&a4Point1Layout[0]; break;
  195. case 6: pEmitter->pChannelAzimuths = (float*)&a5Point1Layout[0]; break;
  196. case 8: pEmitter->pChannelAzimuths = (float*)&a7Point1Layout[0]; break;
  197. default: hr = E_FAIL; break;
  198. }
  199. }
  200. }
  201. if (SUCCEEDED(hr)) {
  202. static X3DAUDIO_DISTANCE_CURVE_POINT DefaultCurvePoints[2] = { 0.0f, 1.0f, 1.0f, 1.0f };
  203. static X3DAUDIO_DISTANCE_CURVE DefaultCurve = { (X3DAUDIO_DISTANCE_CURVE_POINT*)&DefaultCurvePoints[0], 2 };
  204. if (pEmitter->pVolumeCurve == NULL) {
  205. pEmitter->pVolumeCurve = &DefaultCurve;
  206. }
  207. if (pEmitter->pLFECurve == NULL) {
  208. pEmitter->pLFECurve = &DefaultCurve;
  209. }
  210. X3DAudioCalculate(X3DInstance, pListener, pEmitter, (X3DAUDIO_CALCULATE_MATRIX | X3DAUDIO_CALCULATE_DOPPLER | X3DAUDIO_CALCULATE_EMITTER_ANGLE), pDSPSettings);
  211. }
  212. return hr;
  213. }
  214. ////
  215. // DESCRIPTION:
  216. // Applies results from a call to XACT3DCalculate() to a cue.
  217. //
  218. // PARAMETERS:
  219. // pDSPSettings - [in] calculation results generated by XACT3DCalculate()
  220. // pCue - [in] cue to which to apply pDSPSettings
  221. //
  222. // RETURN VALUE:
  223. // HResult error code
  224. ////
  225. EXTERN_C HRESULT inline XACT3DApply (__in const X3DAUDIO_DSP_SETTINGS* pDSPSettings, __in IXACT3Cue* pCue)
  226. {
  227. HRESULT hr = S_OK;
  228. if (pDSPSettings == NULL || pCue == NULL) {
  229. hr = E_POINTER;
  230. }
  231. if (SUCCEEDED(hr)) {
  232. hr = pCue->SetMatrixCoefficients(pDSPSettings->SrcChannelCount, pDSPSettings->DstChannelCount, pDSPSettings->pMatrixCoefficients);
  233. }
  234. if (SUCCEEDED(hr)) {
  235. XACTVARIABLEINDEX xactDistanceID = pCue->GetVariableIndex("Distance");
  236. hr = pCue->SetVariable(xactDistanceID, pDSPSettings->EmitterToListenerDistance);
  237. }
  238. if (SUCCEEDED(hr)) {
  239. XACTVARIABLEINDEX xactDopplerID = pCue->GetVariableIndex("DopplerPitchScalar");
  240. hr = pCue->SetVariable(xactDopplerID, pDSPSettings->DopplerFactor);
  241. }
  242. if (SUCCEEDED(hr)) {
  243. XACTVARIABLEINDEX xactOrientationID = pCue->GetVariableIndex("OrientationAngle");
  244. hr = pCue->SetVariable(xactOrientationID, pDSPSettings->EmitterToListenerAngle * (180.0f / X3DAUDIO_PI));
  245. }
  246. return hr;
  247. }
  248. #pragma warning(pop)
  249. #endif // __XACT3D3_H__
  250. //---------------------------------<-EOF->----------------------------------//