🛠️🐜 Antkeeper superbuild with dependencies included https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2542 lines
78 KiB

  1. #include "config.h"
  2. #include <cmath>
  3. #include "AL/al.h"
  4. #include "AL/efx.h"
  5. #include "alc/effects/base.h"
  6. #include "effects.h"
  7. #ifdef ALSOFT_EAX
  8. #include <tuple>
  9. #include "alnumeric.h"
  10. #include "AL/efx-presets.h"
  11. #include "al/eax_exception.h"
  12. #include "al/eax_utils.h"
  13. #endif // ALSOFT_EAX
  14. namespace {
  15. void Reverb_setParami(EffectProps *props, ALenum param, int val)
  16. {
  17. switch(param)
  18. {
  19. case AL_EAXREVERB_DECAY_HFLIMIT:
  20. if(!(val >= AL_EAXREVERB_MIN_DECAY_HFLIMIT && val <= AL_EAXREVERB_MAX_DECAY_HFLIMIT))
  21. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay hflimit out of range"};
  22. props->Reverb.DecayHFLimit = val != AL_FALSE;
  23. break;
  24. default:
  25. throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb integer property 0x%04x",
  26. param};
  27. }
  28. }
  29. void Reverb_setParamiv(EffectProps *props, ALenum param, const int *vals)
  30. { Reverb_setParami(props, param, vals[0]); }
  31. void Reverb_setParamf(EffectProps *props, ALenum param, float val)
  32. {
  33. switch(param)
  34. {
  35. case AL_EAXREVERB_DENSITY:
  36. if(!(val >= AL_EAXREVERB_MIN_DENSITY && val <= AL_EAXREVERB_MAX_DENSITY))
  37. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb density out of range"};
  38. props->Reverb.Density = val;
  39. break;
  40. case AL_EAXREVERB_DIFFUSION:
  41. if(!(val >= AL_EAXREVERB_MIN_DIFFUSION && val <= AL_EAXREVERB_MAX_DIFFUSION))
  42. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb diffusion out of range"};
  43. props->Reverb.Diffusion = val;
  44. break;
  45. case AL_EAXREVERB_GAIN:
  46. if(!(val >= AL_EAXREVERB_MIN_GAIN && val <= AL_EAXREVERB_MAX_GAIN))
  47. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gain out of range"};
  48. props->Reverb.Gain = val;
  49. break;
  50. case AL_EAXREVERB_GAINHF:
  51. if(!(val >= AL_EAXREVERB_MIN_GAINHF && val <= AL_EAXREVERB_MAX_GAINHF))
  52. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gainhf out of range"};
  53. props->Reverb.GainHF = val;
  54. break;
  55. case AL_EAXREVERB_GAINLF:
  56. if(!(val >= AL_EAXREVERB_MIN_GAINLF && val <= AL_EAXREVERB_MAX_GAINLF))
  57. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gainlf out of range"};
  58. props->Reverb.GainLF = val;
  59. break;
  60. case AL_EAXREVERB_DECAY_TIME:
  61. if(!(val >= AL_EAXREVERB_MIN_DECAY_TIME && val <= AL_EAXREVERB_MAX_DECAY_TIME))
  62. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay time out of range"};
  63. props->Reverb.DecayTime = val;
  64. break;
  65. case AL_EAXREVERB_DECAY_HFRATIO:
  66. if(!(val >= AL_EAXREVERB_MIN_DECAY_HFRATIO && val <= AL_EAXREVERB_MAX_DECAY_HFRATIO))
  67. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay hfratio out of range"};
  68. props->Reverb.DecayHFRatio = val;
  69. break;
  70. case AL_EAXREVERB_DECAY_LFRATIO:
  71. if(!(val >= AL_EAXREVERB_MIN_DECAY_LFRATIO && val <= AL_EAXREVERB_MAX_DECAY_LFRATIO))
  72. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay lfratio out of range"};
  73. props->Reverb.DecayLFRatio = val;
  74. break;
  75. case AL_EAXREVERB_REFLECTIONS_GAIN:
  76. if(!(val >= AL_EAXREVERB_MIN_REFLECTIONS_GAIN && val <= AL_EAXREVERB_MAX_REFLECTIONS_GAIN))
  77. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections gain out of range"};
  78. props->Reverb.ReflectionsGain = val;
  79. break;
  80. case AL_EAXREVERB_REFLECTIONS_DELAY:
  81. if(!(val >= AL_EAXREVERB_MIN_REFLECTIONS_DELAY && val <= AL_EAXREVERB_MAX_REFLECTIONS_DELAY))
  82. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections delay out of range"};
  83. props->Reverb.ReflectionsDelay = val;
  84. break;
  85. case AL_EAXREVERB_LATE_REVERB_GAIN:
  86. if(!(val >= AL_EAXREVERB_MIN_LATE_REVERB_GAIN && val <= AL_EAXREVERB_MAX_LATE_REVERB_GAIN))
  87. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb gain out of range"};
  88. props->Reverb.LateReverbGain = val;
  89. break;
  90. case AL_EAXREVERB_LATE_REVERB_DELAY:
  91. if(!(val >= AL_EAXREVERB_MIN_LATE_REVERB_DELAY && val <= AL_EAXREVERB_MAX_LATE_REVERB_DELAY))
  92. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb delay out of range"};
  93. props->Reverb.LateReverbDelay = val;
  94. break;
  95. case AL_EAXREVERB_AIR_ABSORPTION_GAINHF:
  96. if(!(val >= AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF && val <= AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF))
  97. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb air absorption gainhf out of range"};
  98. props->Reverb.AirAbsorptionGainHF = val;
  99. break;
  100. case AL_EAXREVERB_ECHO_TIME:
  101. if(!(val >= AL_EAXREVERB_MIN_ECHO_TIME && val <= AL_EAXREVERB_MAX_ECHO_TIME))
  102. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb echo time out of range"};
  103. props->Reverb.EchoTime = val;
  104. break;
  105. case AL_EAXREVERB_ECHO_DEPTH:
  106. if(!(val >= AL_EAXREVERB_MIN_ECHO_DEPTH && val <= AL_EAXREVERB_MAX_ECHO_DEPTH))
  107. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb echo depth out of range"};
  108. props->Reverb.EchoDepth = val;
  109. break;
  110. case AL_EAXREVERB_MODULATION_TIME:
  111. if(!(val >= AL_EAXREVERB_MIN_MODULATION_TIME && val <= AL_EAXREVERB_MAX_MODULATION_TIME))
  112. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb modulation time out of range"};
  113. props->Reverb.ModulationTime = val;
  114. break;
  115. case AL_EAXREVERB_MODULATION_DEPTH:
  116. if(!(val >= AL_EAXREVERB_MIN_MODULATION_DEPTH && val <= AL_EAXREVERB_MAX_MODULATION_DEPTH))
  117. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb modulation depth out of range"};
  118. props->Reverb.ModulationDepth = val;
  119. break;
  120. case AL_EAXREVERB_HFREFERENCE:
  121. if(!(val >= AL_EAXREVERB_MIN_HFREFERENCE && val <= AL_EAXREVERB_MAX_HFREFERENCE))
  122. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb hfreference out of range"};
  123. props->Reverb.HFReference = val;
  124. break;
  125. case AL_EAXREVERB_LFREFERENCE:
  126. if(!(val >= AL_EAXREVERB_MIN_LFREFERENCE && val <= AL_EAXREVERB_MAX_LFREFERENCE))
  127. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb lfreference out of range"};
  128. props->Reverb.LFReference = val;
  129. break;
  130. case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR:
  131. if(!(val >= AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR && val <= AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR))
  132. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb room rolloff factor out of range"};
  133. props->Reverb.RoomRolloffFactor = val;
  134. break;
  135. default:
  136. throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", param};
  137. }
  138. }
  139. void Reverb_setParamfv(EffectProps *props, ALenum param, const float *vals)
  140. {
  141. switch(param)
  142. {
  143. case AL_EAXREVERB_REFLECTIONS_PAN:
  144. if(!(std::isfinite(vals[0]) && std::isfinite(vals[1]) && std::isfinite(vals[2])))
  145. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections pan out of range"};
  146. props->Reverb.ReflectionsPan[0] = vals[0];
  147. props->Reverb.ReflectionsPan[1] = vals[1];
  148. props->Reverb.ReflectionsPan[2] = vals[2];
  149. break;
  150. case AL_EAXREVERB_LATE_REVERB_PAN:
  151. if(!(std::isfinite(vals[0]) && std::isfinite(vals[1]) && std::isfinite(vals[2])))
  152. throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb pan out of range"};
  153. props->Reverb.LateReverbPan[0] = vals[0];
  154. props->Reverb.LateReverbPan[1] = vals[1];
  155. props->Reverb.LateReverbPan[2] = vals[2];
  156. break;
  157. default:
  158. Reverb_setParamf(props, param, vals[0]);
  159. break;
  160. }
  161. }
  162. void Reverb_getParami(const EffectProps *props, ALenum param, int *val)
  163. {
  164. switch(param)
  165. {
  166. case AL_EAXREVERB_DECAY_HFLIMIT:
  167. *val = props->Reverb.DecayHFLimit;
  168. break;
  169. default:
  170. throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb integer property 0x%04x",
  171. param};
  172. }
  173. }
  174. void Reverb_getParamiv(const EffectProps *props, ALenum param, int *vals)
  175. { Reverb_getParami(props, param, vals); }
  176. void Reverb_getParamf(const EffectProps *props, ALenum param, float *val)
  177. {
  178. switch(param)
  179. {
  180. case AL_EAXREVERB_DENSITY:
  181. *val = props->Reverb.Density;
  182. break;
  183. case AL_EAXREVERB_DIFFUSION:
  184. *val = props->Reverb.Diffusion;
  185. break;
  186. case AL_EAXREVERB_GAIN:
  187. *val = props->Reverb.Gain;
  188. break;
  189. case AL_EAXREVERB_GAINHF:
  190. *val = props->Reverb.GainHF;
  191. break;
  192. case AL_EAXREVERB_GAINLF:
  193. *val = props->Reverb.GainLF;
  194. break;
  195. case AL_EAXREVERB_DECAY_TIME:
  196. *val = props->Reverb.DecayTime;
  197. break;
  198. case AL_EAXREVERB_DECAY_HFRATIO:
  199. *val = props->Reverb.DecayHFRatio;
  200. break;
  201. case AL_EAXREVERB_DECAY_LFRATIO:
  202. *val = props->Reverb.DecayLFRatio;
  203. break;
  204. case AL_EAXREVERB_REFLECTIONS_GAIN:
  205. *val = props->Reverb.ReflectionsGain;
  206. break;
  207. case AL_EAXREVERB_REFLECTIONS_DELAY:
  208. *val = props->Reverb.ReflectionsDelay;
  209. break;
  210. case AL_EAXREVERB_LATE_REVERB_GAIN:
  211. *val = props->Reverb.LateReverbGain;
  212. break;
  213. case AL_EAXREVERB_LATE_REVERB_DELAY:
  214. *val = props->Reverb.LateReverbDelay;
  215. break;
  216. case AL_EAXREVERB_AIR_ABSORPTION_GAINHF:
  217. *val = props->Reverb.AirAbsorptionGainHF;
  218. break;
  219. case AL_EAXREVERB_ECHO_TIME:
  220. *val = props->Reverb.EchoTime;
  221. break;
  222. case AL_EAXREVERB_ECHO_DEPTH:
  223. *val = props->Reverb.EchoDepth;
  224. break;
  225. case AL_EAXREVERB_MODULATION_TIME:
  226. *val = props->Reverb.ModulationTime;
  227. break;
  228. case AL_EAXREVERB_MODULATION_DEPTH:
  229. *val = props->Reverb.ModulationDepth;
  230. break;
  231. case AL_EAXREVERB_HFREFERENCE:
  232. *val = props->Reverb.HFReference;
  233. break;
  234. case AL_EAXREVERB_LFREFERENCE:
  235. *val = props->Reverb.LFReference;
  236. break;
  237. case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR:
  238. *val = props->Reverb.RoomRolloffFactor;
  239. break;
  240. default:
  241. throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", param};
  242. }
  243. }
  244. void Reverb_getParamfv(const EffectProps *props, ALenum param, float *vals)
  245. {
  246. switch(param)
  247. {
  248. case AL_EAXREVERB_REFLECTIONS_PAN:
  249. vals[0] = props->Reverb.ReflectionsPan[0];
  250. vals[1] = props->Reverb.ReflectionsPan[1];
  251. vals[2] = props->Reverb.ReflectionsPan[2];
  252. break;
  253. case AL_EAXREVERB_LATE_REVERB_PAN:
  254. vals[0] = props->Reverb.LateReverbPan[0];
  255. vals[1] = props->Reverb.LateReverbPan[1];
  256. vals[2] = props->Reverb.LateReverbPan[2];
  257. break;
  258. default:
  259. Reverb_getParamf(props, param, vals);
  260. break;
  261. }
  262. }
  263. EffectProps genDefaultProps() noexcept
  264. {
  265. EffectProps props{};
  266. props.Reverb.Density = AL_EAXREVERB_DEFAULT_DENSITY;
  267. props.Reverb.Diffusion = AL_EAXREVERB_DEFAULT_DIFFUSION;
  268. props.Reverb.Gain = AL_EAXREVERB_DEFAULT_GAIN;
  269. props.Reverb.GainHF = AL_EAXREVERB_DEFAULT_GAINHF;
  270. props.Reverb.GainLF = AL_EAXREVERB_DEFAULT_GAINLF;
  271. props.Reverb.DecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME;
  272. props.Reverb.DecayHFRatio = AL_EAXREVERB_DEFAULT_DECAY_HFRATIO;
  273. props.Reverb.DecayLFRatio = AL_EAXREVERB_DEFAULT_DECAY_LFRATIO;
  274. props.Reverb.ReflectionsGain = AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN;
  275. props.Reverb.ReflectionsDelay = AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY;
  276. props.Reverb.ReflectionsPan[0] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
  277. props.Reverb.ReflectionsPan[1] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
  278. props.Reverb.ReflectionsPan[2] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
  279. props.Reverb.LateReverbGain = AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN;
  280. props.Reverb.LateReverbDelay = AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY;
  281. props.Reverb.LateReverbPan[0] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
  282. props.Reverb.LateReverbPan[1] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
  283. props.Reverb.LateReverbPan[2] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
  284. props.Reverb.EchoTime = AL_EAXREVERB_DEFAULT_ECHO_TIME;
  285. props.Reverb.EchoDepth = AL_EAXREVERB_DEFAULT_ECHO_DEPTH;
  286. props.Reverb.ModulationTime = AL_EAXREVERB_DEFAULT_MODULATION_TIME;
  287. props.Reverb.ModulationDepth = AL_EAXREVERB_DEFAULT_MODULATION_DEPTH;
  288. props.Reverb.AirAbsorptionGainHF = AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF;
  289. props.Reverb.HFReference = AL_EAXREVERB_DEFAULT_HFREFERENCE;
  290. props.Reverb.LFReference = AL_EAXREVERB_DEFAULT_LFREFERENCE;
  291. props.Reverb.RoomRolloffFactor = AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR;
  292. props.Reverb.DecayHFLimit = AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT;
  293. return props;
  294. }
  295. void StdReverb_setParami(EffectProps *props, ALenum param, int val)
  296. {
  297. switch(param)
  298. {
  299. case AL_REVERB_DECAY_HFLIMIT:
  300. if(!(val >= AL_REVERB_MIN_DECAY_HFLIMIT && val <= AL_REVERB_MAX_DECAY_HFLIMIT))
  301. throw effect_exception{AL_INVALID_VALUE, "Reverb decay hflimit out of range"};
  302. props->Reverb.DecayHFLimit = val != AL_FALSE;
  303. break;
  304. default:
  305. throw effect_exception{AL_INVALID_ENUM, "Invalid reverb integer property 0x%04x", param};
  306. }
  307. }
  308. void StdReverb_setParamiv(EffectProps *props, ALenum param, const int *vals)
  309. { StdReverb_setParami(props, param, vals[0]); }
  310. void StdReverb_setParamf(EffectProps *props, ALenum param, float val)
  311. {
  312. switch(param)
  313. {
  314. case AL_REVERB_DENSITY:
  315. if(!(val >= AL_REVERB_MIN_DENSITY && val <= AL_REVERB_MAX_DENSITY))
  316. throw effect_exception{AL_INVALID_VALUE, "Reverb density out of range"};
  317. props->Reverb.Density = val;
  318. break;
  319. case AL_REVERB_DIFFUSION:
  320. if(!(val >= AL_REVERB_MIN_DIFFUSION && val <= AL_REVERB_MAX_DIFFUSION))
  321. throw effect_exception{AL_INVALID_VALUE, "Reverb diffusion out of range"};
  322. props->Reverb.Diffusion = val;
  323. break;
  324. case AL_REVERB_GAIN:
  325. if(!(val >= AL_REVERB_MIN_GAIN && val <= AL_REVERB_MAX_GAIN))
  326. throw effect_exception{AL_INVALID_VALUE, "Reverb gain out of range"};
  327. props->Reverb.Gain = val;
  328. break;
  329. case AL_REVERB_GAINHF:
  330. if(!(val >= AL_REVERB_MIN_GAINHF && val <= AL_REVERB_MAX_GAINHF))
  331. throw effect_exception{AL_INVALID_VALUE, "Reverb gainhf out of range"};
  332. props->Reverb.GainHF = val;
  333. break;
  334. case AL_REVERB_DECAY_TIME:
  335. if(!(val >= AL_REVERB_MIN_DECAY_TIME && val <= AL_REVERB_MAX_DECAY_TIME))
  336. throw effect_exception{AL_INVALID_VALUE, "Reverb decay time out of range"};
  337. props->Reverb.DecayTime = val;
  338. break;
  339. case AL_REVERB_DECAY_HFRATIO:
  340. if(!(val >= AL_REVERB_MIN_DECAY_HFRATIO && val <= AL_REVERB_MAX_DECAY_HFRATIO))
  341. throw effect_exception{AL_INVALID_VALUE, "Reverb decay hfratio out of range"};
  342. props->Reverb.DecayHFRatio = val;
  343. break;
  344. case AL_REVERB_REFLECTIONS_GAIN:
  345. if(!(val >= AL_REVERB_MIN_REFLECTIONS_GAIN && val <= AL_REVERB_MAX_REFLECTIONS_GAIN))
  346. throw effect_exception{AL_INVALID_VALUE, "Reverb reflections gain out of range"};
  347. props->Reverb.ReflectionsGain = val;
  348. break;
  349. case AL_REVERB_REFLECTIONS_DELAY:
  350. if(!(val >= AL_REVERB_MIN_REFLECTIONS_DELAY && val <= AL_REVERB_MAX_REFLECTIONS_DELAY))
  351. throw effect_exception{AL_INVALID_VALUE, "Reverb reflections delay out of range"};
  352. props->Reverb.ReflectionsDelay = val;
  353. break;
  354. case AL_REVERB_LATE_REVERB_GAIN:
  355. if(!(val >= AL_REVERB_MIN_LATE_REVERB_GAIN && val <= AL_REVERB_MAX_LATE_REVERB_GAIN))
  356. throw effect_exception{AL_INVALID_VALUE, "Reverb late reverb gain out of range"};
  357. props->Reverb.LateReverbGain = val;
  358. break;
  359. case AL_REVERB_LATE_REVERB_DELAY:
  360. if(!(val >= AL_REVERB_MIN_LATE_REVERB_DELAY && val <= AL_REVERB_MAX_LATE_REVERB_DELAY))
  361. throw effect_exception{AL_INVALID_VALUE, "Reverb late reverb delay out of range"};
  362. props->Reverb.LateReverbDelay = val;
  363. break;
  364. case AL_REVERB_AIR_ABSORPTION_GAINHF:
  365. if(!(val >= AL_REVERB_MIN_AIR_ABSORPTION_GAINHF && val <= AL_REVERB_MAX_AIR_ABSORPTION_GAINHF))
  366. throw effect_exception{AL_INVALID_VALUE, "Reverb air absorption gainhf out of range"};
  367. props->Reverb.AirAbsorptionGainHF = val;
  368. break;
  369. case AL_REVERB_ROOM_ROLLOFF_FACTOR:
  370. if(!(val >= AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR && val <= AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR))
  371. throw effect_exception{AL_INVALID_VALUE, "Reverb room rolloff factor out of range"};
  372. props->Reverb.RoomRolloffFactor = val;
  373. break;
  374. default:
  375. throw effect_exception{AL_INVALID_ENUM, "Invalid reverb float property 0x%04x", param};
  376. }
  377. }
  378. void StdReverb_setParamfv(EffectProps *props, ALenum param, const float *vals)
  379. { StdReverb_setParamf(props, param, vals[0]); }
  380. void StdReverb_getParami(const EffectProps *props, ALenum param, int *val)
  381. {
  382. switch(param)
  383. {
  384. case AL_REVERB_DECAY_HFLIMIT:
  385. *val = props->Reverb.DecayHFLimit;
  386. break;
  387. default:
  388. throw effect_exception{AL_INVALID_ENUM, "Invalid reverb integer property 0x%04x", param};
  389. }
  390. }
  391. void StdReverb_getParamiv(const EffectProps *props, ALenum param, int *vals)
  392. { StdReverb_getParami(props, param, vals); }
  393. void StdReverb_getParamf(const EffectProps *props, ALenum param, float *val)
  394. {
  395. switch(param)
  396. {
  397. case AL_REVERB_DENSITY:
  398. *val = props->Reverb.Density;
  399. break;
  400. case AL_REVERB_DIFFUSION:
  401. *val = props->Reverb.Diffusion;
  402. break;
  403. case AL_REVERB_GAIN:
  404. *val = props->Reverb.Gain;
  405. break;
  406. case AL_REVERB_GAINHF:
  407. *val = props->Reverb.GainHF;
  408. break;
  409. case AL_REVERB_DECAY_TIME:
  410. *val = props->Reverb.DecayTime;
  411. break;
  412. case AL_REVERB_DECAY_HFRATIO:
  413. *val = props->Reverb.DecayHFRatio;
  414. break;
  415. case AL_REVERB_REFLECTIONS_GAIN:
  416. *val = props->Reverb.ReflectionsGain;
  417. break;
  418. case AL_REVERB_REFLECTIONS_DELAY:
  419. *val = props->Reverb.ReflectionsDelay;
  420. break;
  421. case AL_REVERB_LATE_REVERB_GAIN:
  422. *val = props->Reverb.LateReverbGain;
  423. break;
  424. case AL_REVERB_LATE_REVERB_DELAY:
  425. *val = props->Reverb.LateReverbDelay;
  426. break;
  427. case AL_REVERB_AIR_ABSORPTION_GAINHF:
  428. *val = props->Reverb.AirAbsorptionGainHF;
  429. break;
  430. case AL_REVERB_ROOM_ROLLOFF_FACTOR:
  431. *val = props->Reverb.RoomRolloffFactor;
  432. break;
  433. default:
  434. throw effect_exception{AL_INVALID_ENUM, "Invalid reverb float property 0x%04x", param};
  435. }
  436. }
  437. void StdReverb_getParamfv(const EffectProps *props, ALenum param, float *vals)
  438. { StdReverb_getParamf(props, param, vals); }
  439. EffectProps genDefaultStdProps() noexcept
  440. {
  441. EffectProps props{};
  442. props.Reverb.Density = AL_REVERB_DEFAULT_DENSITY;
  443. props.Reverb.Diffusion = AL_REVERB_DEFAULT_DIFFUSION;
  444. props.Reverb.Gain = AL_REVERB_DEFAULT_GAIN;
  445. props.Reverb.GainHF = AL_REVERB_DEFAULT_GAINHF;
  446. props.Reverb.GainLF = 1.0f;
  447. props.Reverb.DecayTime = AL_REVERB_DEFAULT_DECAY_TIME;
  448. props.Reverb.DecayHFRatio = AL_REVERB_DEFAULT_DECAY_HFRATIO;
  449. props.Reverb.DecayLFRatio = 1.0f;
  450. props.Reverb.ReflectionsGain = AL_REVERB_DEFAULT_REFLECTIONS_GAIN;
  451. props.Reverb.ReflectionsDelay = AL_REVERB_DEFAULT_REFLECTIONS_DELAY;
  452. props.Reverb.ReflectionsPan[0] = 0.0f;
  453. props.Reverb.ReflectionsPan[1] = 0.0f;
  454. props.Reverb.ReflectionsPan[2] = 0.0f;
  455. props.Reverb.LateReverbGain = AL_REVERB_DEFAULT_LATE_REVERB_GAIN;
  456. props.Reverb.LateReverbDelay = AL_REVERB_DEFAULT_LATE_REVERB_DELAY;
  457. props.Reverb.LateReverbPan[0] = 0.0f;
  458. props.Reverb.LateReverbPan[1] = 0.0f;
  459. props.Reverb.LateReverbPan[2] = 0.0f;
  460. props.Reverb.EchoTime = 0.25f;
  461. props.Reverb.EchoDepth = 0.0f;
  462. props.Reverb.ModulationTime = 0.25f;
  463. props.Reverb.ModulationDepth = 0.0f;
  464. props.Reverb.AirAbsorptionGainHF = AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF;
  465. props.Reverb.HFReference = 5000.0f;
  466. props.Reverb.LFReference = 250.0f;
  467. props.Reverb.RoomRolloffFactor = AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR;
  468. props.Reverb.DecayHFLimit = AL_REVERB_DEFAULT_DECAY_HFLIMIT;
  469. return props;
  470. }
  471. } // namespace
  472. DEFINE_ALEFFECT_VTABLE(Reverb);
  473. const EffectProps ReverbEffectProps{genDefaultProps()};
  474. DEFINE_ALEFFECT_VTABLE(StdReverb);
  475. const EffectProps StdReverbEffectProps{genDefaultStdProps()};
  476. #ifdef ALSOFT_EAX
  477. namespace {
  478. extern const EFXEAXREVERBPROPERTIES eax_efx_reverb_presets[];
  479. using EaxReverbEffectDirtyFlagsValue = std::uint_least32_t;
  480. struct EaxReverbEffectDirtyFlags
  481. {
  482. using EaxIsBitFieldStruct = bool;
  483. EaxReverbEffectDirtyFlagsValue ulEnvironment : 1;
  484. EaxReverbEffectDirtyFlagsValue flEnvironmentSize : 1;
  485. EaxReverbEffectDirtyFlagsValue flEnvironmentDiffusion : 1;
  486. EaxReverbEffectDirtyFlagsValue lRoom : 1;
  487. EaxReverbEffectDirtyFlagsValue lRoomHF : 1;
  488. EaxReverbEffectDirtyFlagsValue lRoomLF : 1;
  489. EaxReverbEffectDirtyFlagsValue flDecayTime : 1;
  490. EaxReverbEffectDirtyFlagsValue flDecayHFRatio : 1;
  491. EaxReverbEffectDirtyFlagsValue flDecayLFRatio : 1;
  492. EaxReverbEffectDirtyFlagsValue lReflections : 1;
  493. EaxReverbEffectDirtyFlagsValue flReflectionsDelay : 1;
  494. EaxReverbEffectDirtyFlagsValue vReflectionsPan : 1;
  495. EaxReverbEffectDirtyFlagsValue lReverb : 1;
  496. EaxReverbEffectDirtyFlagsValue flReverbDelay : 1;
  497. EaxReverbEffectDirtyFlagsValue vReverbPan : 1;
  498. EaxReverbEffectDirtyFlagsValue flEchoTime : 1;
  499. EaxReverbEffectDirtyFlagsValue flEchoDepth : 1;
  500. EaxReverbEffectDirtyFlagsValue flModulationTime : 1;
  501. EaxReverbEffectDirtyFlagsValue flModulationDepth : 1;
  502. EaxReverbEffectDirtyFlagsValue flAirAbsorptionHF : 1;
  503. EaxReverbEffectDirtyFlagsValue flHFReference : 1;
  504. EaxReverbEffectDirtyFlagsValue flLFReference : 1;
  505. EaxReverbEffectDirtyFlagsValue flRoomRolloffFactor : 1;
  506. EaxReverbEffectDirtyFlagsValue ulFlags : 1;
  507. }; // EaxReverbEffectDirtyFlags
  508. struct Eax1ReverbEffectDirtyFlags
  509. {
  510. using EaxIsBitFieldStruct = bool;
  511. EaxReverbEffectDirtyFlagsValue ulEnvironment : 1;
  512. EaxReverbEffectDirtyFlagsValue flVolume : 1;
  513. EaxReverbEffectDirtyFlagsValue flDecayTime : 1;
  514. EaxReverbEffectDirtyFlagsValue flDamping : 1;
  515. }; // Eax1ReverbEffectDirtyFlags
  516. class EaxReverbEffect final :
  517. public EaxEffect
  518. {
  519. public:
  520. EaxReverbEffect();
  521. void dispatch(const EaxEaxCall& eax_call) override;
  522. // [[nodiscard]]
  523. bool apply_deferred() override;
  524. private:
  525. EAX_REVERBPROPERTIES eax1_{};
  526. EAX_REVERBPROPERTIES eax1_d_{};
  527. Eax1ReverbEffectDirtyFlags eax1_dirty_flags_{};
  528. EAXREVERBPROPERTIES eax_{};
  529. EAXREVERBPROPERTIES eax_d_{};
  530. EaxReverbEffectDirtyFlags eax_dirty_flags_{};
  531. [[noreturn]] static void eax_fail(const char* message);
  532. void set_eax_defaults();
  533. void set_efx_density_from_environment_size();
  534. void set_efx_diffusion();
  535. void set_efx_gain();
  536. void set_efx_gain_hf();
  537. void set_efx_gain_lf();
  538. void set_efx_decay_time();
  539. void set_efx_decay_hf_ratio();
  540. void set_efx_decay_lf_ratio();
  541. void set_efx_reflections_gain();
  542. void set_efx_reflections_delay();
  543. void set_efx_reflections_pan();
  544. void set_efx_late_reverb_gain();
  545. void set_efx_late_reverb_delay();
  546. void set_efx_late_reverb_pan();
  547. void set_efx_echo_time();
  548. void set_efx_echo_depth();
  549. void set_efx_modulation_time();
  550. void set_efx_modulation_depth();
  551. void set_efx_air_absorption_gain_hf();
  552. void set_efx_hf_reference();
  553. void set_efx_lf_reference();
  554. void set_efx_room_rolloff_factor();
  555. void set_efx_flags();
  556. void set_efx_defaults();
  557. void v1_get(const EaxEaxCall& eax_call) const;
  558. void get_all(const EaxEaxCall& eax_call) const;
  559. void get(const EaxEaxCall& eax_call) const;
  560. static void v1_validate_environment(unsigned long environment);
  561. static void v1_validate_volume(float volume);
  562. static void v1_validate_decay_time(float decay_time);
  563. static void v1_validate_damping(float damping);
  564. static void v1_validate_all(const EAX_REVERBPROPERTIES& all);
  565. void v1_defer_environment(unsigned long environment);
  566. void v1_defer_volume(float volume);
  567. void v1_defer_decay_time(float decay_time);
  568. void v1_defer_damping(float damping);
  569. void v1_defer_all(const EAX_REVERBPROPERTIES& all);
  570. void v1_defer_environment(const EaxEaxCall& eax_call);
  571. void v1_defer_volume(const EaxEaxCall& eax_call);
  572. void v1_defer_decay_time(const EaxEaxCall& eax_call);
  573. void v1_defer_damping(const EaxEaxCall& eax_call);
  574. void v1_defer_all(const EaxEaxCall& eax_call);
  575. void v1_defer(const EaxEaxCall& eax_call);
  576. void v1_set_efx();
  577. static void validate_environment(unsigned long ulEnvironment, int version, bool is_standalone);
  578. static void validate_environment_size(float flEnvironmentSize);
  579. static void validate_environment_diffusion(float flEnvironmentDiffusion);
  580. static void validate_room(long lRoom);
  581. static void validate_room_hf(long lRoomHF);
  582. static void validate_room_lf(long lRoomLF);
  583. static void validate_decay_time(float flDecayTime);
  584. static void validate_decay_hf_ratio(float flDecayHFRatio);
  585. static void validate_decay_lf_ratio(float flDecayLFRatio);
  586. static void validate_reflections(long lReflections);
  587. static void validate_reflections_delay(float flReflectionsDelay);
  588. static void validate_reflections_pan(const EAXVECTOR& vReflectionsPan);
  589. static void validate_reverb(long lReverb);
  590. static void validate_reverb_delay(float flReverbDelay);
  591. static void validate_reverb_pan(const EAXVECTOR& vReverbPan);
  592. static void validate_echo_time(float flEchoTime);
  593. static void validate_echo_depth(float flEchoDepth);
  594. static void validate_modulation_time(float flModulationTime);
  595. static void validate_modulation_depth(float flModulationDepth);
  596. static void validate_air_absorbtion_hf(float air_absorbtion_hf);
  597. static void validate_hf_reference(float flHFReference);
  598. static void validate_lf_reference(float flLFReference);
  599. static void validate_room_rolloff_factor(float flRoomRolloffFactor);
  600. static void validate_flags(unsigned long ulFlags);
  601. static void validate_all(const EAX20LISTENERPROPERTIES& all, int version);
  602. static void validate_all(const EAXREVERBPROPERTIES& all, int version);
  603. void defer_environment(unsigned long ulEnvironment);
  604. void defer_environment_size(float flEnvironmentSize);
  605. void defer_environment_diffusion(float flEnvironmentDiffusion);
  606. void defer_room(long lRoom);
  607. void defer_room_hf(long lRoomHF);
  608. void defer_room_lf(long lRoomLF);
  609. void defer_decay_time(float flDecayTime);
  610. void defer_decay_hf_ratio(float flDecayHFRatio);
  611. void defer_decay_lf_ratio(float flDecayLFRatio);
  612. void defer_reflections(long lReflections);
  613. void defer_reflections_delay(float flReflectionsDelay);
  614. void defer_reflections_pan(const EAXVECTOR& vReflectionsPan);
  615. void defer_reverb(long lReverb);
  616. void defer_reverb_delay(float flReverbDelay);
  617. void defer_reverb_pan(const EAXVECTOR& vReverbPan);
  618. void defer_echo_time(float flEchoTime);
  619. void defer_echo_depth(float flEchoDepth);
  620. void defer_modulation_time(float flModulationTime);
  621. void defer_modulation_depth(float flModulationDepth);
  622. void defer_air_absorbtion_hf(float flAirAbsorptionHF);
  623. void defer_hf_reference(float flHFReference);
  624. void defer_lf_reference(float flLFReference);
  625. void defer_room_rolloff_factor(float flRoomRolloffFactor);
  626. void defer_flags(unsigned long ulFlags);
  627. void defer_all(const EAX20LISTENERPROPERTIES& all);
  628. void defer_all(const EAXREVERBPROPERTIES& all);
  629. void defer_environment(const EaxEaxCall& eax_call);
  630. void defer_environment_size(const EaxEaxCall& eax_call);
  631. void defer_environment_diffusion(const EaxEaxCall& eax_call);
  632. void defer_room(const EaxEaxCall& eax_call);
  633. void defer_room_hf(const EaxEaxCall& eax_call);
  634. void defer_room_lf(const EaxEaxCall& eax_call);
  635. void defer_decay_time(const EaxEaxCall& eax_call);
  636. void defer_decay_hf_ratio(const EaxEaxCall& eax_call);
  637. void defer_decay_lf_ratio(const EaxEaxCall& eax_call);
  638. void defer_reflections(const EaxEaxCall& eax_call);
  639. void defer_reflections_delay(const EaxEaxCall& eax_call);
  640. void defer_reflections_pan(const EaxEaxCall& eax_call);
  641. void defer_reverb(const EaxEaxCall& eax_call);
  642. void defer_reverb_delay(const EaxEaxCall& eax_call);
  643. void defer_reverb_pan(const EaxEaxCall& eax_call);
  644. void defer_echo_time(const EaxEaxCall& eax_call);
  645. void defer_echo_depth(const EaxEaxCall& eax_call);
  646. void defer_modulation_time(const EaxEaxCall& eax_call);
  647. void defer_modulation_depth(const EaxEaxCall& eax_call);
  648. void defer_air_absorbtion_hf(const EaxEaxCall& eax_call);
  649. void defer_hf_reference(const EaxEaxCall& eax_call);
  650. void defer_lf_reference(const EaxEaxCall& eax_call);
  651. void defer_room_rolloff_factor(const EaxEaxCall& eax_call);
  652. void defer_flags(const EaxEaxCall& eax_call);
  653. void defer_all(const EaxEaxCall& eax_call);
  654. void set(const EaxEaxCall& eax_call);
  655. }; // EaxReverbEffect
  656. class EaxReverbEffectException :
  657. public EaxException
  658. {
  659. public:
  660. explicit EaxReverbEffectException(
  661. const char* message)
  662. :
  663. EaxException{"EAX_REVERB_EFFECT", message}
  664. {
  665. }
  666. }; // EaxReverbEffectException
  667. EaxReverbEffect::EaxReverbEffect()
  668. : EaxEffect{AL_EFFECT_EAXREVERB}
  669. {
  670. set_eax_defaults();
  671. set_efx_defaults();
  672. }
  673. void EaxReverbEffect::dispatch(const EaxEaxCall& eax_call)
  674. {
  675. eax_call.is_get() ? get(eax_call) : set(eax_call);
  676. }
  677. [[noreturn]] void EaxReverbEffect::eax_fail(const char* message)
  678. {
  679. throw EaxReverbEffectException{message};
  680. }
  681. void EaxReverbEffect::set_eax_defaults()
  682. {
  683. eax1_ = EAX1REVERB_PRESETS[EAX_ENVIRONMENT_GENERIC];
  684. eax1_d_ = eax1_;
  685. eax_ = EAXREVERB_PRESETS[EAX_ENVIRONMENT_GENERIC];
  686. /* HACK: EAX2 has a default room volume of -10,000dB (silence), although
  687. * newer versions use -1,000dB. What should be happening is properties for
  688. * each EAX version is tracked separately, with the last version used for
  689. * the properties to apply (presumably v2 or nothing being the default).
  690. */
  691. eax_.lRoom = EAXREVERB_MINROOM;
  692. eax_d_ = eax_;
  693. }
  694. void EaxReverbEffect::set_efx_density_from_environment_size()
  695. {
  696. const auto eax_environment_size = eax_.flEnvironmentSize;
  697. const auto efx_density = clamp(
  698. (eax_environment_size * eax_environment_size * eax_environment_size) / 16.0F,
  699. AL_EAXREVERB_MIN_DENSITY,
  700. AL_EAXREVERB_MAX_DENSITY);
  701. al_effect_props_.Reverb.Density = efx_density;
  702. }
  703. void EaxReverbEffect::set_efx_diffusion()
  704. {
  705. const auto efx_diffusion = clamp(
  706. eax_.flEnvironmentDiffusion,
  707. AL_EAXREVERB_MIN_DIFFUSION,
  708. AL_EAXREVERB_MAX_DIFFUSION);
  709. al_effect_props_.Reverb.Diffusion = efx_diffusion;
  710. }
  711. void EaxReverbEffect::set_efx_gain()
  712. {
  713. const auto efx_gain = clamp(
  714. level_mb_to_gain(static_cast<float>(eax_.lRoom)),
  715. AL_EAXREVERB_MIN_GAIN,
  716. AL_EAXREVERB_MAX_GAIN);
  717. al_effect_props_.Reverb.Gain = efx_gain;
  718. }
  719. void EaxReverbEffect::set_efx_gain_hf()
  720. {
  721. const auto efx_gain_hf = clamp(
  722. level_mb_to_gain(static_cast<float>(eax_.lRoomHF)),
  723. AL_EAXREVERB_MIN_GAINHF,
  724. AL_EAXREVERB_MAX_GAINHF);
  725. al_effect_props_.Reverb.GainHF = efx_gain_hf;
  726. }
  727. void EaxReverbEffect::set_efx_gain_lf()
  728. {
  729. const auto efx_gain_lf = clamp(
  730. level_mb_to_gain(static_cast<float>(eax_.lRoomLF)),
  731. AL_EAXREVERB_MIN_GAINLF,
  732. AL_EAXREVERB_MAX_GAINLF);
  733. al_effect_props_.Reverb.GainLF = efx_gain_lf;
  734. }
  735. void EaxReverbEffect::set_efx_decay_time()
  736. {
  737. const auto efx_decay_time = clamp(
  738. eax_.flDecayTime,
  739. AL_EAXREVERB_MIN_DECAY_TIME,
  740. AL_EAXREVERB_MAX_DECAY_TIME);
  741. al_effect_props_.Reverb.DecayTime = efx_decay_time;
  742. }
  743. void EaxReverbEffect::set_efx_decay_hf_ratio()
  744. {
  745. const auto efx_decay_hf_ratio = clamp(
  746. eax_.flDecayHFRatio,
  747. AL_EAXREVERB_MIN_DECAY_HFRATIO,
  748. AL_EAXREVERB_MAX_DECAY_HFRATIO);
  749. al_effect_props_.Reverb.DecayHFRatio = efx_decay_hf_ratio;
  750. }
  751. void EaxReverbEffect::set_efx_decay_lf_ratio()
  752. {
  753. const auto efx_decay_lf_ratio = clamp(
  754. eax_.flDecayLFRatio,
  755. AL_EAXREVERB_MIN_DECAY_LFRATIO,
  756. AL_EAXREVERB_MAX_DECAY_LFRATIO);
  757. al_effect_props_.Reverb.DecayLFRatio = efx_decay_lf_ratio;
  758. }
  759. void EaxReverbEffect::set_efx_reflections_gain()
  760. {
  761. const auto efx_reflections_gain = clamp(
  762. level_mb_to_gain(static_cast<float>(eax_.lReflections)),
  763. AL_EAXREVERB_MIN_REFLECTIONS_GAIN,
  764. AL_EAXREVERB_MAX_REFLECTIONS_GAIN);
  765. al_effect_props_.Reverb.ReflectionsGain = efx_reflections_gain;
  766. }
  767. void EaxReverbEffect::set_efx_reflections_delay()
  768. {
  769. const auto efx_reflections_delay = clamp(
  770. eax_.flReflectionsDelay,
  771. AL_EAXREVERB_MIN_REFLECTIONS_DELAY,
  772. AL_EAXREVERB_MAX_REFLECTIONS_DELAY);
  773. al_effect_props_.Reverb.ReflectionsDelay = efx_reflections_delay;
  774. }
  775. void EaxReverbEffect::set_efx_reflections_pan()
  776. {
  777. al_effect_props_.Reverb.ReflectionsPan[0] = eax_.vReflectionsPan.x;
  778. al_effect_props_.Reverb.ReflectionsPan[1] = eax_.vReflectionsPan.y;
  779. al_effect_props_.Reverb.ReflectionsPan[2] = eax_.vReflectionsPan.z;
  780. }
  781. void EaxReverbEffect::set_efx_late_reverb_gain()
  782. {
  783. const auto efx_late_reverb_gain = clamp(
  784. level_mb_to_gain(static_cast<float>(eax_.lReverb)),
  785. AL_EAXREVERB_MIN_LATE_REVERB_GAIN,
  786. AL_EAXREVERB_MAX_LATE_REVERB_GAIN);
  787. al_effect_props_.Reverb.LateReverbGain = efx_late_reverb_gain;
  788. }
  789. void EaxReverbEffect::set_efx_late_reverb_delay()
  790. {
  791. const auto efx_late_reverb_delay = clamp(
  792. eax_.flReverbDelay,
  793. AL_EAXREVERB_MIN_LATE_REVERB_DELAY,
  794. AL_EAXREVERB_MAX_LATE_REVERB_DELAY);
  795. al_effect_props_.Reverb.LateReverbDelay = efx_late_reverb_delay;
  796. }
  797. void EaxReverbEffect::set_efx_late_reverb_pan()
  798. {
  799. al_effect_props_.Reverb.LateReverbPan[0] = eax_.vReverbPan.x;
  800. al_effect_props_.Reverb.LateReverbPan[1] = eax_.vReverbPan.y;
  801. al_effect_props_.Reverb.LateReverbPan[2] = eax_.vReverbPan.z;
  802. }
  803. void EaxReverbEffect::set_efx_echo_time()
  804. {
  805. const auto efx_echo_time = clamp(
  806. eax_.flEchoTime,
  807. AL_EAXREVERB_MIN_ECHO_TIME,
  808. AL_EAXREVERB_MAX_ECHO_TIME);
  809. al_effect_props_.Reverb.EchoTime = efx_echo_time;
  810. }
  811. void EaxReverbEffect::set_efx_echo_depth()
  812. {
  813. const auto efx_echo_depth = clamp(
  814. eax_.flEchoDepth,
  815. AL_EAXREVERB_MIN_ECHO_DEPTH,
  816. AL_EAXREVERB_MAX_ECHO_DEPTH);
  817. al_effect_props_.Reverb.EchoDepth = efx_echo_depth;
  818. }
  819. void EaxReverbEffect::set_efx_modulation_time()
  820. {
  821. const auto efx_modulation_time = clamp(
  822. eax_.flModulationTime,
  823. AL_EAXREVERB_MIN_MODULATION_TIME,
  824. AL_EAXREVERB_MAX_MODULATION_TIME);
  825. al_effect_props_.Reverb.ModulationTime = efx_modulation_time;
  826. }
  827. void EaxReverbEffect::set_efx_modulation_depth()
  828. {
  829. const auto efx_modulation_depth = clamp(
  830. eax_.flModulationDepth,
  831. AL_EAXREVERB_MIN_MODULATION_DEPTH,
  832. AL_EAXREVERB_MAX_MODULATION_DEPTH);
  833. al_effect_props_.Reverb.ModulationDepth = efx_modulation_depth;
  834. }
  835. void EaxReverbEffect::set_efx_air_absorption_gain_hf()
  836. {
  837. const auto efx_air_absorption_hf = clamp(
  838. level_mb_to_gain(eax_.flAirAbsorptionHF),
  839. AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF,
  840. AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF);
  841. al_effect_props_.Reverb.AirAbsorptionGainHF = efx_air_absorption_hf;
  842. }
  843. void EaxReverbEffect::set_efx_hf_reference()
  844. {
  845. const auto efx_hf_reference = clamp(
  846. eax_.flHFReference,
  847. AL_EAXREVERB_MIN_HFREFERENCE,
  848. AL_EAXREVERB_MAX_HFREFERENCE);
  849. al_effect_props_.Reverb.HFReference = efx_hf_reference;
  850. }
  851. void EaxReverbEffect::set_efx_lf_reference()
  852. {
  853. const auto efx_lf_reference = clamp(
  854. eax_.flLFReference,
  855. AL_EAXREVERB_MIN_LFREFERENCE,
  856. AL_EAXREVERB_MAX_LFREFERENCE);
  857. al_effect_props_.Reverb.LFReference = efx_lf_reference;
  858. }
  859. void EaxReverbEffect::set_efx_room_rolloff_factor()
  860. {
  861. const auto efx_room_rolloff_factor = clamp(
  862. eax_.flRoomRolloffFactor,
  863. AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR,
  864. AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR);
  865. al_effect_props_.Reverb.RoomRolloffFactor = efx_room_rolloff_factor;
  866. }
  867. void EaxReverbEffect::set_efx_flags()
  868. {
  869. al_effect_props_.Reverb.DecayHFLimit = ((eax_.ulFlags & EAXREVERBFLAGS_DECAYHFLIMIT) != 0);
  870. }
  871. void EaxReverbEffect::set_efx_defaults()
  872. {
  873. set_efx_density_from_environment_size();
  874. set_efx_diffusion();
  875. set_efx_gain();
  876. set_efx_gain_hf();
  877. set_efx_gain_lf();
  878. set_efx_decay_time();
  879. set_efx_decay_hf_ratio();
  880. set_efx_decay_lf_ratio();
  881. set_efx_reflections_gain();
  882. set_efx_reflections_delay();
  883. set_efx_reflections_pan();
  884. set_efx_late_reverb_gain();
  885. set_efx_late_reverb_delay();
  886. set_efx_late_reverb_pan();
  887. set_efx_echo_time();
  888. set_efx_echo_depth();
  889. set_efx_modulation_time();
  890. set_efx_modulation_depth();
  891. set_efx_air_absorption_gain_hf();
  892. set_efx_hf_reference();
  893. set_efx_lf_reference();
  894. set_efx_room_rolloff_factor();
  895. set_efx_flags();
  896. }
  897. void EaxReverbEffect::v1_get(const EaxEaxCall& eax_call) const
  898. {
  899. switch(eax_call.get_property_id())
  900. {
  901. case DSPROPERTY_EAX_ALL:
  902. eax_call.set_value<EaxReverbEffectException>(eax1_);
  903. break;
  904. case DSPROPERTY_EAX_ENVIRONMENT:
  905. eax_call.set_value<EaxReverbEffectException>(eax1_.environment);
  906. break;
  907. case DSPROPERTY_EAX_VOLUME:
  908. eax_call.set_value<EaxReverbEffectException>(eax1_.fVolume);
  909. break;
  910. case DSPROPERTY_EAX_DECAYTIME:
  911. eax_call.set_value<EaxReverbEffectException>(eax1_.fDecayTime_sec);
  912. break;
  913. case DSPROPERTY_EAX_DAMPING:
  914. eax_call.set_value<EaxReverbEffectException>(eax1_.fDamping);
  915. break;
  916. default:
  917. eax_fail("Unsupported property id.");
  918. }
  919. }
  920. void EaxReverbEffect::get_all(
  921. const EaxEaxCall& eax_call) const
  922. {
  923. if (eax_call.get_version() == 2)
  924. {
  925. auto& eax_reverb = eax_call.get_value<EaxReverbEffectException, EAX20LISTENERPROPERTIES>();
  926. eax_reverb.lRoom = eax_.lRoom;
  927. eax_reverb.lRoomHF = eax_.lRoomHF;
  928. eax_reverb.flRoomRolloffFactor = eax_.flRoomRolloffFactor;
  929. eax_reverb.flDecayTime = eax_.flDecayTime;
  930. eax_reverb.flDecayHFRatio = eax_.flDecayHFRatio;
  931. eax_reverb.lReflections = eax_.lReflections;
  932. eax_reverb.flReflectionsDelay = eax_.flReflectionsDelay;
  933. eax_reverb.lReverb = eax_.lReverb;
  934. eax_reverb.flReverbDelay = eax_.flReverbDelay;
  935. eax_reverb.dwEnvironment = eax_.ulEnvironment;
  936. eax_reverb.flEnvironmentSize = eax_.flEnvironmentSize;
  937. eax_reverb.flEnvironmentDiffusion = eax_.flEnvironmentDiffusion;
  938. eax_reverb.flAirAbsorptionHF = eax_.flAirAbsorptionHF;
  939. eax_reverb.dwFlags = eax_.ulFlags;
  940. }
  941. else
  942. {
  943. eax_call.set_value<EaxReverbEffectException>(eax_);
  944. }
  945. }
  946. void EaxReverbEffect::get(const EaxEaxCall& eax_call) const
  947. {
  948. if(eax_call.get_version() == 1)
  949. v1_get(eax_call);
  950. else switch(eax_call.get_property_id())
  951. {
  952. case EAXREVERB_NONE:
  953. break;
  954. case EAXREVERB_ALLPARAMETERS:
  955. get_all(eax_call);
  956. break;
  957. case EAXREVERB_ENVIRONMENT:
  958. eax_call.set_value<EaxReverbEffectException>(eax_.ulEnvironment);
  959. break;
  960. case EAXREVERB_ENVIRONMENTSIZE:
  961. eax_call.set_value<EaxReverbEffectException>(eax_.flEnvironmentSize);
  962. break;
  963. case EAXREVERB_ENVIRONMENTDIFFUSION:
  964. eax_call.set_value<EaxReverbEffectException>(eax_.flEnvironmentDiffusion);
  965. break;
  966. case EAXREVERB_ROOM:
  967. eax_call.set_value<EaxReverbEffectException>(eax_.lRoom);
  968. break;
  969. case EAXREVERB_ROOMHF:
  970. eax_call.set_value<EaxReverbEffectException>(eax_.lRoomHF);
  971. break;
  972. case EAXREVERB_ROOMLF:
  973. eax_call.set_value<EaxReverbEffectException>(eax_.lRoomLF);
  974. break;
  975. case EAXREVERB_DECAYTIME:
  976. eax_call.set_value<EaxReverbEffectException>(eax_.flDecayTime);
  977. break;
  978. case EAXREVERB_DECAYHFRATIO:
  979. eax_call.set_value<EaxReverbEffectException>(eax_.flDecayHFRatio);
  980. break;
  981. case EAXREVERB_DECAYLFRATIO:
  982. eax_call.set_value<EaxReverbEffectException>(eax_.flDecayLFRatio);
  983. break;
  984. case EAXREVERB_REFLECTIONS:
  985. eax_call.set_value<EaxReverbEffectException>(eax_.lReflections);
  986. break;
  987. case EAXREVERB_REFLECTIONSDELAY:
  988. eax_call.set_value<EaxReverbEffectException>(eax_.flReflectionsDelay);
  989. break;
  990. case EAXREVERB_REFLECTIONSPAN:
  991. eax_call.set_value<EaxReverbEffectException>(eax_.vReflectionsPan);
  992. break;
  993. case EAXREVERB_REVERB:
  994. eax_call.set_value<EaxReverbEffectException>(eax_.lReverb);
  995. break;
  996. case EAXREVERB_REVERBDELAY:
  997. eax_call.set_value<EaxReverbEffectException>(eax_.flReverbDelay);
  998. break;
  999. case EAXREVERB_REVERBPAN:
  1000. eax_call.set_value<EaxReverbEffectException>(eax_.vReverbPan);
  1001. break;
  1002. case EAXREVERB_ECHOTIME:
  1003. eax_call.set_value<EaxReverbEffectException>(eax_.flEchoTime);
  1004. break;
  1005. case EAXREVERB_ECHODEPTH:
  1006. eax_call.set_value<EaxReverbEffectException>(eax_.flEchoDepth);
  1007. break;
  1008. case EAXREVERB_MODULATIONTIME:
  1009. eax_call.set_value<EaxReverbEffectException>(eax_.flModulationTime);
  1010. break;
  1011. case EAXREVERB_MODULATIONDEPTH:
  1012. eax_call.set_value<EaxReverbEffectException>(eax_.flModulationDepth);
  1013. break;
  1014. case EAXREVERB_AIRABSORPTIONHF:
  1015. eax_call.set_value<EaxReverbEffectException>(eax_.flAirAbsorptionHF);
  1016. break;
  1017. case EAXREVERB_HFREFERENCE:
  1018. eax_call.set_value<EaxReverbEffectException>(eax_.flHFReference);
  1019. break;
  1020. case EAXREVERB_LFREFERENCE:
  1021. eax_call.set_value<EaxReverbEffectException>(eax_.flLFReference);
  1022. break;
  1023. case EAXREVERB_ROOMROLLOFFFACTOR:
  1024. eax_call.set_value<EaxReverbEffectException>(eax_.flRoomRolloffFactor);
  1025. break;
  1026. case EAXREVERB_FLAGS:
  1027. eax_call.set_value<EaxReverbEffectException>(eax_.ulFlags);
  1028. break;
  1029. default:
  1030. eax_fail("Unsupported property id.");
  1031. }
  1032. }
  1033. void EaxReverbEffect::v1_validate_environment(unsigned long environment)
  1034. {
  1035. validate_environment(environment, 1, true);
  1036. }
  1037. void EaxReverbEffect::v1_validate_volume(float volume)
  1038. {
  1039. eax_validate_range<EaxReverbEffectException>("Volume", volume, EAX1REVERB_MINVOLUME, EAX1REVERB_MAXVOLUME);
  1040. }
  1041. void EaxReverbEffect::v1_validate_decay_time(float decay_time)
  1042. {
  1043. validate_decay_time(decay_time);
  1044. }
  1045. void EaxReverbEffect::v1_validate_damping(float damping)
  1046. {
  1047. eax_validate_range<EaxReverbEffectException>("Damping", damping, EAX1REVERB_MINDAMPING, EAX1REVERB_MAXDAMPING);
  1048. }
  1049. void EaxReverbEffect::v1_validate_all(const EAX_REVERBPROPERTIES& all)
  1050. {
  1051. v1_validate_environment(all.environment);
  1052. v1_validate_volume(all.fVolume);
  1053. v1_validate_decay_time(all.fDecayTime_sec);
  1054. v1_validate_damping(all.fDamping);
  1055. }
  1056. void EaxReverbEffect::validate_environment(
  1057. unsigned long ulEnvironment,
  1058. int version,
  1059. bool is_standalone)
  1060. {
  1061. eax_validate_range<EaxReverbEffectException>(
  1062. "Environment",
  1063. ulEnvironment,
  1064. EAXREVERB_MINENVIRONMENT,
  1065. (version <= 2 || is_standalone) ? EAX1REVERB_MAXENVIRONMENT : EAX30REVERB_MAXENVIRONMENT);
  1066. }
  1067. void EaxReverbEffect::validate_environment_size(
  1068. float flEnvironmentSize)
  1069. {
  1070. eax_validate_range<EaxReverbEffectException>(
  1071. "Environment Size",
  1072. flEnvironmentSize,
  1073. EAXREVERB_MINENVIRONMENTSIZE,
  1074. EAXREVERB_MAXENVIRONMENTSIZE);
  1075. }
  1076. void EaxReverbEffect::validate_environment_diffusion(
  1077. float flEnvironmentDiffusion)
  1078. {
  1079. eax_validate_range<EaxReverbEffectException>(
  1080. "Environment Diffusion",
  1081. flEnvironmentDiffusion,
  1082. EAXREVERB_MINENVIRONMENTDIFFUSION,
  1083. EAXREVERB_MAXENVIRONMENTDIFFUSION);
  1084. }
  1085. void EaxReverbEffect::validate_room(
  1086. long lRoom)
  1087. {
  1088. eax_validate_range<EaxReverbEffectException>(
  1089. "Room",
  1090. lRoom,
  1091. EAXREVERB_MINROOM,
  1092. EAXREVERB_MAXROOM);
  1093. }
  1094. void EaxReverbEffect::validate_room_hf(
  1095. long lRoomHF)
  1096. {
  1097. eax_validate_range<EaxReverbEffectException>(
  1098. "Room HF",
  1099. lRoomHF,
  1100. EAXREVERB_MINROOMHF,
  1101. EAXREVERB_MAXROOMHF);
  1102. }
  1103. void EaxReverbEffect::validate_room_lf(
  1104. long lRoomLF)
  1105. {
  1106. eax_validate_range<EaxReverbEffectException>(
  1107. "Room LF",
  1108. lRoomLF,
  1109. EAXREVERB_MINROOMLF,
  1110. EAXREVERB_MAXROOMLF);
  1111. }
  1112. void EaxReverbEffect::validate_decay_time(
  1113. float flDecayTime)
  1114. {
  1115. eax_validate_range<EaxReverbEffectException>(
  1116. "Decay Time",
  1117. flDecayTime,
  1118. EAXREVERB_MINDECAYTIME,
  1119. EAXREVERB_MAXDECAYTIME);
  1120. }
  1121. void EaxReverbEffect::validate_decay_hf_ratio(
  1122. float flDecayHFRatio)
  1123. {
  1124. eax_validate_range<EaxReverbEffectException>(
  1125. "Decay HF Ratio",
  1126. flDecayHFRatio,
  1127. EAXREVERB_MINDECAYHFRATIO,
  1128. EAXREVERB_MAXDECAYHFRATIO);
  1129. }
  1130. void EaxReverbEffect::validate_decay_lf_ratio(
  1131. float flDecayLFRatio)
  1132. {
  1133. eax_validate_range<EaxReverbEffectException>(
  1134. "Decay LF Ratio",
  1135. flDecayLFRatio,
  1136. EAXREVERB_MINDECAYLFRATIO,
  1137. EAXREVERB_MAXDECAYLFRATIO);
  1138. }
  1139. void EaxReverbEffect::validate_reflections(
  1140. long lReflections)
  1141. {
  1142. eax_validate_range<EaxReverbEffectException>(
  1143. "Reflections",
  1144. lReflections,
  1145. EAXREVERB_MINREFLECTIONS,
  1146. EAXREVERB_MAXREFLECTIONS);
  1147. }
  1148. void EaxReverbEffect::validate_reflections_delay(
  1149. float flReflectionsDelay)
  1150. {
  1151. eax_validate_range<EaxReverbEffectException>(
  1152. "Reflections Delay",
  1153. flReflectionsDelay,
  1154. EAXREVERB_MINREFLECTIONSDELAY,
  1155. EAXREVERB_MAXREFLECTIONSDELAY);
  1156. }
  1157. void EaxReverbEffect::validate_reflections_pan(
  1158. const EAXVECTOR& vReflectionsPan)
  1159. {
  1160. std::ignore = vReflectionsPan;
  1161. }
  1162. void EaxReverbEffect::validate_reverb(
  1163. long lReverb)
  1164. {
  1165. eax_validate_range<EaxReverbEffectException>(
  1166. "Reverb",
  1167. lReverb,
  1168. EAXREVERB_MINREVERB,
  1169. EAXREVERB_MAXREVERB);
  1170. }
  1171. void EaxReverbEffect::validate_reverb_delay(
  1172. float flReverbDelay)
  1173. {
  1174. eax_validate_range<EaxReverbEffectException>(
  1175. "Reverb Delay",
  1176. flReverbDelay,
  1177. EAXREVERB_MINREVERBDELAY,
  1178. EAXREVERB_MAXREVERBDELAY);
  1179. }
  1180. void EaxReverbEffect::validate_reverb_pan(
  1181. const EAXVECTOR& vReverbPan)
  1182. {
  1183. std::ignore = vReverbPan;
  1184. }
  1185. void EaxReverbEffect::validate_echo_time(
  1186. float flEchoTime)
  1187. {
  1188. eax_validate_range<EaxReverbEffectException>(
  1189. "Echo Time",
  1190. flEchoTime,
  1191. EAXREVERB_MINECHOTIME,
  1192. EAXREVERB_MAXECHOTIME);
  1193. }
  1194. void EaxReverbEffect::validate_echo_depth(
  1195. float flEchoDepth)
  1196. {
  1197. eax_validate_range<EaxReverbEffectException>(
  1198. "Echo Depth",
  1199. flEchoDepth,
  1200. EAXREVERB_MINECHODEPTH,
  1201. EAXREVERB_MAXECHODEPTH);
  1202. }
  1203. void EaxReverbEffect::validate_modulation_time(
  1204. float flModulationTime)
  1205. {
  1206. eax_validate_range<EaxReverbEffectException>(
  1207. "Modulation Time",
  1208. flModulationTime,
  1209. EAXREVERB_MINMODULATIONTIME,
  1210. EAXREVERB_MAXMODULATIONTIME);
  1211. }
  1212. void EaxReverbEffect::validate_modulation_depth(
  1213. float flModulationDepth)
  1214. {
  1215. eax_validate_range<EaxReverbEffectException>(
  1216. "Modulation Depth",
  1217. flModulationDepth,
  1218. EAXREVERB_MINMODULATIONDEPTH,
  1219. EAXREVERB_MAXMODULATIONDEPTH);
  1220. }
  1221. void EaxReverbEffect::validate_air_absorbtion_hf(
  1222. float air_absorbtion_hf)
  1223. {
  1224. eax_validate_range<EaxReverbEffectException>(
  1225. "Air Absorbtion HF",
  1226. air_absorbtion_hf,
  1227. EAXREVERB_MINAIRABSORPTIONHF,
  1228. EAXREVERB_MAXAIRABSORPTIONHF);
  1229. }
  1230. void EaxReverbEffect::validate_hf_reference(
  1231. float flHFReference)
  1232. {
  1233. eax_validate_range<EaxReverbEffectException>(
  1234. "HF Reference",
  1235. flHFReference,
  1236. EAXREVERB_MINHFREFERENCE,
  1237. EAXREVERB_MAXHFREFERENCE);
  1238. }
  1239. void EaxReverbEffect::validate_lf_reference(
  1240. float flLFReference)
  1241. {
  1242. eax_validate_range<EaxReverbEffectException>(
  1243. "LF Reference",
  1244. flLFReference,
  1245. EAXREVERB_MINLFREFERENCE,
  1246. EAXREVERB_MAXLFREFERENCE);
  1247. }
  1248. void EaxReverbEffect::validate_room_rolloff_factor(
  1249. float flRoomRolloffFactor)
  1250. {
  1251. eax_validate_range<EaxReverbEffectException>(
  1252. "Room Rolloff Factor",
  1253. flRoomRolloffFactor,
  1254. EAXREVERB_MINROOMROLLOFFFACTOR,
  1255. EAXREVERB_MAXROOMROLLOFFFACTOR);
  1256. }
  1257. void EaxReverbEffect::validate_flags(
  1258. unsigned long ulFlags)
  1259. {
  1260. eax_validate_range<EaxReverbEffectException>(
  1261. "Flags",
  1262. ulFlags,
  1263. 0UL,
  1264. ~EAXREVERBFLAGS_RESERVED);
  1265. }
  1266. void EaxReverbEffect::validate_all(
  1267. const EAX20LISTENERPROPERTIES& listener,
  1268. int version)
  1269. {
  1270. validate_room(listener.lRoom);
  1271. validate_room_hf(listener.lRoomHF);
  1272. validate_room_rolloff_factor(listener.flRoomRolloffFactor);
  1273. validate_decay_time(listener.flDecayTime);
  1274. validate_decay_hf_ratio(listener.flDecayHFRatio);
  1275. validate_reflections(listener.lReflections);
  1276. validate_reflections_delay(listener.flReflectionsDelay);
  1277. validate_reverb(listener.lReverb);
  1278. validate_reverb_delay(listener.flReverbDelay);
  1279. validate_environment(listener.dwEnvironment, version, false);
  1280. validate_environment_size(listener.flEnvironmentSize);
  1281. validate_environment_diffusion(listener.flEnvironmentDiffusion);
  1282. validate_air_absorbtion_hf(listener.flAirAbsorptionHF);
  1283. validate_flags(listener.dwFlags);
  1284. }
  1285. void EaxReverbEffect::validate_all(
  1286. const EAXREVERBPROPERTIES& lReverb,
  1287. int version)
  1288. {
  1289. validate_environment(lReverb.ulEnvironment, version, false);
  1290. validate_environment_size(lReverb.flEnvironmentSize);
  1291. validate_environment_diffusion(lReverb.flEnvironmentDiffusion);
  1292. validate_room(lReverb.lRoom);
  1293. validate_room_hf(lReverb.lRoomHF);
  1294. validate_room_lf(lReverb.lRoomLF);
  1295. validate_decay_time(lReverb.flDecayTime);
  1296. validate_decay_hf_ratio(lReverb.flDecayHFRatio);
  1297. validate_decay_lf_ratio(lReverb.flDecayLFRatio);
  1298. validate_reflections(lReverb.lReflections);
  1299. validate_reflections_delay(lReverb.flReflectionsDelay);
  1300. validate_reverb(lReverb.lReverb);
  1301. validate_reverb_delay(lReverb.flReverbDelay);
  1302. validate_echo_time(lReverb.flEchoTime);
  1303. validate_echo_depth(lReverb.flEchoDepth);
  1304. validate_modulation_time(lReverb.flModulationTime);
  1305. validate_modulation_depth(lReverb.flModulationDepth);
  1306. validate_air_absorbtion_hf(lReverb.flAirAbsorptionHF);
  1307. validate_hf_reference(lReverb.flHFReference);
  1308. validate_lf_reference(lReverb.flLFReference);
  1309. validate_room_rolloff_factor(lReverb.flRoomRolloffFactor);
  1310. validate_flags(lReverb.ulFlags);
  1311. }
  1312. void EaxReverbEffect::v1_defer_environment(unsigned long environment)
  1313. {
  1314. eax1_d_ = EAX1REVERB_PRESETS[environment];
  1315. eax1_dirty_flags_.ulEnvironment = true;
  1316. }
  1317. void EaxReverbEffect::v1_defer_volume(float volume)
  1318. {
  1319. eax1_d_.fVolume = volume;
  1320. eax1_dirty_flags_.flVolume = (eax1_.fVolume != eax1_d_.fVolume);
  1321. }
  1322. void EaxReverbEffect::v1_defer_decay_time(float decay_time)
  1323. {
  1324. eax1_d_.fDecayTime_sec = decay_time;
  1325. eax1_dirty_flags_.flDecayTime = (eax1_.fDecayTime_sec != eax1_d_.fDecayTime_sec);
  1326. }
  1327. void EaxReverbEffect::v1_defer_damping(float damping)
  1328. {
  1329. eax1_d_.fDamping = damping;
  1330. eax1_dirty_flags_.flDamping = (eax1_.fDamping != eax1_d_.fDamping);
  1331. }
  1332. void EaxReverbEffect::v1_defer_all(const EAX_REVERBPROPERTIES& lReverb)
  1333. {
  1334. v1_defer_environment(lReverb.environment);
  1335. v1_defer_volume(lReverb.fVolume);
  1336. v1_defer_decay_time(lReverb.fDecayTime_sec);
  1337. v1_defer_damping(lReverb.fDamping);
  1338. }
  1339. void EaxReverbEffect::v1_set_efx()
  1340. {
  1341. auto efx_props = eax_efx_reverb_presets[eax1_.environment];
  1342. efx_props.flGain = eax1_.fVolume;
  1343. efx_props.flDecayTime = eax1_.fDecayTime_sec;
  1344. efx_props.flDecayHFRatio = clamp(eax1_.fDamping, AL_EAXREVERB_MIN_DECAY_HFRATIO, AL_EAXREVERB_MAX_DECAY_HFRATIO);
  1345. al_effect_props_.Reverb.Density = efx_props.flDensity;
  1346. al_effect_props_.Reverb.Diffusion = efx_props.flDiffusion;
  1347. al_effect_props_.Reverb.Gain = efx_props.flGain;
  1348. al_effect_props_.Reverb.GainHF = efx_props.flGainHF;
  1349. al_effect_props_.Reverb.GainLF = efx_props.flGainLF;
  1350. al_effect_props_.Reverb.DecayTime = efx_props.flDecayTime;
  1351. al_effect_props_.Reverb.DecayHFRatio = efx_props.flDecayHFRatio;
  1352. al_effect_props_.Reverb.DecayLFRatio = efx_props.flDecayLFRatio;
  1353. al_effect_props_.Reverb.ReflectionsGain = efx_props.flReflectionsGain;
  1354. al_effect_props_.Reverb.ReflectionsDelay = efx_props.flReflectionsDelay;
  1355. al_effect_props_.Reverb.ReflectionsPan[0] = efx_props.flReflectionsPan[0];
  1356. al_effect_props_.Reverb.ReflectionsPan[1] = efx_props.flReflectionsPan[1];
  1357. al_effect_props_.Reverb.ReflectionsPan[2] = efx_props.flReflectionsPan[2];
  1358. al_effect_props_.Reverb.LateReverbGain = efx_props.flLateReverbGain;
  1359. al_effect_props_.Reverb.LateReverbDelay = efx_props.flLateReverbDelay;
  1360. al_effect_props_.Reverb.LateReverbPan[0] = efx_props.flLateReverbPan[0];
  1361. al_effect_props_.Reverb.LateReverbPan[1] = efx_props.flLateReverbPan[1];
  1362. al_effect_props_.Reverb.LateReverbPan[2] = efx_props.flLateReverbPan[2];
  1363. al_effect_props_.Reverb.EchoTime = efx_props.flEchoTime;
  1364. al_effect_props_.Reverb.EchoDepth = efx_props.flEchoDepth;
  1365. al_effect_props_.Reverb.ModulationTime = efx_props.flModulationTime;
  1366. al_effect_props_.Reverb.ModulationDepth = efx_props.flModulationDepth;
  1367. al_effect_props_.Reverb.HFReference = efx_props.flHFReference;
  1368. al_effect_props_.Reverb.LFReference = efx_props.flLFReference;
  1369. al_effect_props_.Reverb.RoomRolloffFactor = efx_props.flRoomRolloffFactor;
  1370. al_effect_props_.Reverb.AirAbsorptionGainHF = efx_props.flAirAbsorptionGainHF;
  1371. al_effect_props_.Reverb.DecayHFLimit = false;
  1372. }
  1373. void EaxReverbEffect::defer_environment(
  1374. unsigned long ulEnvironment)
  1375. {
  1376. eax_d_.ulEnvironment = ulEnvironment;
  1377. eax_dirty_flags_.ulEnvironment = (eax_.ulEnvironment != eax_d_.ulEnvironment);
  1378. }
  1379. void EaxReverbEffect::defer_environment_size(
  1380. float flEnvironmentSize)
  1381. {
  1382. eax_d_.flEnvironmentSize = flEnvironmentSize;
  1383. eax_dirty_flags_.flEnvironmentSize = (eax_.flEnvironmentSize != eax_d_.flEnvironmentSize);
  1384. }
  1385. void EaxReverbEffect::defer_environment_diffusion(
  1386. float flEnvironmentDiffusion)
  1387. {
  1388. eax_d_.flEnvironmentDiffusion = flEnvironmentDiffusion;
  1389. eax_dirty_flags_.flEnvironmentDiffusion = (eax_.flEnvironmentDiffusion != eax_d_.flEnvironmentDiffusion);
  1390. }
  1391. void EaxReverbEffect::defer_room(
  1392. long lRoom)
  1393. {
  1394. eax_d_.lRoom = lRoom;
  1395. eax_dirty_flags_.lRoom = (eax_.lRoom != eax_d_.lRoom);
  1396. }
  1397. void EaxReverbEffect::defer_room_hf(
  1398. long lRoomHF)
  1399. {
  1400. eax_d_.lRoomHF = lRoomHF;
  1401. eax_dirty_flags_.lRoomHF = (eax_.lRoomHF != eax_d_.lRoomHF);
  1402. }
  1403. void EaxReverbEffect::defer_room_lf(
  1404. long lRoomLF)
  1405. {
  1406. eax_d_.lRoomLF = lRoomLF;
  1407. eax_dirty_flags_.lRoomLF = (eax_.lRoomLF != eax_d_.lRoomLF);
  1408. }
  1409. void EaxReverbEffect::defer_decay_time(
  1410. float flDecayTime)
  1411. {
  1412. eax_d_.flDecayTime = flDecayTime;
  1413. eax_dirty_flags_.flDecayTime = (eax_.flDecayTime != eax_d_.flDecayTime);
  1414. }
  1415. void EaxReverbEffect::defer_decay_hf_ratio(
  1416. float flDecayHFRatio)
  1417. {
  1418. eax_d_.flDecayHFRatio = flDecayHFRatio;
  1419. eax_dirty_flags_.flDecayHFRatio = (eax_.flDecayHFRatio != eax_d_.flDecayHFRatio);
  1420. }
  1421. void EaxReverbEffect::defer_decay_lf_ratio(
  1422. float flDecayLFRatio)
  1423. {
  1424. eax_d_.flDecayLFRatio = flDecayLFRatio;
  1425. eax_dirty_flags_.flDecayLFRatio = (eax_.flDecayLFRatio != eax_d_.flDecayLFRatio);
  1426. }
  1427. void EaxReverbEffect::defer_reflections(
  1428. long lReflections)
  1429. {
  1430. eax_d_.lReflections = lReflections;
  1431. eax_dirty_flags_.lReflections = (eax_.lReflections != eax_d_.lReflections);
  1432. }
  1433. void EaxReverbEffect::defer_reflections_delay(
  1434. float flReflectionsDelay)
  1435. {
  1436. eax_d_.flReflectionsDelay = flReflectionsDelay;
  1437. eax_dirty_flags_.flReflectionsDelay = (eax_.flReflectionsDelay != eax_d_.flReflectionsDelay);
  1438. }
  1439. void EaxReverbEffect::defer_reflections_pan(
  1440. const EAXVECTOR& vReflectionsPan)
  1441. {
  1442. eax_d_.vReflectionsPan = vReflectionsPan;
  1443. eax_dirty_flags_.vReflectionsPan = (eax_.vReflectionsPan != eax_d_.vReflectionsPan);
  1444. }
  1445. void EaxReverbEffect::defer_reverb(
  1446. long lReverb)
  1447. {
  1448. eax_d_.lReverb = lReverb;
  1449. eax_dirty_flags_.lReverb = (eax_.lReverb != eax_d_.lReverb);
  1450. }
  1451. void EaxReverbEffect::defer_reverb_delay(
  1452. float flReverbDelay)
  1453. {
  1454. eax_d_.flReverbDelay = flReverbDelay;
  1455. eax_dirty_flags_.flReverbDelay = (eax_.flReverbDelay != eax_d_.flReverbDelay);
  1456. }
  1457. void EaxReverbEffect::defer_reverb_pan(
  1458. const EAXVECTOR& vReverbPan)
  1459. {
  1460. eax_d_.vReverbPan = vReverbPan;
  1461. eax_dirty_flags_.vReverbPan = (eax_.vReverbPan != eax_d_.vReverbPan);
  1462. }
  1463. void EaxReverbEffect::defer_echo_time(
  1464. float flEchoTime)
  1465. {
  1466. eax_d_.flEchoTime = flEchoTime;
  1467. eax_dirty_flags_.flEchoTime = (eax_.flEchoTime != eax_d_.flEchoTime);
  1468. }
  1469. void EaxReverbEffect::defer_echo_depth(
  1470. float flEchoDepth)
  1471. {
  1472. eax_d_.flEchoDepth = flEchoDepth;
  1473. eax_dirty_flags_.flEchoDepth = (eax_.flEchoDepth != eax_d_.flEchoDepth);
  1474. }
  1475. void EaxReverbEffect::defer_modulation_time(
  1476. float flModulationTime)
  1477. {
  1478. eax_d_.flModulationTime = flModulationTime;
  1479. eax_dirty_flags_.flModulationTime = (eax_.flModulationTime != eax_d_.flModulationTime);
  1480. }
  1481. void EaxReverbEffect::defer_modulation_depth(
  1482. float flModulationDepth)
  1483. {
  1484. eax_d_.flModulationDepth = flModulationDepth;
  1485. eax_dirty_flags_.flModulationDepth = (eax_.flModulationDepth != eax_d_.flModulationDepth);
  1486. }
  1487. void EaxReverbEffect::defer_air_absorbtion_hf(
  1488. float flAirAbsorptionHF)
  1489. {
  1490. eax_d_.flAirAbsorptionHF = flAirAbsorptionHF;
  1491. eax_dirty_flags_.flAirAbsorptionHF = (eax_.flAirAbsorptionHF != eax_d_.flAirAbsorptionHF);
  1492. }
  1493. void EaxReverbEffect::defer_hf_reference(
  1494. float flHFReference)
  1495. {
  1496. eax_d_.flHFReference = flHFReference;
  1497. eax_dirty_flags_.flHFReference = (eax_.flHFReference != eax_d_.flHFReference);
  1498. }
  1499. void EaxReverbEffect::defer_lf_reference(
  1500. float flLFReference)
  1501. {
  1502. eax_d_.flLFReference = flLFReference;
  1503. eax_dirty_flags_.flLFReference = (eax_.flLFReference != eax_d_.flLFReference);
  1504. }
  1505. void EaxReverbEffect::defer_room_rolloff_factor(
  1506. float flRoomRolloffFactor)
  1507. {
  1508. eax_d_.flRoomRolloffFactor = flRoomRolloffFactor;
  1509. eax_dirty_flags_.flRoomRolloffFactor = (eax_.flRoomRolloffFactor != eax_d_.flRoomRolloffFactor);
  1510. }
  1511. void EaxReverbEffect::defer_flags(
  1512. unsigned long ulFlags)
  1513. {
  1514. eax_d_.ulFlags = ulFlags;
  1515. eax_dirty_flags_.ulFlags = (eax_.ulFlags != eax_d_.ulFlags);
  1516. }
  1517. void EaxReverbEffect::defer_all(
  1518. const EAX20LISTENERPROPERTIES& listener)
  1519. {
  1520. defer_room(listener.lRoom);
  1521. defer_room_hf(listener.lRoomHF);
  1522. defer_room_rolloff_factor(listener.flRoomRolloffFactor);
  1523. defer_decay_time(listener.flDecayTime);
  1524. defer_decay_hf_ratio(listener.flDecayHFRatio);
  1525. defer_reflections(listener.lReflections);
  1526. defer_reflections_delay(listener.flReflectionsDelay);
  1527. defer_reverb(listener.lReverb);
  1528. defer_reverb_delay(listener.flReverbDelay);
  1529. defer_environment(listener.dwEnvironment);
  1530. defer_environment_size(listener.flEnvironmentSize);
  1531. defer_environment_diffusion(listener.flEnvironmentDiffusion);
  1532. defer_air_absorbtion_hf(listener.flAirAbsorptionHF);
  1533. defer_flags(listener.dwFlags);
  1534. }
  1535. void EaxReverbEffect::defer_all(
  1536. const EAXREVERBPROPERTIES& lReverb)
  1537. {
  1538. defer_environment(lReverb.ulEnvironment);
  1539. defer_environment_size(lReverb.flEnvironmentSize);
  1540. defer_environment_diffusion(lReverb.flEnvironmentDiffusion);
  1541. defer_room(lReverb.lRoom);
  1542. defer_room_hf(lReverb.lRoomHF);
  1543. defer_room_lf(lReverb.lRoomLF);
  1544. defer_decay_time(lReverb.flDecayTime);
  1545. defer_decay_hf_ratio(lReverb.flDecayHFRatio);
  1546. defer_decay_lf_ratio(lReverb.flDecayLFRatio);
  1547. defer_reflections(lReverb.lReflections);
  1548. defer_reflections_delay(lReverb.flReflectionsDelay);
  1549. defer_reflections_pan(lReverb.vReflectionsPan);
  1550. defer_reverb(lReverb.lReverb);
  1551. defer_reverb_delay(lReverb.flReverbDelay);
  1552. defer_reverb_pan(lReverb.vReverbPan);
  1553. defer_echo_time(lReverb.flEchoTime);
  1554. defer_echo_depth(lReverb.flEchoDepth);
  1555. defer_modulation_time(lReverb.flModulationTime);
  1556. defer_modulation_depth(lReverb.flModulationDepth);
  1557. defer_air_absorbtion_hf(lReverb.flAirAbsorptionHF);
  1558. defer_hf_reference(lReverb.flHFReference);
  1559. defer_lf_reference(lReverb.flLFReference);
  1560. defer_room_rolloff_factor(lReverb.flRoomRolloffFactor);
  1561. defer_flags(lReverb.ulFlags);
  1562. }
  1563. void EaxReverbEffect::v1_defer_environment(const EaxEaxCall& eax_call)
  1564. {
  1565. const auto& environment = eax_call.get_value<EaxReverbEffectException,
  1566. const decltype(EAX_REVERBPROPERTIES::environment)>();
  1567. validate_environment(environment, 1, true);
  1568. const auto& reverb_preset = EAX1REVERB_PRESETS[environment];
  1569. v1_defer_all(reverb_preset);
  1570. }
  1571. void EaxReverbEffect::v1_defer_volume(const EaxEaxCall& eax_call)
  1572. {
  1573. const auto& volume = eax_call.get_value<EaxReverbEffectException,
  1574. const decltype(EAX_REVERBPROPERTIES::fVolume)>();
  1575. v1_validate_volume(volume);
  1576. v1_defer_volume(volume);
  1577. }
  1578. void EaxReverbEffect::v1_defer_decay_time(const EaxEaxCall& eax_call)
  1579. {
  1580. const auto& decay_time = eax_call.get_value<EaxReverbEffectException,
  1581. const decltype(EAX_REVERBPROPERTIES::fDecayTime_sec)>();
  1582. v1_validate_decay_time(decay_time);
  1583. v1_defer_decay_time(decay_time);
  1584. }
  1585. void EaxReverbEffect::v1_defer_damping(const EaxEaxCall& eax_call)
  1586. {
  1587. const auto& damping = eax_call.get_value<EaxReverbEffectException,
  1588. const decltype(EAX_REVERBPROPERTIES::fDamping)>();
  1589. v1_validate_damping(damping);
  1590. v1_defer_damping(damping);
  1591. }
  1592. void EaxReverbEffect::v1_defer_all(const EaxEaxCall& eax_call)
  1593. {
  1594. const auto& reverb_all = eax_call.get_value<EaxReverbEffectException,
  1595. const EAX_REVERBPROPERTIES>();
  1596. v1_validate_all(reverb_all);
  1597. v1_defer_all(reverb_all);
  1598. }
  1599. void EaxReverbEffect::defer_environment(
  1600. const EaxEaxCall& eax_call)
  1601. {
  1602. const auto& ulEnvironment =
  1603. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::ulEnvironment)>();
  1604. validate_environment(ulEnvironment, eax_call.get_version(), true);
  1605. if (eax_d_.ulEnvironment == ulEnvironment)
  1606. {
  1607. return;
  1608. }
  1609. const auto& reverb_preset = EAXREVERB_PRESETS[ulEnvironment];
  1610. defer_all(reverb_preset);
  1611. }
  1612. void EaxReverbEffect::defer_environment_size(
  1613. const EaxEaxCall& eax_call)
  1614. {
  1615. const auto& flEnvironmentSize =
  1616. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::flEnvironmentSize)>();
  1617. validate_environment_size(flEnvironmentSize);
  1618. if (eax_d_.flEnvironmentSize == flEnvironmentSize)
  1619. {
  1620. return;
  1621. }
  1622. const auto scale = flEnvironmentSize / eax_d_.flEnvironmentSize;
  1623. defer_environment_size(flEnvironmentSize);
  1624. if ((eax_d_.ulFlags & EAXREVERBFLAGS_DECAYTIMESCALE) != 0)
  1625. {
  1626. const auto flDecayTime = clamp(
  1627. scale * eax_d_.flDecayTime,
  1628. EAXREVERB_MINDECAYTIME,
  1629. EAXREVERB_MAXDECAYTIME);
  1630. defer_decay_time(flDecayTime);
  1631. }
  1632. if ((eax_d_.ulFlags & EAXREVERBFLAGS_REFLECTIONSSCALE) != 0)
  1633. {
  1634. if ((eax_d_.ulFlags & EAXREVERBFLAGS_REFLECTIONSDELAYSCALE) != 0)
  1635. {
  1636. const auto lReflections = clamp(
  1637. eax_d_.lReflections - static_cast<long>(gain_to_level_mb(scale)),
  1638. EAXREVERB_MINREFLECTIONS,
  1639. EAXREVERB_MAXREFLECTIONS);
  1640. defer_reflections(lReflections);
  1641. }
  1642. }
  1643. if ((eax_d_.ulFlags & EAXREVERBFLAGS_REFLECTIONSDELAYSCALE) != 0)
  1644. {
  1645. const auto flReflectionsDelay = clamp(
  1646. eax_d_.flReflectionsDelay * scale,
  1647. EAXREVERB_MINREFLECTIONSDELAY,
  1648. EAXREVERB_MAXREFLECTIONSDELAY);
  1649. defer_reflections_delay(flReflectionsDelay);
  1650. }
  1651. if ((eax_d_.ulFlags & EAXREVERBFLAGS_REVERBSCALE) != 0)
  1652. {
  1653. const auto log_scalar = ((eax_d_.ulFlags & EAXREVERBFLAGS_DECAYTIMESCALE) != 0) ? 2'000.0F : 3'000.0F;
  1654. const auto lReverb = clamp(
  1655. eax_d_.lReverb - static_cast<long>(std::log10(scale) * log_scalar),
  1656. EAXREVERB_MINREVERB,
  1657. EAXREVERB_MAXREVERB);
  1658. defer_reverb(lReverb);
  1659. }
  1660. if ((eax_d_.ulFlags & EAXREVERBFLAGS_REVERBDELAYSCALE) != 0)
  1661. {
  1662. const auto flReverbDelay = clamp(
  1663. scale * eax_d_.flReverbDelay,
  1664. EAXREVERB_MINREVERBDELAY,
  1665. EAXREVERB_MAXREVERBDELAY);
  1666. defer_reverb_delay(flReverbDelay);
  1667. }
  1668. if ((eax_d_.ulFlags & EAXREVERBFLAGS_ECHOTIMESCALE) != 0)
  1669. {
  1670. const auto flEchoTime = clamp(
  1671. eax_d_.flEchoTime * scale,
  1672. EAXREVERB_MINECHOTIME,
  1673. EAXREVERB_MAXECHOTIME);
  1674. defer_echo_time(flEchoTime);
  1675. }
  1676. if ((eax_d_.ulFlags & EAXREVERBFLAGS_MODULATIONTIMESCALE) != 0)
  1677. {
  1678. const auto flModulationTime = clamp(
  1679. scale * eax_d_.flModulationTime,
  1680. EAXREVERB_MINMODULATIONTIME,
  1681. EAXREVERB_MAXMODULATIONTIME);
  1682. defer_modulation_time(flModulationTime);
  1683. }
  1684. }
  1685. void EaxReverbEffect::defer_environment_diffusion(
  1686. const EaxEaxCall& eax_call)
  1687. {
  1688. const auto& flEnvironmentDiffusion =
  1689. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::flEnvironmentDiffusion)>();
  1690. validate_environment_diffusion(flEnvironmentDiffusion);
  1691. defer_environment_diffusion(flEnvironmentDiffusion);
  1692. }
  1693. void EaxReverbEffect::defer_room(
  1694. const EaxEaxCall& eax_call)
  1695. {
  1696. const auto& lRoom =
  1697. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::lRoom)>();
  1698. validate_room(lRoom);
  1699. defer_room(lRoom);
  1700. }
  1701. void EaxReverbEffect::defer_room_hf(
  1702. const EaxEaxCall& eax_call)
  1703. {
  1704. const auto& lRoomHF =
  1705. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::lRoomHF)>();
  1706. validate_room_hf(lRoomHF);
  1707. defer_room_hf(lRoomHF);
  1708. }
  1709. void EaxReverbEffect::defer_room_lf(
  1710. const EaxEaxCall& eax_call)
  1711. {
  1712. const auto& lRoomLF =
  1713. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::lRoomLF)>();
  1714. validate_room_lf(lRoomLF);
  1715. defer_room_lf(lRoomLF);
  1716. }
  1717. void EaxReverbEffect::defer_decay_time(
  1718. const EaxEaxCall& eax_call)
  1719. {
  1720. const auto& flDecayTime =
  1721. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::flDecayTime)>();
  1722. validate_decay_time(flDecayTime);
  1723. defer_decay_time(flDecayTime);
  1724. }
  1725. void EaxReverbEffect::defer_decay_hf_ratio(
  1726. const EaxEaxCall& eax_call)
  1727. {
  1728. const auto& flDecayHFRatio =
  1729. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::flDecayHFRatio)>();
  1730. validate_decay_hf_ratio(flDecayHFRatio);
  1731. defer_decay_hf_ratio(flDecayHFRatio);
  1732. }
  1733. void EaxReverbEffect::defer_decay_lf_ratio(
  1734. const EaxEaxCall& eax_call)
  1735. {
  1736. const auto& flDecayLFRatio =
  1737. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::flDecayLFRatio)>();
  1738. validate_decay_lf_ratio(flDecayLFRatio);
  1739. defer_decay_lf_ratio(flDecayLFRatio);
  1740. }
  1741. void EaxReverbEffect::defer_reflections(
  1742. const EaxEaxCall& eax_call)
  1743. {
  1744. const auto& lReflections =
  1745. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::lReflections)>();
  1746. validate_reflections(lReflections);
  1747. defer_reflections(lReflections);
  1748. }
  1749. void EaxReverbEffect::defer_reflections_delay(
  1750. const EaxEaxCall& eax_call)
  1751. {
  1752. const auto& flReflectionsDelay =
  1753. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::flReflectionsDelay)>();
  1754. validate_reflections_delay(flReflectionsDelay);
  1755. defer_reflections_delay(flReflectionsDelay);
  1756. }
  1757. void EaxReverbEffect::defer_reflections_pan(
  1758. const EaxEaxCall& eax_call)
  1759. {
  1760. const auto& vReflectionsPan =
  1761. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::vReflectionsPan)>();
  1762. validate_reflections_pan(vReflectionsPan);
  1763. defer_reflections_pan(vReflectionsPan);
  1764. }
  1765. void EaxReverbEffect::defer_reverb(
  1766. const EaxEaxCall& eax_call)
  1767. {
  1768. const auto& lReverb =
  1769. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::lReverb)>();
  1770. validate_reverb(lReverb);
  1771. defer_reverb(lReverb);
  1772. }
  1773. void EaxReverbEffect::defer_reverb_delay(
  1774. const EaxEaxCall& eax_call)
  1775. {
  1776. const auto& flReverbDelay =
  1777. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::flReverbDelay)>();
  1778. validate_reverb_delay(flReverbDelay);
  1779. defer_reverb_delay(flReverbDelay);
  1780. }
  1781. void EaxReverbEffect::defer_reverb_pan(
  1782. const EaxEaxCall& eax_call)
  1783. {
  1784. const auto& vReverbPan =
  1785. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::vReverbPan)>();
  1786. validate_reverb_pan(vReverbPan);
  1787. defer_reverb_pan(vReverbPan);
  1788. }
  1789. void EaxReverbEffect::defer_echo_time(
  1790. const EaxEaxCall& eax_call)
  1791. {
  1792. const auto& flEchoTime =
  1793. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::flEchoTime)>();
  1794. validate_echo_time(flEchoTime);
  1795. defer_echo_time(flEchoTime);
  1796. }
  1797. void EaxReverbEffect::defer_echo_depth(
  1798. const EaxEaxCall& eax_call)
  1799. {
  1800. const auto& flEchoDepth =
  1801. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::flEchoDepth)>();
  1802. validate_echo_depth(flEchoDepth);
  1803. defer_echo_depth(flEchoDepth);
  1804. }
  1805. void EaxReverbEffect::defer_modulation_time(
  1806. const EaxEaxCall& eax_call)
  1807. {
  1808. const auto& flModulationTime =
  1809. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::flModulationTime)>();
  1810. validate_modulation_time(flModulationTime);
  1811. defer_modulation_time(flModulationTime);
  1812. }
  1813. void EaxReverbEffect::defer_modulation_depth(
  1814. const EaxEaxCall& eax_call)
  1815. {
  1816. const auto& flModulationDepth =
  1817. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::flModulationDepth)>();
  1818. validate_modulation_depth(flModulationDepth);
  1819. defer_modulation_depth(flModulationDepth);
  1820. }
  1821. void EaxReverbEffect::defer_air_absorbtion_hf(
  1822. const EaxEaxCall& eax_call)
  1823. {
  1824. const auto& air_absorbtion_hf =
  1825. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::flAirAbsorptionHF)>();
  1826. validate_air_absorbtion_hf(air_absorbtion_hf);
  1827. defer_air_absorbtion_hf(air_absorbtion_hf);
  1828. }
  1829. void EaxReverbEffect::defer_hf_reference(
  1830. const EaxEaxCall& eax_call)
  1831. {
  1832. const auto& flHFReference =
  1833. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::flHFReference)>();
  1834. validate_hf_reference(flHFReference);
  1835. defer_hf_reference(flHFReference);
  1836. }
  1837. void EaxReverbEffect::defer_lf_reference(
  1838. const EaxEaxCall& eax_call)
  1839. {
  1840. const auto& flLFReference =
  1841. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::flLFReference)>();
  1842. validate_lf_reference(flLFReference);
  1843. defer_lf_reference(flLFReference);
  1844. }
  1845. void EaxReverbEffect::defer_room_rolloff_factor(
  1846. const EaxEaxCall& eax_call)
  1847. {
  1848. const auto& flRoomRolloffFactor =
  1849. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::flRoomRolloffFactor)>();
  1850. validate_room_rolloff_factor(flRoomRolloffFactor);
  1851. defer_room_rolloff_factor(flRoomRolloffFactor);
  1852. }
  1853. void EaxReverbEffect::defer_flags(
  1854. const EaxEaxCall& eax_call)
  1855. {
  1856. const auto& ulFlags =
  1857. eax_call.get_value<EaxReverbEffectException, const decltype(EAXREVERBPROPERTIES::ulFlags)>();
  1858. validate_flags(ulFlags);
  1859. defer_flags(ulFlags);
  1860. }
  1861. void EaxReverbEffect::defer_all(
  1862. const EaxEaxCall& eax_call)
  1863. {
  1864. const auto eax_version = eax_call.get_version();
  1865. if (eax_version == 2)
  1866. {
  1867. const auto& listener =
  1868. eax_call.get_value<EaxReverbEffectException, const EAX20LISTENERPROPERTIES>();
  1869. validate_all(listener, eax_version);
  1870. defer_all(listener);
  1871. }
  1872. else
  1873. {
  1874. const auto& reverb_all =
  1875. eax_call.get_value<EaxReverbEffectException, const EAXREVERBPROPERTIES>();
  1876. validate_all(reverb_all, eax_version);
  1877. defer_all(reverb_all);
  1878. }
  1879. }
  1880. void EaxReverbEffect::v1_defer(const EaxEaxCall& eax_call)
  1881. {
  1882. switch (eax_call.get_property_id())
  1883. {
  1884. case DSPROPERTY_EAX_ALL: return v1_defer_all(eax_call);
  1885. case DSPROPERTY_EAX_ENVIRONMENT: return v1_defer_environment(eax_call);
  1886. case DSPROPERTY_EAX_VOLUME: return v1_defer_volume(eax_call);
  1887. case DSPROPERTY_EAX_DECAYTIME: return v1_defer_decay_time(eax_call);
  1888. case DSPROPERTY_EAX_DAMPING: return v1_defer_damping(eax_call);
  1889. default: eax_fail("Unsupported property id.");
  1890. }
  1891. }
  1892. // [[nodiscard]]
  1893. bool EaxReverbEffect::apply_deferred()
  1894. {
  1895. bool ret{false};
  1896. if(unlikely(eax1_dirty_flags_ != Eax1ReverbEffectDirtyFlags{}))
  1897. {
  1898. eax1_ = eax1_d_;
  1899. v1_set_efx();
  1900. eax1_dirty_flags_ = Eax1ReverbEffectDirtyFlags{};
  1901. ret = true;
  1902. }
  1903. if(eax_dirty_flags_ == EaxReverbEffectDirtyFlags{})
  1904. return ret;
  1905. eax_ = eax_d_;
  1906. if (eax_dirty_flags_.ulEnvironment)
  1907. {
  1908. }
  1909. if (eax_dirty_flags_.flEnvironmentSize)
  1910. {
  1911. set_efx_density_from_environment_size();
  1912. }
  1913. if (eax_dirty_flags_.flEnvironmentDiffusion)
  1914. {
  1915. set_efx_diffusion();
  1916. }
  1917. if (eax_dirty_flags_.lRoom)
  1918. {
  1919. set_efx_gain();
  1920. }
  1921. if (eax_dirty_flags_.lRoomHF)
  1922. {
  1923. set_efx_gain_hf();
  1924. }
  1925. if (eax_dirty_flags_.lRoomLF)
  1926. {
  1927. set_efx_gain_lf();
  1928. }
  1929. if (eax_dirty_flags_.flDecayTime)
  1930. {
  1931. set_efx_decay_time();
  1932. }
  1933. if (eax_dirty_flags_.flDecayHFRatio)
  1934. {
  1935. set_efx_decay_hf_ratio();
  1936. }
  1937. if (eax_dirty_flags_.flDecayLFRatio)
  1938. {
  1939. set_efx_decay_lf_ratio();
  1940. }
  1941. if (eax_dirty_flags_.lReflections)
  1942. {
  1943. set_efx_reflections_gain();
  1944. }
  1945. if (eax_dirty_flags_.flReflectionsDelay)
  1946. {
  1947. set_efx_reflections_delay();
  1948. }
  1949. if (eax_dirty_flags_.vReflectionsPan)
  1950. {
  1951. set_efx_reflections_pan();
  1952. }
  1953. if (eax_dirty_flags_.lReverb)
  1954. {
  1955. set_efx_late_reverb_gain();
  1956. }
  1957. if (eax_dirty_flags_.flReverbDelay)
  1958. {
  1959. set_efx_late_reverb_delay();
  1960. }
  1961. if (eax_dirty_flags_.vReverbPan)
  1962. {
  1963. set_efx_late_reverb_pan();
  1964. }
  1965. if (eax_dirty_flags_.flEchoTime)
  1966. {
  1967. set_efx_echo_time();
  1968. }
  1969. if (eax_dirty_flags_.flEchoDepth)
  1970. {
  1971. set_efx_echo_depth();
  1972. }
  1973. if (eax_dirty_flags_.flModulationTime)
  1974. {
  1975. set_efx_modulation_time();
  1976. }
  1977. if (eax_dirty_flags_.flModulationDepth)
  1978. {
  1979. set_efx_modulation_depth();
  1980. }
  1981. if (eax_dirty_flags_.flAirAbsorptionHF)
  1982. {
  1983. set_efx_air_absorption_gain_hf();
  1984. }
  1985. if (eax_dirty_flags_.flHFReference)
  1986. {
  1987. set_efx_hf_reference();
  1988. }
  1989. if (eax_dirty_flags_.flLFReference)
  1990. {
  1991. set_efx_lf_reference();
  1992. }
  1993. if (eax_dirty_flags_.flRoomRolloffFactor)
  1994. {
  1995. set_efx_room_rolloff_factor();
  1996. }
  1997. if (eax_dirty_flags_.ulFlags)
  1998. {
  1999. set_efx_flags();
  2000. }
  2001. eax_dirty_flags_ = EaxReverbEffectDirtyFlags{};
  2002. return true;
  2003. }
  2004. void EaxReverbEffect::set(const EaxEaxCall& eax_call)
  2005. {
  2006. if(eax_call.get_version() == 1)
  2007. v1_defer(eax_call);
  2008. else switch(eax_call.get_property_id())
  2009. {
  2010. case EAXREVERB_NONE:
  2011. break;
  2012. case EAXREVERB_ALLPARAMETERS:
  2013. defer_all(eax_call);
  2014. break;
  2015. case EAXREVERB_ENVIRONMENT:
  2016. defer_environment(eax_call);
  2017. break;
  2018. case EAXREVERB_ENVIRONMENTSIZE:
  2019. defer_environment_size(eax_call);
  2020. break;
  2021. case EAXREVERB_ENVIRONMENTDIFFUSION:
  2022. defer_environment_diffusion(eax_call);
  2023. break;
  2024. case EAXREVERB_ROOM:
  2025. defer_room(eax_call);
  2026. break;
  2027. case EAXREVERB_ROOMHF:
  2028. defer_room_hf(eax_call);
  2029. break;
  2030. case EAXREVERB_ROOMLF:
  2031. defer_room_lf(eax_call);
  2032. break;
  2033. case EAXREVERB_DECAYTIME:
  2034. defer_decay_time(eax_call);
  2035. break;
  2036. case EAXREVERB_DECAYHFRATIO:
  2037. defer_decay_hf_ratio(eax_call);
  2038. break;
  2039. case EAXREVERB_DECAYLFRATIO:
  2040. defer_decay_lf_ratio(eax_call);
  2041. break;
  2042. case EAXREVERB_REFLECTIONS:
  2043. defer_reflections(eax_call);
  2044. break;
  2045. case EAXREVERB_REFLECTIONSDELAY:
  2046. defer_reflections_delay(eax_call);
  2047. break;
  2048. case EAXREVERB_REFLECTIONSPAN:
  2049. defer_reflections_pan(eax_call);
  2050. break;
  2051. case EAXREVERB_REVERB:
  2052. defer_reverb(eax_call);
  2053. break;
  2054. case EAXREVERB_REVERBDELAY:
  2055. defer_reverb_delay(eax_call);
  2056. break;
  2057. case EAXREVERB_REVERBPAN:
  2058. defer_reverb_pan(eax_call);
  2059. break;
  2060. case EAXREVERB_ECHOTIME:
  2061. defer_echo_time(eax_call);
  2062. break;
  2063. case EAXREVERB_ECHODEPTH:
  2064. defer_echo_depth(eax_call);
  2065. break;
  2066. case EAXREVERB_MODULATIONTIME:
  2067. defer_modulation_time(eax_call);
  2068. break;
  2069. case EAXREVERB_MODULATIONDEPTH:
  2070. defer_modulation_depth(eax_call);
  2071. break;
  2072. case EAXREVERB_AIRABSORPTIONHF:
  2073. defer_air_absorbtion_hf(eax_call);
  2074. break;
  2075. case EAXREVERB_HFREFERENCE:
  2076. defer_hf_reference(eax_call);
  2077. break;
  2078. case EAXREVERB_LFREFERENCE:
  2079. defer_lf_reference(eax_call);
  2080. break;
  2081. case EAXREVERB_ROOMROLLOFFFACTOR:
  2082. defer_room_rolloff_factor(eax_call);
  2083. break;
  2084. case EAXREVERB_FLAGS:
  2085. defer_flags(eax_call);
  2086. break;
  2087. default:
  2088. eax_fail("Unsupported property id.");
  2089. }
  2090. }
  2091. const EFXEAXREVERBPROPERTIES eax_efx_reverb_presets[EAX1_ENVIRONMENT_COUNT] =
  2092. {
  2093. EFX_REVERB_PRESET_GENERIC,
  2094. EFX_REVERB_PRESET_PADDEDCELL,
  2095. EFX_REVERB_PRESET_ROOM,
  2096. EFX_REVERB_PRESET_BATHROOM,
  2097. EFX_REVERB_PRESET_LIVINGROOM,
  2098. EFX_REVERB_PRESET_STONEROOM,
  2099. EFX_REVERB_PRESET_AUDITORIUM,
  2100. EFX_REVERB_PRESET_CONCERTHALL,
  2101. EFX_REVERB_PRESET_CAVE,
  2102. EFX_REVERB_PRESET_ARENA,
  2103. EFX_REVERB_PRESET_HANGAR,
  2104. EFX_REVERB_PRESET_CARPETEDHALLWAY,
  2105. EFX_REVERB_PRESET_HALLWAY,
  2106. EFX_REVERB_PRESET_STONECORRIDOR,
  2107. EFX_REVERB_PRESET_ALLEY,
  2108. EFX_REVERB_PRESET_FOREST,
  2109. EFX_REVERB_PRESET_CITY,
  2110. EFX_REVERB_PRESET_MOUNTAINS,
  2111. EFX_REVERB_PRESET_QUARRY,
  2112. EFX_REVERB_PRESET_PLAIN,
  2113. EFX_REVERB_PRESET_PARKINGLOT,
  2114. EFX_REVERB_PRESET_SEWERPIPE,
  2115. EFX_REVERB_PRESET_UNDERWATER,
  2116. EFX_REVERB_PRESET_DRUGGED,
  2117. EFX_REVERB_PRESET_DIZZY,
  2118. EFX_REVERB_PRESET_PSYCHOTIC,
  2119. }; // EFXEAXREVERBPROPERTIES
  2120. } // namespace
  2121. EaxEffectUPtr eax_create_eax_reverb_effect()
  2122. {
  2123. return std::make_unique<EaxReverbEffect>();
  2124. }
  2125. #endif // ALSOFT_EAX