sfxALDevice.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  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. #include "sfx/openal/sfxALDevice.h"
  23. #include "sfx/openal/sfxALBuffer.h"
  24. #include "platform/async/asyncUpdate.h"
  25. //----------------------------------------------------------------------------
  26. // STATIC OPENAL FUNCTIONS
  27. //----------------------------------------------------------------------------
  28. void SFXALDevice::printALInfo(ALCdevice* device)
  29. {
  30. ALCint major, minor;
  31. if (device)
  32. {
  33. const ALCchar* devname = NULL;
  34. Con::printBlankLine();
  35. if (mOpenAL.alcIsExtensionPresent(device, "ALC_ENUMERATE_ALL_EXT") != AL_FALSE)
  36. {
  37. devname = mOpenAL.alcGetString(device, ALC_ALL_DEVICES_SPECIFIER);
  38. }
  39. else
  40. {
  41. devname = mOpenAL.alcGetString(device, ALC_DEVICE_SPECIFIER);
  42. }
  43. Con::printf("| Device info for: %s ", devname);
  44. }
  45. mOpenAL.alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major);
  46. mOpenAL.alcGetIntegerv(device, ALC_MINOR_VERSION, 1, &minor);
  47. Con::printf("| OpenAL Version: %d.%d", major, minor);
  48. if (device)
  49. {
  50. Con::printf("%s", mOpenAL.alcGetString(device, ALC_EXTENSIONS));
  51. U32 err = mOpenAL.alcGetError(device);
  52. if (err != ALC_NO_ERROR)
  53. Con::errorf("SFXALDevice - Error Retrieving ALC Extensions: %s", mOpenAL.alcGetString(device, err));
  54. }
  55. }
  56. void SFXALDevice::printHRTFInfo(ALCdevice* device)
  57. {
  58. if (mOpenAL.alcIsExtensionPresent(device, "ALC_SOFT_HRTF") == AL_FALSE)
  59. {
  60. Con::printf("HRTF Extensions not compatible");
  61. return;
  62. }
  63. ALCint numHrtfs;
  64. mOpenAL.alcGetIntegerv(device, ALC_NUM_HRTF_SPECIFIERS_SOFT, 1, &numHrtfs);
  65. if (!numHrtfs)
  66. Con::printf("No HRTFs Found");
  67. else
  68. {
  69. Con::printf("Available HRTFs");
  70. for (U32 i = 0; i < numHrtfs; ++i)
  71. {
  72. const ALCchar* name = mOpenAL.alcGetStringiSOFT(device, ALC_HRTF_SPECIFIER_SOFT, i);
  73. printf(" %s", name);
  74. }
  75. }
  76. U32 err = mOpenAL.alcGetError(device);
  77. if (err != ALC_NO_ERROR)
  78. Con::errorf("SFXALDevice - Error Retrieving HRTF info: %s", mOpenAL.alcGetString(device, err));
  79. }
  80. void SFXALDevice::getEFXInfo(ALCdevice *device)
  81. {
  82. static const ALint filters[] = {
  83. AL_FILTER_LOWPASS, AL_FILTER_HIGHPASS, AL_FILTER_BANDPASS,
  84. AL_FILTER_NULL
  85. };
  86. char filterNames[] = "Low-pass,High-pass,Band-pass,";
  87. static const ALint effects[] = {
  88. AL_EFFECT_EAXREVERB, AL_EFFECT_REVERB, AL_EFFECT_CHORUS,
  89. AL_EFFECT_DISTORTION, AL_EFFECT_ECHO, AL_EFFECT_FLANGER,
  90. AL_EFFECT_FREQUENCY_SHIFTER, AL_EFFECT_VOCAL_MORPHER,
  91. AL_EFFECT_PITCH_SHIFTER, AL_EFFECT_RING_MODULATOR,
  92. AL_EFFECT_AUTOWAH, AL_EFFECT_COMPRESSOR, AL_EFFECT_EQUALIZER,
  93. AL_EFFECT_NULL
  94. };
  95. static const ALint dedeffects[] = {
  96. AL_EFFECT_DEDICATED_DIALOGUE, AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT,
  97. AL_EFFECT_NULL
  98. };
  99. char effectNames[] = "EAX Reverb,Reverb,Chorus,Distortion,Echo,Flanger,"
  100. "Frequency Shifter,Vocal Morpher,Pitch Shifter,Ring Modulator,Autowah,"
  101. "Compressor,Equalizer,Dedicated Dialog,Dedicated LFE,";
  102. ALCint major, minor, sends;
  103. ALuint obj;
  104. char* current;
  105. U32 i;
  106. if (mOpenAL.alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_FALSE)
  107. {
  108. Con::printf("SFXALDevice - EFX Not available.");
  109. return;
  110. }
  111. mOpenAL.alcGetIntegerv(device, ALC_EFX_MAJOR_VERSION, 1, &major);
  112. mOpenAL.alcGetIntegerv(device, ALC_EFX_MINOR_VERSION, 1, &minor);
  113. U32 err = mOpenAL.alcGetError(device);
  114. if (err != ALC_NO_ERROR)
  115. Con::errorf("SFXALDevice - Error Retrieving EFX Version: %s", mOpenAL.alcGetString(device, err));
  116. else
  117. {
  118. Con::printf("| EFX Version: %d.%d", major, minor);
  119. }
  120. mOpenAL.alcGetIntegerv(device, ALC_MAX_AUXILIARY_SENDS, 1, &sends);
  121. err = mOpenAL.alcGetError(device);
  122. if (err != ALC_NO_ERROR)
  123. Con::errorf("SFXALDevice - Error Retrieving Auxiliary Sends: %s", mOpenAL.alcGetString(device, err));
  124. else
  125. {
  126. Con::printf("| Max Aux Sends: %d", sends);
  127. }
  128. mOpenAL.alGenFilters(1, &obj);
  129. err = mOpenAL.alcGetError(device);
  130. if (err != ALC_NO_ERROR)
  131. Con::errorf("SFXALDevice - Error Generating filter: %s", mOpenAL.alcGetString(device, err));
  132. current = filterNames;
  133. for (i = 0; filters[i] != AL_FILTER_NULL; i++)
  134. {
  135. char* next = dStrchr(current, ',');
  136. mOpenAL.alFilteri(obj, AL_FILTER_TYPE, filters[i]);
  137. if (mOpenAL.alGetError() != AL_NO_ERROR)
  138. dMemmove(current, next + 1, strlen(next));
  139. else
  140. current = next + 1;
  141. }
  142. Con::printf("| Supported Filters: %s", filterNames);
  143. mOpenAL.alDeleteFilters(1, &obj);
  144. mOpenAL.alGenEffects(1, &obj);
  145. err = mOpenAL.alcGetError(device);
  146. if (err != ALC_NO_ERROR)
  147. Con::errorf("SFXALDevice - Error Generating effects: %s", mOpenAL.alcGetString(device, err));
  148. current = effectNames;
  149. for (i = 0; effects[i] != AL_EFFECT_NULL; i++)
  150. {
  151. char* next = dStrchr(current, ',');
  152. mOpenAL.alEffecti(obj, AL_FILTER_TYPE, effects[i]);
  153. if (mOpenAL.alGetError() != AL_NO_ERROR)
  154. dMemmove(current, next + 1, strlen(next));
  155. else
  156. current = next + 1;
  157. }
  158. if (mOpenAL.alcIsExtensionPresent(device, "ALC_EXT_DEDICATED"))
  159. {
  160. for (i = 0; dedeffects[i] != AL_EFFECT_NULL; i++)
  161. {
  162. char* next = dStrchr(current, ',');
  163. mOpenAL.alEffecti(obj, AL_FILTER_TYPE, dedeffects[i]);
  164. if (mOpenAL.alGetError() != AL_NO_ERROR)
  165. dMemmove(current, next + 1, strlen(next));
  166. else
  167. current = next + 1;
  168. }
  169. }
  170. else
  171. {
  172. for (i = 0; dedeffects[i] != AL_EFFECT_NULL; i++)
  173. {
  174. char* next = dStrchr(current, ',');
  175. dMemmove(current, next + 1, strlen(next));
  176. }
  177. }
  178. Con::printf("| Supported Effects: %s", effectNames);
  179. mOpenAL.alDeleteEffects(1, &obj);
  180. }
  181. S32 SFXALDevice::getMaxSources()
  182. {
  183. // Clear AL Error Code
  184. mOpenAL.alGetError();
  185. ALCint nummono;
  186. mOpenAL.alcGetIntegerv(mDevice, ALC_MONO_SOURCES, 1, &nummono);
  187. return nummono;
  188. }
  189. //-----------------------------------------------------------------------------
  190. SFXALDevice::SFXALDevice( SFXProvider *provider,
  191. const OPENALFNTABLE &openal,
  192. String name,
  193. bool useHardware,
  194. S32 maxBuffers )
  195. : Parent( name, provider, useHardware, maxBuffers ),
  196. mOpenAL( openal ),
  197. mContext( NULL ),
  198. mDevice( NULL ),
  199. mDistanceModel(SFXDistanceModelLinear),
  200. mDistanceFactor(1.0f),
  201. mRolloffFactor( 1.0f ),
  202. mUserRolloffFactor(1.0f)
  203. {
  204. mMaxBuffers = getMax( maxBuffers, 8 );
  205. // TODO: The OpenAL device doesn't set the primary buffer
  206. // $pref::SFX::frequency or $pref::SFX::bitrate!
  207. //check auxiliary device sends 4 and add them to the device
  208. ALint attribs[4] = { 0 };
  209. #if defined(AL_ALEXT_PROTOTYPES)
  210. ALCint iSends = 0;
  211. attribs[0] = ALC_MAX_AUXILIARY_SENDS;
  212. #endif
  213. attribs[1] = 4;
  214. printALInfo(NULL);
  215. mDevice = mOpenAL.alcOpenDevice( name );
  216. U32 err = mOpenAL.alcGetError(mDevice);
  217. if (err != ALC_NO_ERROR)
  218. Con::errorf("SFXALDevice - Device Initialization Error: %s", mOpenAL.alcGetString(mDevice, err));
  219. if( mDevice )
  220. {
  221. mContext = mOpenAL.alcCreateContext( mDevice, attribs );
  222. if( mContext )
  223. mOpenAL.alcMakeContextCurrent( mContext );
  224. #if defined(AL_ALEXT_PROTOTYPES)
  225. mOpenAL.alcGetIntegerv(mDevice, ALC_MAX_AUXILIARY_SENDS, 1, &iSends);
  226. #endif
  227. U32 err = mOpenAL.alcGetError( mDevice );
  228. if( err != ALC_NO_ERROR )
  229. Con::errorf( "SFXALDevice - Context Initialization Error: %s", mOpenAL.alcGetString( mDevice, err ) );
  230. }
  231. AssertFatal( mDevice != NULL && mContext != NULL, "Failed to create OpenAL device and/or context!" );
  232. // Start the update thread.
  233. // TODO AsyncPeriodicUpdateThread support for Linux/Mac
  234. #ifdef TORQUE_OS_WIN
  235. if( !Con::getBoolVariable( "$_forceAllMainThread" ) )
  236. {
  237. SFXInternal::gUpdateThread = new AsyncPeriodicUpdateThread
  238. ( "OpenAL Update Thread", SFXInternal::gBufferUpdateList,
  239. Con::getIntVariable( "$pref::SFX::updateInterval", SFXInternal::DEFAULT_UPDATE_INTERVAL ) );
  240. SFXInternal::gUpdateThread->start();
  241. }
  242. #endif
  243. #if defined(AL_ALEXT_PROTOTYPES)
  244. dMemset(effectSlot, 0, sizeof(effectSlot));
  245. dMemset(effect, 0, sizeof(effect));
  246. uLoop = 0;
  247. #endif
  248. printALInfo(mDevice);
  249. printHRTFInfo(mDevice);
  250. getEFXInfo(mDevice);
  251. mMaxBuffers = getMaxSources();
  252. // this should be max sources.
  253. Con::printf("| Max Sources: %d", mMaxBuffers);
  254. }
  255. //-----------------------------------------------------------------------------
  256. SFXALDevice::~SFXALDevice()
  257. {
  258. _releaseAllResources();
  259. ///cleanup our effects
  260. #if defined(AL_ALEXT_PROTOTYPES)
  261. mOpenAL.alDeleteAuxiliaryEffectSlots(4, effectSlot);
  262. mOpenAL.alDeleteEffects(2, effect);
  263. #endif
  264. ///cleanup of effects ends
  265. mOpenAL.alcMakeContextCurrent( NULL );
  266. mOpenAL.alcDestroyContext( mContext );
  267. mOpenAL.alcCloseDevice( mDevice );
  268. }
  269. //-----------------------------------------------------------------------------
  270. SFXBuffer* SFXALDevice::createBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description )
  271. {
  272. AssertFatal( stream, "SFXALDevice::createBuffer() - Got null stream!" );
  273. AssertFatal( description, "SFXALDevice::createBuffer() - Got null description!" );
  274. SFXALBuffer* buffer = SFXALBuffer::create( mOpenAL,
  275. stream,
  276. description,
  277. mUseHardware );
  278. if ( !buffer )
  279. return NULL;
  280. _addBuffer( buffer );
  281. return buffer;
  282. }
  283. //-----------------------------------------------------------------------------
  284. SFXVoice* SFXALDevice::createVoice( bool is3D, SFXBuffer *buffer )
  285. {
  286. // Don't bother going any further if we've
  287. // exceeded the maximum voices.
  288. if ( mVoices.size() >= mMaxBuffers )
  289. return NULL;
  290. AssertFatal( buffer, "SFXALDevice::createVoice() - Got null buffer!" );
  291. SFXALBuffer* alBuffer = dynamic_cast<SFXALBuffer*>( buffer );
  292. AssertFatal( alBuffer, "SFXALDevice::createVoice() - Got bad buffer!" );
  293. SFXALVoice* voice = SFXALVoice::create( this, alBuffer );
  294. if ( !voice )
  295. return NULL;
  296. _addVoice( voice );
  297. return voice;
  298. }
  299. //-----------------------------------------------------------------------------
  300. void SFXALDevice::setListener( U32 index, const SFXListenerProperties& listener )
  301. {
  302. if( index != 0 )
  303. return;
  304. // Torque and OpenAL are both right handed
  305. // systems, so no coordinate flipping is needed.
  306. const MatrixF &transform = listener.getTransform();
  307. Point3F pos, tupple[2];
  308. transform.getColumn( 3, &pos );
  309. transform.getColumn( 1, &tupple[0] );
  310. transform.getColumn( 2, &tupple[1] );
  311. const VectorF &velocity = listener.getVelocity();
  312. mOpenAL.alListenerfv( AL_POSITION, pos );
  313. mOpenAL.alListenerfv( AL_VELOCITY, velocity );
  314. mOpenAL.alListenerfv( AL_ORIENTATION, (const F32 *)&tupple[0] );
  315. ///Pass a unit size to openal, 1.0 assumes 1 meter to 1 game unit.
  316. ///Crucial for air absorbtion calculations.
  317. #if defined(AL_ALEXT_PROTOTYPES)
  318. mOpenAL.alListenerf(AL_METERS_PER_UNIT, 1.0f);
  319. #endif
  320. }
  321. //-----------------------------------------------------------------------------
  322. void SFXALDevice::setDistanceModel( SFXDistanceModel model )
  323. {
  324. switch( model )
  325. {
  326. case SFXDistanceModelLinear:
  327. mOpenAL.alDistanceModel( AL_LINEAR_DISTANCE_CLAMPED );
  328. if( mRolloffFactor != 1.0f )
  329. _setRolloffFactor( 1.0f ); // No rolloff on linear.
  330. break;
  331. case SFXDistanceModelLogarithmic:
  332. mOpenAL.alDistanceModel( AL_INVERSE_DISTANCE_CLAMPED );
  333. if( mUserRolloffFactor != mRolloffFactor )
  334. _setRolloffFactor( mUserRolloffFactor );
  335. break;
  336. /// create a case for our exponential distance model
  337. case SFXDistanceModelExponent:
  338. mOpenAL.alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED);
  339. if (mUserRolloffFactor != mRolloffFactor)
  340. _setRolloffFactor(mUserRolloffFactor);
  341. break;
  342. default:
  343. AssertWarn( false, "SFXALDevice::setDistanceModel - distance model not implemented" );
  344. }
  345. mDistanceModel = model;
  346. }
  347. //-----------------------------------------------------------------------------
  348. void SFXALDevice::setDopplerFactor( F32 factor )
  349. {
  350. mOpenAL.alDopplerFactor( factor );
  351. }
  352. //-----------------------------------------------------------------------------
  353. void SFXALDevice::_setRolloffFactor( F32 factor )
  354. {
  355. mRolloffFactor = factor;
  356. for( U32 i = 0, num = mVoices.size(); i < num; ++ i )
  357. mOpenAL.alSourcef( ( ( SFXALVoice* ) mVoices[ i ] )->mSourceName, AL_ROLLOFF_FACTOR, factor );
  358. }
  359. //-----------------------------------------------------------------------------
  360. void SFXALDevice::setRolloffFactor( F32 factor )
  361. {
  362. if( mDistanceModel == SFXDistanceModelLinear && factor != 1.0f )
  363. Con::errorf( "SFXALDevice::setRolloffFactor - rolloff factor <> 1.0f ignored in linear distance model" );
  364. else
  365. _setRolloffFactor( factor );
  366. mUserRolloffFactor = factor;
  367. }
  368. #if defined(AL_ALEXT_PROTOTYPES)
  369. void SFXALDevice::openSlots()
  370. {
  371. for (uLoop = 0; uLoop < 4; uLoop++)
  372. {
  373. mOpenAL.alGenAuxiliaryEffectSlots(1, &effectSlot[uLoop]);
  374. }
  375. for (uLoop = 0; uLoop < 2; uLoop++)
  376. {
  377. mOpenAL.alGenEffects(1, &effect[uLoop]);
  378. }
  379. ///debug string output so we know our slots are open
  380. Platform::outputDebugString("Slots Open");
  381. }
  382. ///create reverb effect
  383. void SFXALDevice::setReverb(const SFXReverbProperties& reverb)
  384. {
  385. ///output a debug string so we know each time the reverb changes
  386. Platform::outputDebugString("Updated");
  387. ///load an efxeaxreverb default and add our values from
  388. ///sfxreverbproperties to it
  389. EFXEAXREVERBPROPERTIES prop = EFX_REVERB_PRESET_GENERIC;
  390. prop.flDensity = reverb.flDensity;
  391. prop.flDiffusion = reverb.flDiffusion;
  392. prop.flGain = reverb.flGain;
  393. prop.flGainHF = reverb.flGainHF;
  394. prop.flGainLF = reverb.flGainLF;
  395. prop.flDecayTime = reverb.flDecayTime;
  396. prop.flDecayHFRatio = reverb.flDecayHFRatio;
  397. prop.flDecayLFRatio = reverb.flDecayLFRatio;
  398. prop.flReflectionsGain = reverb.flReflectionsGain;
  399. prop.flReflectionsDelay = reverb.flReflectionsDelay;
  400. prop.flLateReverbGain = reverb.flLateReverbGain;
  401. prop.flLateReverbDelay = reverb.flLateReverbDelay;
  402. prop.flEchoTime = reverb.flEchoTime;
  403. prop.flEchoDepth = reverb.flEchoDepth;
  404. prop.flModulationTime = reverb.flModulationTime;
  405. prop.flModulationDepth = reverb.flModulationDepth;
  406. prop.flAirAbsorptionGainHF = reverb.flAirAbsorptionGainHF;
  407. prop.flHFReference = reverb.flHFReference;
  408. prop.flLFReference = reverb.flLFReference;
  409. prop.flRoomRolloffFactor = reverb.flRoomRolloffFactor;
  410. prop.iDecayHFLimit = reverb.iDecayHFLimit;
  411. if (mOpenAL.alGetEnumValue("AL_EFFECT_EAXREVERB") != 0)
  412. {
  413. /// EAX Reverb is available. Set the EAX effect type
  414. mOpenAL.alEffecti(effect[0], AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB);
  415. ///add our values to the setup of the reverb
  416. mOpenAL.alEffectf(effect[0], AL_EAXREVERB_DENSITY, prop.flDensity);
  417. mOpenAL.alEffectf(effect[0], AL_EAXREVERB_DIFFUSION, prop.flDiffusion);
  418. mOpenAL.alEffectf(effect[0], AL_EAXREVERB_GAIN, prop.flGain);
  419. mOpenAL.alEffectf(effect[0], AL_EAXREVERB_GAINHF, prop.flGainHF);
  420. mOpenAL.alEffectf(effect[0], AL_EAXREVERB_GAINLF, prop.flGainLF);
  421. mOpenAL.alEffectf(effect[0], AL_EAXREVERB_DECAY_TIME, prop.flDecayTime);
  422. mOpenAL.alEffectf(effect[0], AL_EAXREVERB_DECAY_HFRATIO, prop.flDecayHFRatio);
  423. mOpenAL.alEffectf(effect[0], AL_EAXREVERB_DECAY_LFRATIO, prop.flDecayLFRatio);
  424. mOpenAL.alEffectf(effect[0], AL_EAXREVERB_REFLECTIONS_GAIN, prop.flReflectionsGain);
  425. mOpenAL.alEffectf(effect[0], AL_EAXREVERB_REFLECTIONS_DELAY, prop.flReflectionsDelay);
  426. mOpenAL.alEffectf(effect[0], AL_EAXREVERB_LATE_REVERB_GAIN, prop.flLateReverbGain);
  427. mOpenAL.alEffectf(effect[0], AL_EAXREVERB_LATE_REVERB_DELAY, prop.flLateReverbDelay);
  428. mOpenAL.alEffectf(effect[0], AL_EAXREVERB_ECHO_TIME, prop.flEchoTime);
  429. mOpenAL.alEffectf(effect[0], AL_EAXREVERB_ECHO_DEPTH, prop.flEchoDepth);
  430. mOpenAL.alEffectf(effect[0], AL_EAXREVERB_MODULATION_TIME, prop.flModulationTime);
  431. mOpenAL.alEffectf(effect[0], AL_EAXREVERB_MODULATION_DEPTH, prop.flModulationDepth);
  432. mOpenAL.alEffectf(effect[0], AL_EAXREVERB_AIR_ABSORPTION_GAINHF, prop.flAirAbsorptionGainHF);
  433. mOpenAL.alEffectf(effect[0], AL_EAXREVERB_HFREFERENCE, prop.flHFReference);
  434. mOpenAL.alEffectf(effect[0], AL_EAXREVERB_LFREFERENCE, prop.flLFReference);
  435. mOpenAL.alEffectf(effect[0], AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, prop.flRoomRolloffFactor);
  436. mOpenAL.alEffecti(effect[0], AL_EAXREVERB_DECAY_HFLIMIT, prop.iDecayHFLimit);
  437. mOpenAL.alAuxiliaryEffectSloti(1, AL_EFFECTSLOT_EFFECT, effect[0]);
  438. Platform::outputDebugString("eax reverb properties set");
  439. }
  440. else
  441. {
  442. /// No EAX Reverb. Set the standard reverb effect
  443. mOpenAL.alEffecti(effect[0], AL_EFFECT_TYPE, AL_EFFECT_REVERB);
  444. mOpenAL.alEffectf(effect[0], AL_REVERB_DENSITY, prop.flDensity);
  445. mOpenAL.alEffectf(effect[0], AL_REVERB_DIFFUSION, prop.flDiffusion);
  446. mOpenAL.alEffectf(effect[0], AL_REVERB_GAIN, prop.flGain);
  447. mOpenAL.alEffectf(effect[0], AL_REVERB_GAINHF, prop.flGainHF);
  448. mOpenAL.alEffectf(effect[0], AL_REVERB_DECAY_TIME, prop.flDecayTime);
  449. mOpenAL.alEffectf(effect[0], AL_REVERB_DECAY_HFRATIO, prop.flDecayHFRatio);
  450. mOpenAL.alEffectf(effect[0], AL_REVERB_REFLECTIONS_GAIN, prop.flReflectionsGain);
  451. mOpenAL.alEffectf(effect[0], AL_REVERB_REFLECTIONS_DELAY, prop.flReflectionsDelay);
  452. mOpenAL.alEffectf(effect[0], AL_REVERB_LATE_REVERB_GAIN, prop.flLateReverbGain);
  453. mOpenAL.alEffectf(effect[0], AL_REVERB_LATE_REVERB_DELAY, prop.flLateReverbDelay);
  454. mOpenAL.alEffectf(effect[0], AL_REVERB_AIR_ABSORPTION_GAINHF, prop.flAirAbsorptionGainHF);
  455. mOpenAL.alEffectf(effect[0], AL_REVERB_ROOM_ROLLOFF_FACTOR, prop.flRoomRolloffFactor);
  456. mOpenAL.alEffecti(effect[0], AL_REVERB_DECAY_HFLIMIT, prop.iDecayHFLimit);
  457. mOpenAL.alAuxiliaryEffectSloti(1, AL_EFFECTSLOT_EFFECT, effect[0]);
  458. }
  459. }
  460. #endif