reverb.c 88 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407
  1. /**
  2. * Ambisonic reverb engine for the OpenAL cross platform audio library
  3. * Copyright (C) 2008-2017 by Chris Robinson and Christopher Fitzgerald.
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Library General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2 of the License, or (at your option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Library General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Library General Public
  15. * License along with this library; if not, write to the
  16. * Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. * Or go to http://www.gnu.org/copyleft/lgpl.html
  19. */
  20. #include "config.h"
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <math.h>
  24. #include "alMain.h"
  25. #include "alu.h"
  26. #include "alAuxEffectSlot.h"
  27. #include "alEffect.h"
  28. #include "alFilter.h"
  29. #include "alError.h"
  30. #include "mixer_defs.h"
  31. /* This is the maximum number of samples processed for each inner loop
  32. * iteration. */
  33. #define MAX_UPDATE_SAMPLES 256
  34. /* The number of samples used for cross-faded delay lines. This can be used
  35. * to balance the compensation for abrupt line changes and attenuation due to
  36. * minimally lengthed recursive lines. Try to keep this below the device
  37. * update size.
  38. */
  39. #define FADE_SAMPLES 128
  40. #ifdef __GNUC__
  41. #define UNEXPECTED(x) __builtin_expect((bool)(x), 0)
  42. #else
  43. #define UNEXPECTED(x) (x)
  44. #endif
  45. static MixerFunc MixSamples = Mix_C;
  46. static RowMixerFunc MixRowSamples = MixRow_C;
  47. static alonce_flag mixfunc_inited = AL_ONCE_FLAG_INIT;
  48. static void init_mixfunc(void)
  49. {
  50. MixSamples = SelectMixer();
  51. MixRowSamples = SelectRowMixer();
  52. }
  53. typedef struct DelayLineI {
  54. /* The delay lines use interleaved samples, with the lengths being powers
  55. * of 2 to allow the use of bit-masking instead of a modulus for wrapping.
  56. */
  57. ALsizei Mask;
  58. ALfloat (*Line)[4];
  59. } DelayLineI;
  60. typedef struct VecAllpass {
  61. DelayLineI Delay;
  62. ALsizei Offset[4][2];
  63. } VecAllpass;
  64. typedef struct ALreverbState {
  65. DERIVE_FROM_TYPE(ALeffectState);
  66. ALboolean IsEax;
  67. /* All delay lines are allocated as a single buffer to reduce memory
  68. * fragmentation and management code.
  69. */
  70. ALfloat *SampleBuffer;
  71. ALuint TotalSamples;
  72. /* Master effect filters */
  73. struct {
  74. ALfilterState Lp;
  75. ALfilterState Hp; /* EAX only */
  76. } Filter[4];
  77. /* Core delay line (early reflections and late reverb tap from this). */
  78. DelayLineI Delay;
  79. /* Tap points for early reflection delay. */
  80. ALsizei EarlyDelayTap[4][2];
  81. ALfloat EarlyDelayCoeff[4];
  82. /* Tap points for late reverb feed and delay. */
  83. ALsizei LateFeedTap;
  84. ALsizei LateDelayTap[4][2];
  85. /* The feed-back and feed-forward all-pass coefficient. */
  86. ALfloat ApFeedCoeff;
  87. /* Coefficients for the all-pass and line scattering matrices. */
  88. ALfloat MixX;
  89. ALfloat MixY;
  90. struct {
  91. /* A Gerzon vector all-pass filter is used to simulate initial
  92. * diffusion. The spread from this filter also helps smooth out the
  93. * reverb tail.
  94. */
  95. VecAllpass VecAp;
  96. /* An echo line is used to complete the second half of the early
  97. * reflections.
  98. */
  99. DelayLineI Delay;
  100. ALsizei Offset[4][2];
  101. ALfloat Coeff[4];
  102. /* The gain for each output channel based on 3D panning. */
  103. ALfloat CurrentGain[4][MAX_OUTPUT_CHANNELS];
  104. ALfloat PanGain[4][MAX_OUTPUT_CHANNELS];
  105. } Early;
  106. struct {
  107. /* The vibrato time is tracked with an index over a modulus-wrapped
  108. * range (in samples).
  109. */
  110. ALuint Index;
  111. ALuint Range;
  112. /* The depth of frequency change (also in samples) and its filter. */
  113. ALfloat Depth;
  114. ALfloat Coeff;
  115. ALfloat Filter;
  116. } Mod; /* EAX only */
  117. struct {
  118. /* Attenuation to compensate for the modal density and decay rate of
  119. * the late lines.
  120. */
  121. ALfloat DensityGain;
  122. /* A recursive delay line is used fill in the reverb tail. */
  123. DelayLineI Delay;
  124. ALsizei Offset[4][2];
  125. /* T60 decay filters are used to simulate absorption. */
  126. struct {
  127. ALfloat LFCoeffs[3];
  128. ALfloat HFCoeffs[3];
  129. ALfloat MidCoeff;
  130. /* The LF and HF filters keep a state of the last input and last
  131. * output sample.
  132. */
  133. ALfloat States[2][2];
  134. } Filters[4];
  135. /* A Gerzon vector all-pass filter is used to simulate diffusion. */
  136. VecAllpass VecAp;
  137. /* The gain for each output channel based on 3D panning. */
  138. ALfloat CurrentGain[4][MAX_OUTPUT_CHANNELS];
  139. ALfloat PanGain[4][MAX_OUTPUT_CHANNELS];
  140. } Late;
  141. /* Indicates the cross-fade point for delay line reads [0,FADE_SAMPLES]. */
  142. ALsizei FadeCount;
  143. /* The current write offset for all delay lines. */
  144. ALsizei Offset;
  145. /* Temporary storage used when processing. */
  146. alignas(16) ALfloat AFormatSamples[4][MAX_UPDATE_SAMPLES];
  147. alignas(16) ALfloat ReverbSamples[4][MAX_UPDATE_SAMPLES];
  148. alignas(16) ALfloat EarlySamples[4][MAX_UPDATE_SAMPLES];
  149. } ALreverbState;
  150. static ALvoid ALreverbState_Destruct(ALreverbState *State);
  151. static ALboolean ALreverbState_deviceUpdate(ALreverbState *State, ALCdevice *Device);
  152. static ALvoid ALreverbState_update(ALreverbState *State, const ALCdevice *Device, const ALeffectslot *Slot, const ALeffectProps *props);
  153. static ALvoid ALreverbState_process(ALreverbState *State, ALsizei SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALsizei NumChannels);
  154. DECLARE_DEFAULT_ALLOCATORS(ALreverbState)
  155. DEFINE_ALEFFECTSTATE_VTABLE(ALreverbState);
  156. static void ALreverbState_Construct(ALreverbState *state)
  157. {
  158. ALsizei i, j;
  159. ALeffectState_Construct(STATIC_CAST(ALeffectState, state));
  160. SET_VTABLE2(ALreverbState, ALeffectState, state);
  161. state->IsEax = AL_FALSE;
  162. state->TotalSamples = 0;
  163. state->SampleBuffer = NULL;
  164. for(i = 0;i < 4;i++)
  165. {
  166. ALfilterState_clear(&state->Filter[i].Lp);
  167. ALfilterState_clear(&state->Filter[i].Hp);
  168. }
  169. state->Delay.Mask = 0;
  170. state->Delay.Line = NULL;
  171. for(i = 0;i < 4;i++)
  172. {
  173. state->EarlyDelayTap[i][0] = 0;
  174. state->EarlyDelayTap[i][1] = 0;
  175. state->EarlyDelayCoeff[i] = 0.0f;
  176. }
  177. state->LateFeedTap = 0;
  178. for(i = 0;i < 4;i++)
  179. {
  180. state->LateDelayTap[i][0] = 0;
  181. state->LateDelayTap[i][1] = 0;
  182. }
  183. state->ApFeedCoeff = 0.0f;
  184. state->MixX = 0.0f;
  185. state->MixY = 0.0f;
  186. state->Early.VecAp.Delay.Mask = 0;
  187. state->Early.VecAp.Delay.Line = NULL;
  188. state->Early.Delay.Mask = 0;
  189. state->Early.Delay.Line = NULL;
  190. for(i = 0;i < 4;i++)
  191. {
  192. state->Early.VecAp.Offset[i][0] = 0;
  193. state->Early.VecAp.Offset[i][1] = 0;
  194. state->Early.Offset[i][0] = 0;
  195. state->Early.Offset[i][1] = 0;
  196. state->Early.Coeff[i] = 0.0f;
  197. }
  198. state->Mod.Index = 0;
  199. state->Mod.Range = 1;
  200. state->Mod.Depth = 0.0f;
  201. state->Mod.Coeff = 0.0f;
  202. state->Mod.Filter = 0.0f;
  203. state->Late.DensityGain = 0.0f;
  204. state->Late.Delay.Mask = 0;
  205. state->Late.Delay.Line = NULL;
  206. state->Late.VecAp.Delay.Mask = 0;
  207. state->Late.VecAp.Delay.Line = NULL;
  208. for(i = 0;i < 4;i++)
  209. {
  210. state->Late.Offset[i][0] = 0;
  211. state->Late.Offset[i][1] = 0;
  212. state->Late.VecAp.Offset[i][0] = 0;
  213. state->Late.VecAp.Offset[i][1] = 0;
  214. for(j = 0;j < 3;j++)
  215. {
  216. state->Late.Filters[i].LFCoeffs[j] = 0.0f;
  217. state->Late.Filters[i].HFCoeffs[j] = 0.0f;
  218. }
  219. state->Late.Filters[i].MidCoeff = 0.0f;
  220. state->Late.Filters[i].States[0][0] = 0.0f;
  221. state->Late.Filters[i].States[0][1] = 0.0f;
  222. state->Late.Filters[i].States[1][0] = 0.0f;
  223. state->Late.Filters[i].States[1][1] = 0.0f;
  224. }
  225. for(i = 0;i < 4;i++)
  226. {
  227. for(j = 0;j < MAX_OUTPUT_CHANNELS;j++)
  228. {
  229. state->Early.CurrentGain[i][j] = 0.0f;
  230. state->Early.PanGain[i][j] = 0.0f;
  231. state->Late.CurrentGain[i][j] = 0.0f;
  232. state->Late.PanGain[i][j] = 0.0f;
  233. }
  234. }
  235. state->FadeCount = 0;
  236. state->Offset = 0;
  237. }
  238. static ALvoid ALreverbState_Destruct(ALreverbState *State)
  239. {
  240. al_free(State->SampleBuffer);
  241. State->SampleBuffer = NULL;
  242. ALeffectState_Destruct(STATIC_CAST(ALeffectState,State));
  243. }
  244. /* The B-Format to A-Format conversion matrix. The arrangement of rows is
  245. * deliberately chosen to align the resulting lines to their spatial opposites
  246. * (0:above front left <-> 3:above back right, 1:below front right <-> 2:below
  247. * back left). It's not quite opposite, since the A-Format results in a
  248. * tetrahedron, but it's close enough. Should the model be extended to 8-lines
  249. * in the future, true opposites can be used.
  250. */
  251. static const aluMatrixf B2A = {{
  252. { 0.288675134595f, 0.288675134595f, 0.288675134595f, 0.288675134595f },
  253. { 0.288675134595f, -0.288675134595f, -0.288675134595f, 0.288675134595f },
  254. { 0.288675134595f, 0.288675134595f, -0.288675134595f, -0.288675134595f },
  255. { 0.288675134595f, -0.288675134595f, 0.288675134595f, -0.288675134595f }
  256. }};
  257. /* Converts A-Format to B-Format. */
  258. static const aluMatrixf A2B = {{
  259. { 0.866025403785f, 0.866025403785f, 0.866025403785f, 0.866025403785f },
  260. { 0.866025403785f, -0.866025403785f, 0.866025403785f, -0.866025403785f },
  261. { 0.866025403785f, -0.866025403785f, -0.866025403785f, 0.866025403785f },
  262. { 0.866025403785f, 0.866025403785f, -0.866025403785f, -0.866025403785f }
  263. }};
  264. static const ALfloat FadeStep = 1.0f / FADE_SAMPLES;
  265. /* This is a user config option for modifying the overall output of the reverb
  266. * effect.
  267. */
  268. ALfloat ReverbBoost = 1.0f;
  269. /* Specifies whether to use a standard reverb effect in place of EAX reverb (no
  270. * high-pass, modulation, or echo).
  271. */
  272. ALboolean EmulateEAXReverb = AL_FALSE;
  273. /* The all-pass and delay lines have a variable length dependent on the
  274. * effect's density parameter. The resulting density multiplier is:
  275. *
  276. * multiplier = 1 + (density * LINE_MULTIPLIER)
  277. *
  278. * Thus the line multiplier below will result in a maximum density multiplier
  279. * of 10.
  280. */
  281. static const ALfloat LINE_MULTIPLIER = 9.0f;
  282. /* All delay line lengths are specified in seconds.
  283. *
  284. * To approximate early reflections, we break them up into primary (those
  285. * arriving from the same direction as the source) and secondary (those
  286. * arriving from the opposite direction).
  287. *
  288. * The early taps decorrelate the 4-channel signal to approximate an average
  289. * room response for the primary reflections after the initial early delay.
  290. *
  291. * Given an average room dimension (d_a) and the speed of sound (c) we can
  292. * calculate the average reflection delay (r_a) regardless of listener and
  293. * source positions as:
  294. *
  295. * r_a = d_a / c
  296. * c = 343.3
  297. *
  298. * This can extended to finding the average difference (r_d) between the
  299. * maximum (r_1) and minimum (r_0) reflection delays:
  300. *
  301. * r_0 = 2 / 3 r_a
  302. * = r_a - r_d / 2
  303. * = r_d
  304. * r_1 = 4 / 3 r_a
  305. * = r_a + r_d / 2
  306. * = 2 r_d
  307. * r_d = 2 / 3 r_a
  308. * = r_1 - r_0
  309. *
  310. * As can be determined by integrating the 1D model with a source (s) and
  311. * listener (l) positioned across the dimension of length (d_a):
  312. *
  313. * r_d = int_(l=0)^d_a (int_(s=0)^d_a |2 d_a - 2 (l + s)| ds) dl / c
  314. *
  315. * The initial taps (T_(i=0)^N) are then specified by taking a power series
  316. * that ranges between r_0 and half of r_1 less r_0:
  317. *
  318. * R_i = 2^(i / (2 N - 1)) r_d
  319. * = r_0 + (2^(i / (2 N - 1)) - 1) r_d
  320. * = r_0 + T_i
  321. * T_i = R_i - r_0
  322. * = (2^(i / (2 N - 1)) - 1) r_d
  323. *
  324. * Assuming an average of 5m (up to 50m with the density multiplier), we get
  325. * the following taps:
  326. */
  327. static const ALfloat EARLY_TAP_LENGTHS[4] =
  328. {
  329. 0.000000e+0f, 1.010676e-3f, 2.126553e-3f, 3.358580e-3f
  330. };
  331. /* The early all-pass filter lengths are based on the early tap lengths:
  332. *
  333. * A_i = R_i / a
  334. *
  335. * Where a is the approximate maximum all-pass cycle limit (20).
  336. */
  337. static const ALfloat EARLY_ALLPASS_LENGTHS[4] =
  338. {
  339. 4.854840e-4f, 5.360178e-4f, 5.918117e-4f, 6.534130e-4f
  340. };
  341. /* The early delay lines are used to transform the primary reflections into
  342. * the secondary reflections. The A-format is arranged in such a way that
  343. * the channels/lines are spatially opposite:
  344. *
  345. * C_i is opposite C_(N-i-1)
  346. *
  347. * The delays of the two opposing reflections (R_i and O_i) from a source
  348. * anywhere along a particular dimension always sum to twice its full delay:
  349. *
  350. * 2 r_a = R_i + O_i
  351. *
  352. * With that in mind we can determine the delay between the two reflections
  353. * and thus specify our early line lengths (L_(i=0)^N) using:
  354. *
  355. * O_i = 2 r_a - R_(N-i-1)
  356. * L_i = O_i - R_(N-i-1)
  357. * = 2 (r_a - R_(N-i-1))
  358. * = 2 (r_a - T_(N-i-1) - r_0)
  359. * = 2 r_a (1 - (2 / 3) 2^((N - i - 1) / (2 N - 1)))
  360. *
  361. * Using an average dimension of 5m, we get:
  362. */
  363. static const ALfloat EARLY_LINE_LENGTHS[4] =
  364. {
  365. 2.992520e-3f, 5.456575e-3f, 7.688329e-3f, 9.709681e-3f
  366. };
  367. /* The late all-pass filter lengths are based on the late line lengths:
  368. *
  369. * A_i = (5 / 3) L_i / r_1
  370. */
  371. static const ALfloat LATE_ALLPASS_LENGTHS[4] =
  372. {
  373. 8.091400e-4f, 1.019453e-3f, 1.407968e-3f, 1.618280e-3f
  374. };
  375. /* The late lines are used to approximate the decaying cycle of recursive
  376. * late reflections.
  377. *
  378. * Splitting the lines in half, we start with the shortest reflection paths
  379. * (L_(i=0)^(N/2)):
  380. *
  381. * L_i = 2^(i / (N - 1)) r_d
  382. *
  383. * Then for the opposite (longest) reflection paths (L_(i=N/2)^N):
  384. *
  385. * L_i = 2 r_a - L_(i-N/2)
  386. * = 2 r_a - 2^((i - N / 2) / (N - 1)) r_d
  387. *
  388. * For our 5m average room, we get:
  389. */
  390. static const ALfloat LATE_LINE_LENGTHS[4] =
  391. {
  392. 9.709681e-3f, 1.223343e-2f, 1.689561e-2f, 1.941936e-2f
  393. };
  394. /* This coefficient is used to define the sinus depth according to the
  395. * modulation depth property. This value must be below half the shortest late
  396. * line length (0.0097/2 = ~0.0048), otherwise with certain parameters (high
  397. * mod time, low density) the downswing can sample before the input.
  398. */
  399. static const ALfloat MODULATION_DEPTH_COEFF = 1.0f / 4096.0f;
  400. /* A filter is used to avoid the terrible distortion caused by changing
  401. * modulation time and/or depth. To be consistent across different sample
  402. * rates, the coefficient must be raised to a constant divided by the sample
  403. * rate: coeff^(constant / rate).
  404. */
  405. static const ALfloat MODULATION_FILTER_COEFF = 0.048f;
  406. static const ALfloat MODULATION_FILTER_CONST = 100000.0f;
  407. /* Prior to VS2013, MSVC lacks the round() family of functions. */
  408. #if defined(_MSC_VER) && _MSC_VER < 1800
  409. static inline long lroundf(float val)
  410. {
  411. if(val < 0.0)
  412. return fastf2i(ceilf(val-0.5f));
  413. return fastf2i(floorf(val+0.5f));
  414. }
  415. #endif
  416. /**************************************
  417. * Device Update *
  418. **************************************/
  419. /* Given the allocated sample buffer, this function updates each delay line
  420. * offset.
  421. */
  422. static inline ALvoid RealizeLineOffset(ALfloat *sampleBuffer, DelayLineI *Delay)
  423. {
  424. union {
  425. ALfloat *f;
  426. ALfloat (*f4)[4];
  427. } u;
  428. u.f = &sampleBuffer[(ptrdiff_t)Delay->Line * 4];
  429. Delay->Line = u.f4;
  430. }
  431. /* Calculate the length of a delay line and store its mask and offset. */
  432. static ALuint CalcLineLength(const ALfloat length, const ptrdiff_t offset, const ALuint frequency,
  433. const ALuint extra, DelayLineI *Delay)
  434. {
  435. ALuint samples;
  436. /* All line lengths are powers of 2, calculated from their lengths in
  437. * seconds, rounded up.
  438. */
  439. samples = fastf2i(ceilf(length*frequency));
  440. samples = NextPowerOf2(samples + extra);
  441. /* All lines share a single sample buffer. */
  442. Delay->Mask = samples - 1;
  443. Delay->Line = (ALfloat(*)[4])offset;
  444. /* Return the sample count for accumulation. */
  445. return samples;
  446. }
  447. /* Calculates the delay line metrics and allocates the shared sample buffer
  448. * for all lines given the sample rate (frequency). If an allocation failure
  449. * occurs, it returns AL_FALSE.
  450. */
  451. static ALboolean AllocLines(const ALuint frequency, ALreverbState *State)
  452. {
  453. ALuint totalSamples, i;
  454. ALfloat multiplier, length;
  455. /* All delay line lengths are calculated to accomodate the full range of
  456. * lengths given their respective paramters.
  457. */
  458. totalSamples = 0;
  459. /* Multiplier for the maximum density value, i.e. density=1, which is
  460. * actually the least density...
  461. */
  462. multiplier = 1.0f + LINE_MULTIPLIER;
  463. /* The main delay length includes the maximum early reflection delay, the
  464. * largest early tap width, the maximum late reverb delay, and the
  465. * largest late tap width. Finally, it must also be extended by the
  466. * update size (MAX_UPDATE_SAMPLES) for block processing.
  467. */
  468. length = AL_EAXREVERB_MAX_REFLECTIONS_DELAY +
  469. EARLY_TAP_LENGTHS[3]*multiplier +
  470. AL_EAXREVERB_MAX_LATE_REVERB_DELAY +
  471. (LATE_LINE_LENGTHS[3] - LATE_LINE_LENGTHS[0])*0.25f*multiplier;
  472. totalSamples += CalcLineLength(length, totalSamples, frequency, MAX_UPDATE_SAMPLES,
  473. &State->Delay);
  474. /* The early vector all-pass line. */
  475. length = EARLY_ALLPASS_LENGTHS[3] * multiplier;
  476. totalSamples += CalcLineLength(length, totalSamples, frequency, 0,
  477. &State->Early.VecAp.Delay);
  478. /* The early reflection line. */
  479. length = EARLY_LINE_LENGTHS[3] * multiplier;
  480. totalSamples += CalcLineLength(length, totalSamples, frequency, 0,
  481. &State->Early.Delay);
  482. /* The late vector all-pass line. */
  483. length = LATE_ALLPASS_LENGTHS[3] * multiplier;
  484. totalSamples += CalcLineLength(length, totalSamples, frequency, 0,
  485. &State->Late.VecAp.Delay);
  486. /* The late delay lines are calculated from the larger of the maximum
  487. * density line length or the maximum echo time, and includes the maximum
  488. * modulation-related delay. The modulator's delay is calculated from the
  489. * maximum modulation time and depth coefficient, and halved for the low-
  490. * to-high frequency swing.
  491. */
  492. length = maxf(AL_EAXREVERB_MAX_ECHO_TIME, LATE_LINE_LENGTHS[3]*multiplier) +
  493. AL_EAXREVERB_MAX_MODULATION_TIME*MODULATION_DEPTH_COEFF/2.0f;
  494. totalSamples += CalcLineLength(length, totalSamples, frequency, 0,
  495. &State->Late.Delay);
  496. if(totalSamples != State->TotalSamples)
  497. {
  498. ALfloat *newBuffer;
  499. TRACE("New reverb buffer length: %ux4 samples\n", totalSamples);
  500. newBuffer = al_calloc(16, sizeof(ALfloat[4]) * totalSamples);
  501. if(!newBuffer) return AL_FALSE;
  502. al_free(State->SampleBuffer);
  503. State->SampleBuffer = newBuffer;
  504. State->TotalSamples = totalSamples;
  505. }
  506. /* Update all delays to reflect the new sample buffer. */
  507. RealizeLineOffset(State->SampleBuffer, &State->Delay);
  508. RealizeLineOffset(State->SampleBuffer, &State->Early.VecAp.Delay);
  509. RealizeLineOffset(State->SampleBuffer, &State->Early.Delay);
  510. RealizeLineOffset(State->SampleBuffer, &State->Late.VecAp.Delay);
  511. RealizeLineOffset(State->SampleBuffer, &State->Late.Delay);
  512. /* Clear the sample buffer. */
  513. for(i = 0;i < State->TotalSamples;i++)
  514. State->SampleBuffer[i] = 0.0f;
  515. return AL_TRUE;
  516. }
  517. static ALboolean ALreverbState_deviceUpdate(ALreverbState *State, ALCdevice *Device)
  518. {
  519. ALuint frequency = Device->Frequency, i;
  520. ALfloat multiplier;
  521. /* Allocate the delay lines. */
  522. if(!AllocLines(frequency, State))
  523. return AL_FALSE;
  524. /* Calculate the modulation filter coefficient. Notice that the exponent
  525. * is calculated given the current sample rate. This ensures that the
  526. * resulting filter response over time is consistent across all sample
  527. * rates.
  528. */
  529. State->Mod.Coeff = powf(MODULATION_FILTER_COEFF,
  530. MODULATION_FILTER_CONST / frequency);
  531. multiplier = 1.0f + LINE_MULTIPLIER;
  532. /* The late feed taps are set a fixed position past the latest delay tap. */
  533. for(i = 0;i < 4;i++)
  534. State->LateFeedTap = fastf2i((AL_EAXREVERB_MAX_REFLECTIONS_DELAY +
  535. EARLY_TAP_LENGTHS[3]*multiplier) *
  536. frequency);
  537. return AL_TRUE;
  538. }
  539. /**************************************
  540. * Effect Update *
  541. **************************************/
  542. /* Calculate a decay coefficient given the length of each cycle and the time
  543. * until the decay reaches -60 dB.
  544. */
  545. static inline ALfloat CalcDecayCoeff(const ALfloat length, const ALfloat decayTime)
  546. {
  547. return powf(REVERB_DECAY_GAIN, length/decayTime);
  548. }
  549. /* Calculate a decay length from a coefficient and the time until the decay
  550. * reaches -60 dB.
  551. */
  552. static inline ALfloat CalcDecayLength(const ALfloat coeff, const ALfloat decayTime)
  553. {
  554. return log10f(coeff) * decayTime / log10f(REVERB_DECAY_GAIN);
  555. }
  556. /* Calculate an attenuation to be applied to the input of any echo models to
  557. * compensate for modal density and decay time.
  558. */
  559. static inline ALfloat CalcDensityGain(const ALfloat a)
  560. {
  561. /* The energy of a signal can be obtained by finding the area under the
  562. * squared signal. This takes the form of Sum(x_n^2), where x is the
  563. * amplitude for the sample n.
  564. *
  565. * Decaying feedback matches exponential decay of the form Sum(a^n),
  566. * where a is the attenuation coefficient, and n is the sample. The area
  567. * under this decay curve can be calculated as: 1 / (1 - a).
  568. *
  569. * Modifying the above equation to find the area under the squared curve
  570. * (for energy) yields: 1 / (1 - a^2). Input attenuation can then be
  571. * calculated by inverting the square root of this approximation,
  572. * yielding: 1 / sqrt(1 / (1 - a^2)), simplified to: sqrt(1 - a^2).
  573. */
  574. return sqrtf(1.0f - a*a);
  575. }
  576. /* Calculate the scattering matrix coefficients given a diffusion factor. */
  577. static inline ALvoid CalcMatrixCoeffs(const ALfloat diffusion, ALfloat *x, ALfloat *y)
  578. {
  579. ALfloat n, t;
  580. /* The matrix is of order 4, so n is sqrt(4 - 1). */
  581. n = sqrtf(3.0f);
  582. t = diffusion * atanf(n);
  583. /* Calculate the first mixing matrix coefficient. */
  584. *x = cosf(t);
  585. /* Calculate the second mixing matrix coefficient. */
  586. *y = sinf(t) / n;
  587. }
  588. /* Calculate the limited HF ratio for use with the late reverb low-pass
  589. * filters.
  590. */
  591. static ALfloat CalcLimitedHfRatio(const ALfloat hfRatio, const ALfloat airAbsorptionGainHF,
  592. const ALfloat decayTime)
  593. {
  594. ALfloat limitRatio;
  595. /* Find the attenuation due to air absorption in dB (converting delay
  596. * time to meters using the speed of sound). Then reversing the decay
  597. * equation, solve for HF ratio. The delay length is cancelled out of
  598. * the equation, so it can be calculated once for all lines.
  599. */
  600. limitRatio = 1.0f / (CalcDecayLength(airAbsorptionGainHF, decayTime) *
  601. SPEEDOFSOUNDMETRESPERSEC);
  602. /* Using the limit calculated above, apply the upper bound to the HF
  603. * ratio. Also need to limit the result to a minimum of 0.1, just like
  604. * the HF ratio parameter.
  605. */
  606. return clampf(limitRatio, 0.1f, hfRatio);
  607. }
  608. /* Calculates the first-order high-pass coefficients following the I3DL2
  609. * reference model. This is the transfer function:
  610. *
  611. * 1 - z^-1
  612. * H(z) = p ------------
  613. * 1 - p z^-1
  614. *
  615. * And this is the I3DL2 coefficient calculation given gain (g) and reference
  616. * angular frequency (w):
  617. *
  618. * g
  619. * p = ------------------------------------------------------
  620. * g cos(w) + sqrt((cos(w) - 1) (g^2 cos(w) + g^2 - 2))
  621. *
  622. * The coefficient is applied to the partial differential filter equation as:
  623. *
  624. * c_0 = p
  625. * c_1 = -p
  626. * c_2 = p
  627. * y_i = c_0 x_i + c_1 x_(i-1) + c_2 y_(i-1)
  628. *
  629. */
  630. static inline void CalcHighpassCoeffs(const ALfloat gain, const ALfloat w, ALfloat coeffs[3])
  631. {
  632. ALfloat g, g2, cw, p;
  633. if(gain >= 1.0f)
  634. {
  635. coeffs[0] = 1.0f;
  636. coeffs[1] = 0.0f;
  637. coeffs[2] = 0.0f;
  638. return;
  639. }
  640. g = maxf(0.001f, gain);
  641. g2 = g * g;
  642. cw = cosf(w);
  643. p = g / (g*cw + sqrtf((cw - 1.0f) * (g2*cw + g2 - 2.0f)));
  644. coeffs[0] = p;
  645. coeffs[1] = -p;
  646. coeffs[2] = p;
  647. }
  648. /* Calculates the first-order low-pass coefficients following the I3DL2
  649. * reference model. This is the transfer function:
  650. *
  651. * (1 - a) z^0
  652. * H(z) = ----------------
  653. * 1 z^0 - a z^-1
  654. *
  655. * And this is the I3DL2 coefficient calculation given gain (g) and reference
  656. * angular frequency (w):
  657. *
  658. * 1 - g^2 cos(w) - sqrt(2 g^2 (1 - cos(w)) - g^4 (1 - cos(w)^2))
  659. * a = ----------------------------------------------------------------
  660. * 1 - g^2
  661. *
  662. * The coefficient is applied to the partial differential filter equation as:
  663. *
  664. * c_0 = 1 - a
  665. * c_1 = 0
  666. * c_2 = a
  667. * y_i = c_0 x_i + c_1 x_(i-1) + c_2 y_(i-1)
  668. *
  669. */
  670. static inline void CalcLowpassCoeffs(const ALfloat gain, const ALfloat w, ALfloat coeffs[3])
  671. {
  672. ALfloat g, g2, cw, a;
  673. if(gain >= 1.0f)
  674. {
  675. coeffs[0] = 1.0f;
  676. coeffs[1] = 0.0f;
  677. coeffs[2] = 0.0f;
  678. return;
  679. }
  680. /* Be careful with gains < 0.001, as that causes the coefficient
  681. * to head towards 1, which will flatten the signal. */
  682. g = maxf(0.001f, gain);
  683. g2 = g * g;
  684. cw = cosf(w);
  685. a = (1.0f - g2*cw - sqrtf((2.0f*g2*(1.0f - cw)) - g2*g2*(1.0f - cw*cw))) /
  686. (1.0f - g2);
  687. coeffs[0] = 1.0f - a;
  688. coeffs[1] = 0.0f;
  689. coeffs[2] = a;
  690. }
  691. /* Calculates the first-order low-shelf coefficients. The shelf filters are
  692. * used in place of low/high-pass filters to preserve the mid-band. This is
  693. * the transfer function:
  694. *
  695. * a_0 + a_1 z^-1
  696. * H(z) = ----------------
  697. * 1 + b_1 z^-1
  698. *
  699. * And these are the coefficient calculations given cut gain (g) and a center
  700. * angular frequency (w):
  701. *
  702. * sin(0.5 (pi - w) - 0.25 pi)
  703. * p = -----------------------------
  704. * sin(0.5 (pi - w) + 0.25 pi)
  705. *
  706. * g + 1 g + 1
  707. * a = ------- + sqrt((-------)^2 - 1)
  708. * g - 1 g - 1
  709. *
  710. * 1 + g + (1 - g) a
  711. * b_0 = -------------------
  712. * 2
  713. *
  714. * 1 - g + (1 + g) a
  715. * b_1 = -------------------
  716. * 2
  717. *
  718. * The coefficients are applied to the partial differential filter equation
  719. * as:
  720. *
  721. * b_0 + p b_1
  722. * c_0 = -------------
  723. * 1 + p a
  724. *
  725. * -(b_1 + p b_0)
  726. * c_1 = ----------------
  727. * 1 + p a
  728. *
  729. * p + a
  730. * c_2 = ---------
  731. * 1 + p a
  732. *
  733. * y_i = c_0 x_i + c_1 x_(i-1) + c_2 y_(i-1)
  734. *
  735. */
  736. static inline void CalcLowShelfCoeffs(const ALfloat gain, const ALfloat w, ALfloat coeffs[3])
  737. {
  738. ALfloat g, rw, p, n;
  739. ALfloat alpha, beta0, beta1;
  740. if(gain >= 1.0f)
  741. {
  742. coeffs[0] = 1.0f;
  743. coeffs[1] = 0.0f;
  744. coeffs[2] = 0.0f;
  745. return;
  746. }
  747. g = maxf(0.001f, gain);
  748. rw = F_PI - w;
  749. p = sinf(0.5f*rw - 0.25f*F_PI) / sinf(0.5f*rw + 0.25f*F_PI);
  750. n = (g + 1.0f) / (g - 1.0f);
  751. alpha = n + sqrtf(n*n - 1.0f);
  752. beta0 = (1.0f + g + (1.0f - g)*alpha) / 2.0f;
  753. beta1 = (1.0f - g + (1.0f + g)*alpha) / 2.0f;
  754. coeffs[0] = (beta0 + p*beta1) / (1.0f + p*alpha);
  755. coeffs[1] = -(beta1 + p*beta0) / (1.0f + p*alpha);
  756. coeffs[2] = (p + alpha) / (1.0f + p*alpha);
  757. }
  758. /* Calculates the first-order high-shelf coefficients. The shelf filters are
  759. * used in place of low/high-pass filters to preserve the mid-band. This is
  760. * the transfer function:
  761. *
  762. * a_0 + a_1 z^-1
  763. * H(z) = ----------------
  764. * 1 + b_1 z^-1
  765. *
  766. * And these are the coefficient calculations given cut gain (g) and a center
  767. * angular frequency (w):
  768. *
  769. * sin(0.5 w - 0.25 pi)
  770. * p = ----------------------
  771. * sin(0.5 w + 0.25 pi)
  772. *
  773. * g + 1 g + 1
  774. * a = ------- + sqrt((-------)^2 - 1)
  775. * g - 1 g - 1
  776. *
  777. * 1 + g + (1 - g) a
  778. * b_0 = -------------------
  779. * 2
  780. *
  781. * 1 - g + (1 + g) a
  782. * b_1 = -------------------
  783. * 2
  784. *
  785. * The coefficients are applied to the partial differential filter equation
  786. * as:
  787. *
  788. * b_0 + p b_1
  789. * c_0 = -------------
  790. * 1 + p a
  791. *
  792. * b_1 + p b_0
  793. * c_1 = -------------
  794. * 1 + p a
  795. *
  796. * -(p + a)
  797. * c_2 = ----------
  798. * 1 + p a
  799. *
  800. * y_i = c_0 x_i + c_1 x_(i-1) + c_2 y_(i-1)
  801. *
  802. */
  803. static inline void CalcHighShelfCoeffs(const ALfloat gain, const ALfloat w, ALfloat coeffs[3])
  804. {
  805. ALfloat g, p, n;
  806. ALfloat alpha, beta0, beta1;
  807. if(gain >= 1.0f)
  808. {
  809. coeffs[0] = 1.0f;
  810. coeffs[1] = 0.0f;
  811. coeffs[2] = 0.0f;
  812. return;
  813. }
  814. g = maxf(0.001f, gain);
  815. p = sinf(0.5f*w - 0.25f*F_PI) / sinf(0.5f*w + 0.25f*F_PI);
  816. n = (g + 1.0f) / (g - 1.0f);
  817. alpha = n + sqrtf(n*n - 1.0f);
  818. beta0 = (1.0f + g + (1.0f - g)*alpha) / 2.0f;
  819. beta1 = (1.0f - g + (1.0f + g)*alpha) / 2.0f;
  820. coeffs[0] = (beta0 + p*beta1) / (1.0f + p*alpha);
  821. coeffs[1] = (beta1 + p*beta0) / (1.0f + p*alpha);
  822. coeffs[2] = -(p + alpha) / (1.0f + p*alpha);
  823. }
  824. /* Calculates the 3-band T60 damping coefficients for a particular delay line
  825. * of specified length using a combination of two low/high-pass/shelf or
  826. * pass-through filter sections (producing 3 coefficients each) and a general
  827. * gain (7th coefficient) given decay times for each band split at two (LF/
  828. * HF) reference frequencies (w).
  829. */
  830. static void CalcT60DampingCoeffs(const ALfloat length, const ALfloat lfDecayTime,
  831. const ALfloat mfDecayTime, const ALfloat hfDecayTime,
  832. const ALfloat lfW, const ALfloat hfW, ALfloat lfcoeffs[3],
  833. ALfloat hfcoeffs[3], ALfloat *midcoeff)
  834. {
  835. ALfloat lfGain = CalcDecayCoeff(length, lfDecayTime);
  836. ALfloat mfGain = CalcDecayCoeff(length, mfDecayTime);
  837. ALfloat hfGain = CalcDecayCoeff(length, hfDecayTime);
  838. if(lfGain < mfGain)
  839. {
  840. if(mfGain < hfGain)
  841. {
  842. CalcLowShelfCoeffs(mfGain / hfGain, hfW, lfcoeffs);
  843. CalcHighpassCoeffs(lfGain / mfGain, lfW, hfcoeffs);
  844. *midcoeff = hfGain;
  845. }
  846. else if(mfGain > hfGain)
  847. {
  848. CalcHighpassCoeffs(lfGain / mfGain, lfW, lfcoeffs);
  849. CalcLowpassCoeffs(hfGain / mfGain, hfW, hfcoeffs);
  850. *midcoeff = mfGain;
  851. }
  852. else
  853. {
  854. lfcoeffs[0] = 1.0f;
  855. lfcoeffs[1] = 0.0f;
  856. lfcoeffs[2] = 0.0f;
  857. CalcHighpassCoeffs(lfGain / mfGain, lfW, hfcoeffs);
  858. *midcoeff = mfGain;
  859. }
  860. }
  861. else if(lfGain > mfGain)
  862. {
  863. if(mfGain < hfGain)
  864. {
  865. ALfloat hg = mfGain / lfGain;
  866. ALfloat lg = mfGain / hfGain;
  867. CalcHighShelfCoeffs(hg, lfW, lfcoeffs);
  868. CalcLowShelfCoeffs(lg, hfW, hfcoeffs);
  869. *midcoeff = maxf(lfGain, hfGain) / maxf(hg, lg);
  870. }
  871. else if(mfGain > hfGain)
  872. {
  873. CalcHighShelfCoeffs(mfGain / lfGain, lfW, lfcoeffs);
  874. CalcLowpassCoeffs(hfGain / mfGain, hfW, hfcoeffs);
  875. *midcoeff = lfGain;
  876. }
  877. else
  878. {
  879. lfcoeffs[0] = 1.0f;
  880. lfcoeffs[1] = 0.0f;
  881. lfcoeffs[2] = 0.0f;
  882. CalcHighShelfCoeffs(mfGain / lfGain, lfW, hfcoeffs);
  883. *midcoeff = lfGain;
  884. }
  885. }
  886. else
  887. {
  888. lfcoeffs[0] = 1.0f;
  889. lfcoeffs[1] = 0.0f;
  890. lfcoeffs[2] = 0.0f;
  891. if(mfGain < hfGain)
  892. {
  893. CalcLowShelfCoeffs(mfGain / hfGain, hfW, hfcoeffs);
  894. *midcoeff = hfGain;
  895. }
  896. else if(mfGain > hfGain)
  897. {
  898. CalcLowpassCoeffs(hfGain / mfGain, hfW, hfcoeffs);
  899. *midcoeff = mfGain;
  900. }
  901. else
  902. {
  903. hfcoeffs[3] = 1.0f;
  904. hfcoeffs[4] = 0.0f;
  905. hfcoeffs[5] = 0.0f;
  906. *midcoeff = mfGain;
  907. }
  908. }
  909. }
  910. /* Update the EAX modulation index, range, and depth. Keep in mind that this
  911. * kind of vibrato is additive and not multiplicative as one may expect. The
  912. * downswing will sound stronger than the upswing.
  913. */
  914. static ALvoid UpdateModulator(const ALfloat modTime, const ALfloat modDepth,
  915. const ALuint frequency, ALreverbState *State)
  916. {
  917. ALuint range;
  918. /* Modulation is calculated in two parts.
  919. *
  920. * The modulation time effects the speed of the sinus. An index out of the
  921. * current range (both in samples) is incremented each sample, so a longer
  922. * time implies a larger range. The range is bound to a reasonable minimum
  923. * (1 sample) and when the timing changes, the index is rescaled to the new
  924. * range to keep the sinus consistent.
  925. */
  926. range = maxi(fastf2i(modTime*frequency), 1);
  927. State->Mod.Index = (ALuint)(State->Mod.Index * (ALuint64)range /
  928. State->Mod.Range);
  929. State->Mod.Range = range;
  930. /* The modulation depth effects the scale of the sinus, which changes how
  931. * much extra delay is added to the delay line. This delay changing over
  932. * time changes the pitch, creating the modulation effect. The scale needs
  933. * to be multiplied by the modulation time so that a given depth produces a
  934. * consistent shift in frequency over all ranges of time. Since the depth
  935. * is applied to a sinus value, it needs to be halved for the sinus swing
  936. * in time (half of it is spent decreasing the frequency, half is spent
  937. * increasing it).
  938. */
  939. State->Mod.Depth = modDepth * MODULATION_DEPTH_COEFF * modTime / 2.0f *
  940. frequency;
  941. }
  942. /* Update the offsets for the main effect delay line. */
  943. static ALvoid UpdateDelayLine(const ALfloat earlyDelay, const ALfloat lateDelay, const ALfloat density, const ALfloat decayTime, const ALuint frequency, ALreverbState *State)
  944. {
  945. ALfloat multiplier, length;
  946. ALuint i;
  947. multiplier = 1.0f + density*LINE_MULTIPLIER;
  948. /* Early reflection taps are decorrelated by means of an average room
  949. * reflection approximation described above the definition of the taps.
  950. * This approximation is linear and so the above density multiplier can
  951. * be applied to adjust the width of the taps. A single-band decay
  952. * coefficient is applied to simulate initial attenuation and absorption.
  953. *
  954. * Late reverb taps are based on the late line lengths to allow a zero-
  955. * delay path and offsets that would continue the propagation naturally
  956. * into the late lines.
  957. */
  958. for(i = 0;i < 4;i++)
  959. {
  960. length = earlyDelay + EARLY_TAP_LENGTHS[i]*multiplier;
  961. State->EarlyDelayTap[i][1] = fastf2i(length * frequency);
  962. length = EARLY_TAP_LENGTHS[i]*multiplier;
  963. State->EarlyDelayCoeff[i] = CalcDecayCoeff(length, decayTime);
  964. length = lateDelay + (LATE_LINE_LENGTHS[i] - LATE_LINE_LENGTHS[0])*0.25f*multiplier;
  965. State->LateDelayTap[i][1] = State->LateFeedTap + fastf2i(length * frequency);
  966. }
  967. }
  968. /* Update the early reflection line lengths and gain coefficients. */
  969. static ALvoid UpdateEarlyLines(const ALfloat density, const ALfloat decayTime, const ALuint frequency, ALreverbState *State)
  970. {
  971. ALfloat multiplier, length;
  972. ALsizei i;
  973. multiplier = 1.0f + density*LINE_MULTIPLIER;
  974. for(i = 0;i < 4;i++)
  975. {
  976. /* Calculate the length (in seconds) of each all-pass line. */
  977. length = EARLY_ALLPASS_LENGTHS[i] * multiplier;
  978. /* Calculate the delay offset for each all-pass line. */
  979. State->Early.VecAp.Offset[i][1] = fastf2i(length * frequency);
  980. /* Calculate the length (in seconds) of each delay line. */
  981. length = EARLY_LINE_LENGTHS[i] * multiplier;
  982. /* Calculate the delay offset for each delay line. */
  983. State->Early.Offset[i][1] = fastf2i(length * frequency);
  984. /* Calculate the gain (coefficient) for each line. */
  985. State->Early.Coeff[i] = CalcDecayCoeff(length, decayTime);
  986. }
  987. }
  988. /* Update the late reverb line lengths and T60 coefficients. */
  989. static ALvoid UpdateLateLines(const ALfloat density, const ALfloat diffusion, const ALfloat lfDecayTime, const ALfloat mfDecayTime, const ALfloat hfDecayTime, const ALfloat lfW, const ALfloat hfW, const ALfloat echoTime, const ALfloat echoDepth, const ALuint frequency, ALreverbState *State)
  990. {
  991. ALfloat multiplier, length, bandWeights[3];
  992. ALsizei i;
  993. /* To compensate for changes in modal density and decay time of the late
  994. * reverb signal, the input is attenuated based on the maximal energy of
  995. * the outgoing signal. This approximation is used to keep the apparent
  996. * energy of the signal equal for all ranges of density and decay time.
  997. *
  998. * The average length of the delay lines is used to calculate the
  999. * attenuation coefficient.
  1000. */
  1001. multiplier = 1.0f + density*LINE_MULTIPLIER;
  1002. length = (LATE_LINE_LENGTHS[0] + LATE_LINE_LENGTHS[1] +
  1003. LATE_LINE_LENGTHS[2] + LATE_LINE_LENGTHS[3]) / 4.0f * multiplier;
  1004. /* Include the echo transformation (see below). */
  1005. length = lerp(length, echoTime, echoDepth);
  1006. length += (LATE_ALLPASS_LENGTHS[0] + LATE_ALLPASS_LENGTHS[1] +
  1007. LATE_ALLPASS_LENGTHS[2] + LATE_ALLPASS_LENGTHS[3]) / 4.0f * multiplier;
  1008. /* The density gain calculation uses an average decay time weighted by
  1009. * approximate bandwidth. This attempts to compensate for losses of
  1010. * energy that reduce decay time due to scattering into highly attenuated
  1011. * bands.
  1012. */
  1013. bandWeights[0] = lfW;
  1014. bandWeights[1] = hfW - lfW;
  1015. bandWeights[2] = F_TAU - hfW;
  1016. State->Late.DensityGain = CalcDensityGain(
  1017. CalcDecayCoeff(length, (bandWeights[0]*lfDecayTime + bandWeights[1]*mfDecayTime +
  1018. bandWeights[2]*hfDecayTime) / F_TAU)
  1019. );
  1020. for(i = 0;i < 4;i++)
  1021. {
  1022. /* Calculate the length (in seconds) of each all-pass line. */
  1023. length = LATE_ALLPASS_LENGTHS[i] * multiplier;
  1024. /* Calculate the delay offset for each all-pass line. */
  1025. State->Late.VecAp.Offset[i][1] = fastf2i(length * frequency);
  1026. /* Calculate the length (in seconds) of each delay line. This also
  1027. * applies the echo transformation. As the EAX echo depth approaches
  1028. * 1, the line lengths approach a length equal to the echoTime. This
  1029. * helps to produce distinct echoes along the tail.
  1030. */
  1031. length = lerp(LATE_LINE_LENGTHS[i] * multiplier, echoTime, echoDepth);
  1032. /* Calculate the delay offset for each delay line. */
  1033. State->Late.Offset[i][1] = fastf2i(length * frequency);
  1034. /* Approximate the absorption that the vector all-pass would exhibit
  1035. * given the current diffusion so we don't have to process a full T60
  1036. * filter for each of its four lines.
  1037. */
  1038. length += lerp(LATE_ALLPASS_LENGTHS[i],
  1039. (LATE_ALLPASS_LENGTHS[0] + LATE_ALLPASS_LENGTHS[1] +
  1040. LATE_ALLPASS_LENGTHS[2] + LATE_ALLPASS_LENGTHS[3]) / 4.0f,
  1041. diffusion) * multiplier;
  1042. /* Calculate the T60 damping coefficients for each line. */
  1043. CalcT60DampingCoeffs(length, lfDecayTime, mfDecayTime, hfDecayTime,
  1044. lfW, hfW, State->Late.Filters[i].LFCoeffs,
  1045. State->Late.Filters[i].HFCoeffs,
  1046. &State->Late.Filters[i].MidCoeff);
  1047. }
  1048. }
  1049. /* Creates a transform matrix given a reverb vector. This works by creating a
  1050. * Z-focus transform, then a rotate transform around X, then Y, to place the
  1051. * focal point in the direction of the vector, using the vector length as a
  1052. * focus strength.
  1053. *
  1054. * This isn't technically correct since the vector is supposed to define the
  1055. * aperture and not rotate the perceived soundfield, but in practice it's
  1056. * probably good enough.
  1057. */
  1058. static aluMatrixf GetTransformFromVector(const ALfloat *vec)
  1059. {
  1060. aluMatrixf zfocus, xrot, yrot;
  1061. aluMatrixf tmp1, tmp2;
  1062. ALfloat length;
  1063. ALfloat sa, a;
  1064. length = sqrtf(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
  1065. /* Define a Z-focus (X in Ambisonics) transform, given the panning vector
  1066. * length.
  1067. */
  1068. sa = sinf(minf(length, 1.0f) * (F_PI/4.0f));
  1069. aluMatrixfSet(&zfocus,
  1070. 1.0f/(1.0f+sa), 0.0f, 0.0f, (sa/(1.0f+sa))/1.732050808f,
  1071. 0.0f, sqrtf((1.0f-sa)/(1.0f+sa)), 0.0f, 0.0f,
  1072. 0.0f, 0.0f, sqrtf((1.0f-sa)/(1.0f+sa)), 0.0f,
  1073. (sa/(1.0f+sa))*1.732050808f, 0.0f, 0.0f, 1.0f/(1.0f+sa)
  1074. );
  1075. /* Define rotation around X (Y in Ambisonics) */
  1076. a = atan2f(vec[1], sqrtf(vec[0]*vec[0] + vec[2]*vec[2]));
  1077. aluMatrixfSet(&xrot,
  1078. 1.0f, 0.0f, 0.0f, 0.0f,
  1079. 0.0f, 1.0f, 0.0f, 0.0f,
  1080. 0.0f, 0.0f, cosf(a), sinf(a),
  1081. 0.0f, 0.0f, -sinf(a), cosf(a)
  1082. );
  1083. /* Define rotation around Y (Z in Ambisonics). NOTE: EFX's reverb vectors
  1084. * use a right-handled coordinate system, compared to the rest of OpenAL
  1085. * which uses left-handed. This is fixed by negating Z, however it would
  1086. * need to also be negated to get a proper Ambisonics angle, thus
  1087. * cancelling it out.
  1088. */
  1089. a = atan2f(-vec[0], vec[2]);
  1090. aluMatrixfSet(&yrot,
  1091. 1.0f, 0.0f, 0.0f, 0.0f,
  1092. 0.0f, cosf(a), 0.0f, sinf(a),
  1093. 0.0f, 0.0f, 1.0f, 0.0f,
  1094. 0.0f, -sinf(a), 0.0f, cosf(a)
  1095. );
  1096. #define MATRIX_MULT(_res, _m1, _m2) do { \
  1097. int row, col; \
  1098. for(col = 0;col < 4;col++) \
  1099. { \
  1100. for(row = 0;row < 4;row++) \
  1101. _res.m[row][col] = _m1.m[row][0]*_m2.m[0][col] + _m1.m[row][1]*_m2.m[1][col] + \
  1102. _m1.m[row][2]*_m2.m[2][col] + _m1.m[row][3]*_m2.m[3][col]; \
  1103. } \
  1104. } while(0)
  1105. /* Define a matrix that first focuses on Z, then rotates around X then Y to
  1106. * focus the output in the direction of the vector.
  1107. */
  1108. MATRIX_MULT(tmp1, xrot, zfocus);
  1109. MATRIX_MULT(tmp2, yrot, tmp1);
  1110. #undef MATRIX_MULT
  1111. return tmp2;
  1112. }
  1113. /* Update the early and late 3D panning gains. */
  1114. static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *ReflectionsPan, const ALfloat *LateReverbPan, const ALfloat gain, const ALfloat earlyGain, const ALfloat lateGain, ALreverbState *State)
  1115. {
  1116. aluMatrixf transform, rot;
  1117. ALsizei i;
  1118. STATIC_CAST(ALeffectState,State)->OutBuffer = Device->FOAOut.Buffer;
  1119. STATIC_CAST(ALeffectState,State)->OutChannels = Device->FOAOut.NumChannels;
  1120. /* Note: _res is transposed. */
  1121. #define MATRIX_MULT(_res, _m1, _m2) do { \
  1122. int row, col; \
  1123. for(col = 0;col < 4;col++) \
  1124. { \
  1125. for(row = 0;row < 4;row++) \
  1126. _res.m[col][row] = _m1.m[row][0]*_m2.m[0][col] + _m1.m[row][1]*_m2.m[1][col] + \
  1127. _m1.m[row][2]*_m2.m[2][col] + _m1.m[row][3]*_m2.m[3][col]; \
  1128. } \
  1129. } while(0)
  1130. /* Create a matrix that first converts A-Format to B-Format, then rotates
  1131. * the B-Format soundfield according to the panning vector.
  1132. */
  1133. rot = GetTransformFromVector(ReflectionsPan);
  1134. MATRIX_MULT(transform, rot, A2B);
  1135. memset(&State->Early.PanGain, 0, sizeof(State->Early.PanGain));
  1136. for(i = 0;i < MAX_EFFECT_CHANNELS;i++)
  1137. ComputeFirstOrderGains(Device->FOAOut, transform.m[i], gain*earlyGain, State->Early.PanGain[i]);
  1138. rot = GetTransformFromVector(LateReverbPan);
  1139. MATRIX_MULT(transform, rot, A2B);
  1140. memset(&State->Late.PanGain, 0, sizeof(State->Late.PanGain));
  1141. for(i = 0;i < MAX_EFFECT_CHANNELS;i++)
  1142. ComputeFirstOrderGains(Device->FOAOut, transform.m[i], gain*lateGain, State->Late.PanGain[i]);
  1143. #undef MATRIX_MULT
  1144. }
  1145. static ALvoid ALreverbState_update(ALreverbState *State, const ALCdevice *Device, const ALeffectslot *Slot, const ALeffectProps *props)
  1146. {
  1147. ALuint frequency = Device->Frequency;
  1148. ALfloat lfScale, hfScale, hfRatio;
  1149. ALfloat lfDecayTime, hfDecayTime;
  1150. ALfloat gain, gainlf, gainhf;
  1151. ALsizei i;
  1152. if(Slot->Params.EffectType == AL_EFFECT_EAXREVERB && !EmulateEAXReverb)
  1153. State->IsEax = AL_TRUE;
  1154. else if(Slot->Params.EffectType == AL_EFFECT_REVERB || EmulateEAXReverb)
  1155. State->IsEax = AL_FALSE;
  1156. /* Calculate the master filters */
  1157. hfScale = props->Reverb.HFReference / frequency;
  1158. /* Restrict the filter gains from going below -60dB to keep the filter from
  1159. * killing most of the signal.
  1160. */
  1161. gainhf = maxf(props->Reverb.GainHF, 0.001f);
  1162. ALfilterState_setParams(&State->Filter[0].Lp, ALfilterType_HighShelf,
  1163. gainhf, hfScale, calc_rcpQ_from_slope(gainhf, 1.0f));
  1164. lfScale = props->Reverb.LFReference / frequency;
  1165. gainlf = maxf(props->Reverb.GainLF, 0.001f);
  1166. ALfilterState_setParams(&State->Filter[0].Hp, ALfilterType_LowShelf,
  1167. gainlf, lfScale, calc_rcpQ_from_slope(gainlf, 1.0f));
  1168. for(i = 1;i < 4;i++)
  1169. {
  1170. ALfilterState_copyParams(&State->Filter[i].Lp, &State->Filter[0].Lp);
  1171. ALfilterState_copyParams(&State->Filter[i].Hp, &State->Filter[0].Hp);
  1172. }
  1173. /* Update the main effect delay and associated taps. */
  1174. UpdateDelayLine(props->Reverb.ReflectionsDelay, props->Reverb.LateReverbDelay,
  1175. props->Reverb.Density, props->Reverb.DecayTime, frequency,
  1176. State);
  1177. /* Calculate the all-pass feed-back/forward coefficient. */
  1178. State->ApFeedCoeff = sqrtf(0.5f) * powf(props->Reverb.Diffusion, 2.0f);
  1179. /* Update the early lines. */
  1180. UpdateEarlyLines(props->Reverb.Density, props->Reverb.DecayTime,
  1181. frequency, State);
  1182. /* Get the mixing matrix coefficients. */
  1183. CalcMatrixCoeffs(props->Reverb.Diffusion, &State->MixX, &State->MixY);
  1184. /* If the HF limit parameter is flagged, calculate an appropriate limit
  1185. * based on the air absorption parameter.
  1186. */
  1187. hfRatio = props->Reverb.DecayHFRatio;
  1188. if(props->Reverb.DecayHFLimit && props->Reverb.AirAbsorptionGainHF < 1.0f)
  1189. hfRatio = CalcLimitedHfRatio(hfRatio, props->Reverb.AirAbsorptionGainHF,
  1190. props->Reverb.DecayTime);
  1191. /* Calculate the LF/HF decay times. */
  1192. lfDecayTime = clampf(props->Reverb.DecayTime * props->Reverb.DecayLFRatio,
  1193. AL_EAXREVERB_MIN_DECAY_TIME, AL_EAXREVERB_MAX_DECAY_TIME);
  1194. hfDecayTime = clampf(props->Reverb.DecayTime * hfRatio,
  1195. AL_EAXREVERB_MIN_DECAY_TIME, AL_EAXREVERB_MAX_DECAY_TIME);
  1196. /* Update the modulator line. */
  1197. UpdateModulator(props->Reverb.ModulationTime, props->Reverb.ModulationDepth,
  1198. frequency, State);
  1199. /* Update the late lines. */
  1200. UpdateLateLines(props->Reverb.Density, props->Reverb.Diffusion,
  1201. lfDecayTime, props->Reverb.DecayTime, hfDecayTime,
  1202. F_TAU * lfScale, F_TAU * hfScale,
  1203. props->Reverb.EchoTime, props->Reverb.EchoDepth,
  1204. frequency, State);
  1205. /* Update early and late 3D panning. */
  1206. gain = props->Reverb.Gain * Slot->Params.Gain * ReverbBoost;
  1207. Update3DPanning(Device, props->Reverb.ReflectionsPan,
  1208. props->Reverb.LateReverbPan, gain,
  1209. props->Reverb.ReflectionsGain,
  1210. props->Reverb.LateReverbGain, State);
  1211. /* Determine if delay-line cross-fading is required. */
  1212. for(i = 0;i < 4;i++)
  1213. {
  1214. if((State->EarlyDelayTap[i][1] != State->EarlyDelayTap[i][0]) ||
  1215. (State->Early.VecAp.Offset[i][1] != State->Early.VecAp.Offset[i][0]) ||
  1216. (State->Early.Offset[i][1] != State->Early.Offset[i][0]) ||
  1217. (State->LateDelayTap[i][1] != State->LateDelayTap[i][0]) ||
  1218. (State->Late.VecAp.Offset[i][1] != State->Late.VecAp.Offset[i][0]) ||
  1219. (State->Late.Offset[i][1] != State->Late.Offset[i][0]))
  1220. {
  1221. State->FadeCount = 0;
  1222. break;
  1223. }
  1224. }
  1225. }
  1226. /**************************************
  1227. * Effect Processing *
  1228. **************************************/
  1229. /* Basic delay line input/output routines. */
  1230. static inline ALfloat DelayLineOut(const DelayLineI *Delay, const ALsizei offset, const ALsizei c)
  1231. {
  1232. return Delay->Line[offset&Delay->Mask][c];
  1233. }
  1234. /* Cross-faded delay line output routine. Instead of interpolating the
  1235. * offsets, this interpolates (cross-fades) the outputs at each offset.
  1236. */
  1237. static inline ALfloat FadedDelayLineOut(const DelayLineI *Delay, const ALsizei off0,
  1238. const ALsizei off1, const ALsizei c, const ALfloat mu)
  1239. {
  1240. return lerp(Delay->Line[off0&Delay->Mask][c], Delay->Line[off1&Delay->Mask][c], mu);
  1241. }
  1242. #define DELAY_OUT_Faded(d, o0, o1, c, mu) FadedDelayLineOut(d, o0, o1, c, mu)
  1243. #define DELAY_OUT_Unfaded(d, o0, o1, c, mu) DelayLineOut(d, o0, c)
  1244. static inline ALvoid DelayLineIn(DelayLineI *Delay, const ALsizei offset, const ALsizei c, const ALfloat in)
  1245. {
  1246. Delay->Line[offset&Delay->Mask][c] = in;
  1247. }
  1248. static inline ALvoid DelayLineIn4(DelayLineI *Delay, ALsizei offset, const ALfloat in[4])
  1249. {
  1250. ALsizei i;
  1251. offset &= Delay->Mask;
  1252. for(i = 0;i < 4;i++)
  1253. Delay->Line[offset][i] = in[i];
  1254. }
  1255. static inline ALvoid DelayLineIn4Rev(DelayLineI *Delay, ALsizei offset, const ALfloat in[4])
  1256. {
  1257. ALsizei i;
  1258. offset &= Delay->Mask;
  1259. for(i = 0;i < 4;i++)
  1260. Delay->Line[offset][i] = in[3-i];
  1261. }
  1262. static void CalcModulationDelays(ALreverbState *State, ALint *restrict delays, const ALsizei todo)
  1263. {
  1264. ALfloat sinus, range;
  1265. ALsizei index, i;
  1266. index = State->Mod.Index;
  1267. range = State->Mod.Filter;
  1268. for(i = 0;i < todo;i++)
  1269. {
  1270. /* Calculate the sinus rhythm (dependent on modulation time and the
  1271. * sampling rate).
  1272. */
  1273. sinus = sinf(F_TAU * index / State->Mod.Range);
  1274. /* Step the modulation index forward, keeping it bound to its range. */
  1275. index = (index+1) % State->Mod.Range;
  1276. /* The depth determines the range over which to read the input samples
  1277. * from, so it must be filtered to reduce the distortion caused by even
  1278. * small parameter changes.
  1279. */
  1280. range = lerp(range, State->Mod.Depth, State->Mod.Coeff);
  1281. /* Calculate the read offset. */
  1282. delays[i] = lroundf(range*sinus);
  1283. }
  1284. State->Mod.Index = index;
  1285. State->Mod.Filter = range;
  1286. }
  1287. /* Applies a scattering matrix to the 4-line (vector) input. This is used
  1288. * for both the below vector all-pass model and to perform modal feed-back
  1289. * delay network (FDN) mixing.
  1290. *
  1291. * The matrix is derived from a skew-symmetric matrix to form a 4D rotation
  1292. * matrix with a single unitary rotational parameter:
  1293. *
  1294. * [ d, a, b, c ] 1 = a^2 + b^2 + c^2 + d^2
  1295. * [ -a, d, c, -b ]
  1296. * [ -b, -c, d, a ]
  1297. * [ -c, b, -a, d ]
  1298. *
  1299. * The rotation is constructed from the effect's diffusion parameter,
  1300. * yielding:
  1301. *
  1302. * 1 = x^2 + 3 y^2
  1303. *
  1304. * Where a, b, and c are the coefficient y with differing signs, and d is the
  1305. * coefficient x. The final matrix is thus:
  1306. *
  1307. * [ x, y, -y, y ] n = sqrt(matrix_order - 1)
  1308. * [ -y, x, y, y ] t = diffusion_parameter * atan(n)
  1309. * [ y, -y, x, y ] x = cos(t)
  1310. * [ -y, -y, -y, x ] y = sin(t) / n
  1311. *
  1312. * Any square orthogonal matrix with an order that is a power of two will
  1313. * work (where ^T is transpose, ^-1 is inverse):
  1314. *
  1315. * M^T = M^-1
  1316. *
  1317. * Using that knowledge, finding an appropriate matrix can be accomplished
  1318. * naively by searching all combinations of:
  1319. *
  1320. * M = D + S - S^T
  1321. *
  1322. * Where D is a diagonal matrix (of x), and S is a triangular matrix (of y)
  1323. * whose combination of signs are being iterated.
  1324. */
  1325. static inline void VectorPartialScatter(ALfloat *restrict vec, const ALfloat xCoeff, const ALfloat yCoeff)
  1326. {
  1327. const ALfloat f[4] = { vec[0], vec[1], vec[2], vec[3] };
  1328. vec[0] = xCoeff*f[0] + yCoeff*( f[1] + -f[2] + f[3]);
  1329. vec[1] = xCoeff*f[1] + yCoeff*(-f[0] + f[2] + f[3]);
  1330. vec[2] = xCoeff*f[2] + yCoeff*( f[0] + -f[1] + f[3]);
  1331. vec[3] = xCoeff*f[3] + yCoeff*(-f[0] + -f[1] + -f[2] );
  1332. }
  1333. /* This applies a Gerzon multiple-in/multiple-out (MIMO) vector all-pass
  1334. * filter to the 4-line input.
  1335. *
  1336. * It works by vectorizing a regular all-pass filter and replacing the delay
  1337. * element with a scattering matrix (like the one above) and a diagonal
  1338. * matrix of delay elements.
  1339. *
  1340. * Two static specializations are used for transitional (cross-faded) delay
  1341. * line processing and non-transitional processing.
  1342. */
  1343. #define DECL_TEMPLATE(T) \
  1344. static void VectorAllpass_##T(ALfloat *restrict vec, const ALsizei offset, \
  1345. const ALfloat feedCoeff, const ALfloat xCoeff, \
  1346. const ALfloat yCoeff, const ALfloat mu, \
  1347. VecAllpass *Vap) \
  1348. { \
  1349. ALfloat input; \
  1350. ALfloat f[4]; \
  1351. ALsizei i; \
  1352. \
  1353. (void)mu; /* Ignore for Unfaded. */ \
  1354. \
  1355. for(i = 0;i < 4;i++) \
  1356. { \
  1357. input = vec[i]; \
  1358. vec[i] = DELAY_OUT_##T(&Vap->Delay, offset-Vap->Offset[i][0], \
  1359. offset-Vap->Offset[i][1], i, mu) - \
  1360. feedCoeff*input; \
  1361. f[i] = input + feedCoeff*vec[i]; \
  1362. } \
  1363. \
  1364. VectorPartialScatter(f, xCoeff, yCoeff); \
  1365. \
  1366. DelayLineIn4(&Vap->Delay, offset, f); \
  1367. }
  1368. DECL_TEMPLATE(Unfaded)
  1369. DECL_TEMPLATE(Faded)
  1370. #undef DECL_TEMPLATE
  1371. /* A helper to reverse vector components. */
  1372. static inline void VectorReverse(ALfloat vec[4])
  1373. {
  1374. const ALfloat f[4] = { vec[0], vec[1], vec[2], vec[3] };
  1375. vec[0] = f[3];
  1376. vec[1] = f[2];
  1377. vec[2] = f[1];
  1378. vec[3] = f[0];
  1379. }
  1380. /* This generates early reflections.
  1381. *
  1382. * This is done by obtaining the primary reflections (those arriving from the
  1383. * same direction as the source) from the main delay line. These are
  1384. * attenuated and all-pass filtered (based on the diffusion parameter).
  1385. *
  1386. * The early lines are then fed in reverse (according to the approximately
  1387. * opposite spatial location of the A-Format lines) to create the secondary
  1388. * reflections (those arriving from the opposite direction as the source).
  1389. *
  1390. * The early response is then completed by combining the primary reflections
  1391. * with the delayed and attenuated output from the early lines.
  1392. *
  1393. * Finally, the early response is reversed, scattered (based on diffusion),
  1394. * and fed into the late reverb section of the main delay line.
  1395. *
  1396. * Two static specializations are used for transitional (cross-faded) delay
  1397. * line processing and non-transitional processing.
  1398. */
  1399. #define DECL_TEMPLATE(T) \
  1400. static ALvoid EarlyReflection_##T(ALreverbState *State, const ALsizei todo, \
  1401. ALfloat fade, \
  1402. ALfloat (*restrict out)[MAX_UPDATE_SAMPLES])\
  1403. { \
  1404. ALsizei offset = State->Offset; \
  1405. const ALfloat apFeedCoeff = State->ApFeedCoeff; \
  1406. const ALfloat mixX = State->MixX; \
  1407. const ALfloat mixY = State->MixY; \
  1408. ALfloat f[4]; \
  1409. ALsizei i, j; \
  1410. \
  1411. for(i = 0;i < todo;i++) \
  1412. { \
  1413. for(j = 0;j < 4;j++) \
  1414. f[j] = DELAY_OUT_##T(&State->Delay, \
  1415. offset-State->EarlyDelayTap[j][0], \
  1416. offset-State->EarlyDelayTap[j][1], j, fade \
  1417. ) * State->EarlyDelayCoeff[j]; \
  1418. \
  1419. VectorAllpass_##T(f, offset, apFeedCoeff, mixX, mixY, fade, \
  1420. &State->Early.VecAp); \
  1421. \
  1422. DelayLineIn4Rev(&State->Early.Delay, offset, f); \
  1423. \
  1424. for(j = 0;j < 4;j++) \
  1425. f[j] += DELAY_OUT_##T(&State->Early.Delay, \
  1426. offset-State->Early.Offset[j][0], \
  1427. offset-State->Early.Offset[j][1], j, fade \
  1428. ) * State->Early.Coeff[j]; \
  1429. \
  1430. for(j = 0;j < 4;j++) \
  1431. out[j][i] = f[j]; \
  1432. \
  1433. VectorReverse(f); \
  1434. \
  1435. VectorPartialScatter(f, mixX, mixY); \
  1436. \
  1437. DelayLineIn4(&State->Delay, offset-State->LateFeedTap, f); \
  1438. \
  1439. offset++; \
  1440. fade += FadeStep; \
  1441. } \
  1442. }
  1443. DECL_TEMPLATE(Unfaded)
  1444. DECL_TEMPLATE(Faded)
  1445. #undef DECL_TEMPLATE
  1446. /* Applies a first order filter section. */
  1447. static inline ALfloat FirstOrderFilter(const ALfloat in, const ALfloat coeffs[3], ALfloat state[2])
  1448. {
  1449. ALfloat out = coeffs[0]*in + coeffs[1]*state[0] + coeffs[2]*state[1];
  1450. state[0] = in;
  1451. state[1] = out;
  1452. return out;
  1453. }
  1454. /* Applies the two T60 damping filter sections. */
  1455. static inline ALfloat LateT60Filter(const ALsizei index, const ALfloat in, ALreverbState *State)
  1456. {
  1457. ALfloat out = FirstOrderFilter(in, State->Late.Filters[index].LFCoeffs,
  1458. State->Late.Filters[index].States[0]);
  1459. return State->Late.Filters[index].MidCoeff *
  1460. FirstOrderFilter(out, State->Late.Filters[index].HFCoeffs,
  1461. State->Late.Filters[index].States[1]);
  1462. }
  1463. /* This generates the reverb tail using a modified feed-back delay network
  1464. * (FDN).
  1465. *
  1466. * Results from the early reflections are attenuated by the density gain and
  1467. * mixed with the output from the late delay lines.
  1468. *
  1469. * The late response is then completed by T60 and all-pass filtering the mix.
  1470. *
  1471. * Finally, the lines are reversed (so they feed their opposite directions)
  1472. * and scattered with the FDN matrix before re-feeding the delay lines.
  1473. *
  1474. * Two static specializations are used for transitional (cross-faded) delay
  1475. * line processing and non-transitional processing.
  1476. */
  1477. #define DECL_TEMPLATE(T) \
  1478. static ALvoid LateReverb_##T(ALreverbState *State, const ALsizei todo, \
  1479. ALfloat fade, \
  1480. ALfloat (*restrict out)[MAX_UPDATE_SAMPLES]) \
  1481. { \
  1482. const ALfloat apFeedCoeff = State->ApFeedCoeff; \
  1483. const ALfloat mixX = State->MixX; \
  1484. const ALfloat mixY = State->MixY; \
  1485. ALint moddelay[MAX_UPDATE_SAMPLES]; \
  1486. ALsizei delay; \
  1487. ALsizei offset; \
  1488. ALsizei i, j; \
  1489. ALfloat f[4]; \
  1490. \
  1491. CalcModulationDelays(State, moddelay, todo); \
  1492. \
  1493. offset = State->Offset; \
  1494. for(i = 0;i < todo;i++) \
  1495. { \
  1496. for(j = 0;j < 4;j++) \
  1497. f[j] = DELAY_OUT_##T(&State->Delay, \
  1498. offset-State->LateDelayTap[j][0], \
  1499. offset-State->LateDelayTap[j][1], j, fade \
  1500. ) * State->Late.DensityGain; \
  1501. \
  1502. delay = offset - moddelay[i]; \
  1503. for(j = 0;j < 4;j++) \
  1504. f[j] += DELAY_OUT_##T(&State->Late.Delay, \
  1505. delay-State->Late.Offset[j][0], \
  1506. delay-State->Late.Offset[j][1], j, fade \
  1507. ); \
  1508. \
  1509. for(j = 0;j < 4;j++) \
  1510. f[j] = LateT60Filter(j, f[j], State); \
  1511. \
  1512. VectorAllpass_##T(f, offset, apFeedCoeff, mixX, mixY, fade, \
  1513. &State->Late.VecAp); \
  1514. \
  1515. for(j = 0;j < 4;j++) \
  1516. out[j][i] = f[j]; \
  1517. \
  1518. VectorReverse(f); \
  1519. \
  1520. VectorPartialScatter(f, mixX, mixY); \
  1521. \
  1522. DelayLineIn4(&State->Late.Delay, offset, f); \
  1523. \
  1524. offset++; \
  1525. fade += FadeStep; \
  1526. } \
  1527. }
  1528. DECL_TEMPLATE(Unfaded)
  1529. DECL_TEMPLATE(Faded)
  1530. #undef DECL_TEMPLATE
  1531. typedef ALfloat (*ProcMethodType)(ALreverbState *State, const ALsizei todo, ALfloat fade,
  1532. const ALfloat (*restrict input)[MAX_UPDATE_SAMPLES],
  1533. ALfloat (*restrict early)[MAX_UPDATE_SAMPLES], ALfloat (*restrict late)[MAX_UPDATE_SAMPLES]);
  1534. /* Perform the non-EAX reverb pass on a given input sample, resulting in
  1535. * four-channel output.
  1536. */
  1537. static ALfloat VerbPass(ALreverbState *State, const ALsizei todo, ALfloat fade,
  1538. const ALfloat (*restrict input)[MAX_UPDATE_SAMPLES],
  1539. ALfloat (*restrict early)[MAX_UPDATE_SAMPLES],
  1540. ALfloat (*restrict late)[MAX_UPDATE_SAMPLES])
  1541. {
  1542. ALsizei i, c;
  1543. for(c = 0;c < 4;c++)
  1544. {
  1545. /* Low-pass filter the incoming samples (use the early buffer as temp
  1546. * storage).
  1547. */
  1548. ALfilterState_process(&State->Filter[c].Lp, &early[0][0], input[c], todo);
  1549. /* Feed the initial delay line. */
  1550. for(i = 0;i < todo;i++)
  1551. DelayLineIn(&State->Delay, State->Offset+i, c, early[0][i]);
  1552. }
  1553. if(fade < 1.0f)
  1554. {
  1555. /* Generate early reflections. */
  1556. EarlyReflection_Faded(State, todo, fade, early);
  1557. /* Generate late reverb. */
  1558. LateReverb_Faded(State, todo, fade, late);
  1559. fade = minf(1.0f, fade + todo*FadeStep);
  1560. }
  1561. else
  1562. {
  1563. /* Generate early reflections. */
  1564. EarlyReflection_Unfaded(State, todo, fade, early);
  1565. /* Generate late reverb. */
  1566. LateReverb_Unfaded(State, todo, fade, late);
  1567. }
  1568. /* Step all delays forward one sample. */
  1569. State->Offset += todo;
  1570. return fade;
  1571. }
  1572. /* Perform the EAX reverb pass on a given input sample, resulting in four-
  1573. * channel output.
  1574. */
  1575. static ALfloat EAXVerbPass(ALreverbState *State, const ALsizei todo, ALfloat fade,
  1576. const ALfloat (*restrict input)[MAX_UPDATE_SAMPLES],
  1577. ALfloat (*restrict early)[MAX_UPDATE_SAMPLES],
  1578. ALfloat (*restrict late)[MAX_UPDATE_SAMPLES])
  1579. {
  1580. ALsizei i, c;
  1581. for(c = 0;c < 4;c++)
  1582. {
  1583. /* Band-pass the incoming samples. Use the early output lines for temp
  1584. * storage.
  1585. */
  1586. ALfilterState_process(&State->Filter[c].Lp, early[0], input[c], todo);
  1587. ALfilterState_process(&State->Filter[c].Hp, early[1], early[0], todo);
  1588. /* Feed the initial delay line. */
  1589. for(i = 0;i < todo;i++)
  1590. DelayLineIn(&State->Delay, State->Offset+i, c, early[1][i]);
  1591. }
  1592. if(fade < 1.0f)
  1593. {
  1594. /* Generate early reflections. */
  1595. EarlyReflection_Faded(State, todo, fade, early);
  1596. /* Generate late reverb. */
  1597. LateReverb_Faded(State, todo, fade, late);
  1598. fade = minf(1.0f, fade + todo*FadeStep);
  1599. }
  1600. else
  1601. {
  1602. /* Generate early reflections. */
  1603. EarlyReflection_Unfaded(State, todo, fade, early);
  1604. /* Generate late reverb. */
  1605. LateReverb_Unfaded(State, todo, fade, late);
  1606. }
  1607. /* Step all delays forward. */
  1608. State->Offset += todo;
  1609. return fade;
  1610. }
  1611. static ALvoid ALreverbState_process(ALreverbState *State, ALsizei SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
  1612. {
  1613. ProcMethodType ReverbProc = State->IsEax ? EAXVerbPass : VerbPass;
  1614. ALfloat (*restrict afmt)[MAX_UPDATE_SAMPLES] = State->AFormatSamples;
  1615. ALfloat (*restrict early)[MAX_UPDATE_SAMPLES] = State->EarlySamples;
  1616. ALfloat (*restrict late)[MAX_UPDATE_SAMPLES] = State->ReverbSamples;
  1617. ALsizei fadeCount = State->FadeCount;
  1618. ALfloat fade = (ALfloat)fadeCount / FADE_SAMPLES;
  1619. ALsizei base, c;
  1620. /* Process reverb for these samples. */
  1621. for(base = 0;base < SamplesToDo;)
  1622. {
  1623. ALsizei todo = mini(SamplesToDo-base, MAX_UPDATE_SAMPLES);
  1624. /* If cross-fading, don't do more samples than there are to fade. */
  1625. if(FADE_SAMPLES-fadeCount > 0)
  1626. todo = mini(todo, FADE_SAMPLES-fadeCount);
  1627. /* Convert B-Format to A-Format for processing. */
  1628. memset(afmt, 0, sizeof(*afmt)*4);
  1629. for(c = 0;c < 4;c++)
  1630. MixRowSamples(afmt[c], B2A.m[c],
  1631. SamplesIn, MAX_EFFECT_CHANNELS, base, todo
  1632. );
  1633. /* Process the samples for reverb. */
  1634. fade = ReverbProc(State, todo, fade, afmt, early, late);
  1635. if(UNEXPECTED(fadeCount < FADE_SAMPLES) && (fadeCount += todo) >= FADE_SAMPLES)
  1636. {
  1637. /* Update the cross-fading delay line taps. */
  1638. fadeCount = FADE_SAMPLES;
  1639. fade = 1.0f;
  1640. for(c = 0;c < 4;c++)
  1641. {
  1642. State->EarlyDelayTap[c][0] = State->EarlyDelayTap[c][1];
  1643. State->Early.VecAp.Offset[c][0] = State->Early.VecAp.Offset[c][1];
  1644. State->Early.Offset[c][0] = State->Early.Offset[c][1];
  1645. State->LateDelayTap[c][0] = State->LateDelayTap[c][1];
  1646. State->Late.VecAp.Offset[c][0] = State->Late.VecAp.Offset[c][1];
  1647. State->Late.Offset[c][0] = State->Late.Offset[c][1];
  1648. }
  1649. }
  1650. /* Mix the A-Format results to output, implicitly converting back to
  1651. * B-Format.
  1652. */
  1653. for(c = 0;c < 4;c++)
  1654. MixSamples(early[c], NumChannels, SamplesOut,
  1655. State->Early.CurrentGain[c], State->Early.PanGain[c],
  1656. SamplesToDo-base, base, todo
  1657. );
  1658. for(c = 0;c < 4;c++)
  1659. MixSamples(late[c], NumChannels, SamplesOut,
  1660. State->Late.CurrentGain[c], State->Late.PanGain[c],
  1661. SamplesToDo-base, base, todo
  1662. );
  1663. base += todo;
  1664. }
  1665. State->FadeCount = fadeCount;
  1666. }
  1667. typedef struct ALreverbStateFactory {
  1668. DERIVE_FROM_TYPE(ALeffectStateFactory);
  1669. } ALreverbStateFactory;
  1670. static ALeffectState *ALreverbStateFactory_create(ALreverbStateFactory* UNUSED(factory))
  1671. {
  1672. ALreverbState *state;
  1673. alcall_once(&mixfunc_inited, init_mixfunc);
  1674. NEW_OBJ0(state, ALreverbState)();
  1675. if(!state) return NULL;
  1676. return STATIC_CAST(ALeffectState, state);
  1677. }
  1678. DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALreverbStateFactory);
  1679. ALeffectStateFactory *ALreverbStateFactory_getFactory(void)
  1680. {
  1681. static ALreverbStateFactory ReverbFactory = { { GET_VTABLE2(ALreverbStateFactory, ALeffectStateFactory) } };
  1682. return STATIC_CAST(ALeffectStateFactory, &ReverbFactory);
  1683. }
  1684. void ALeaxreverb_setParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val)
  1685. {
  1686. ALeffectProps *props = &effect->Props;
  1687. switch(param)
  1688. {
  1689. case AL_EAXREVERB_DECAY_HFLIMIT:
  1690. if(!(val >= AL_EAXREVERB_MIN_DECAY_HFLIMIT && val <= AL_EAXREVERB_MAX_DECAY_HFLIMIT))
  1691. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1692. props->Reverb.DecayHFLimit = val;
  1693. break;
  1694. default:
  1695. SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM);
  1696. }
  1697. }
  1698. void ALeaxreverb_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals)
  1699. {
  1700. ALeaxreverb_setParami(effect, context, param, vals[0]);
  1701. }
  1702. void ALeaxreverb_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val)
  1703. {
  1704. ALeffectProps *props = &effect->Props;
  1705. switch(param)
  1706. {
  1707. case AL_EAXREVERB_DENSITY:
  1708. if(!(val >= AL_EAXREVERB_MIN_DENSITY && val <= AL_EAXREVERB_MAX_DENSITY))
  1709. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1710. props->Reverb.Density = val;
  1711. break;
  1712. case AL_EAXREVERB_DIFFUSION:
  1713. if(!(val >= AL_EAXREVERB_MIN_DIFFUSION && val <= AL_EAXREVERB_MAX_DIFFUSION))
  1714. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1715. props->Reverb.Diffusion = val;
  1716. break;
  1717. case AL_EAXREVERB_GAIN:
  1718. if(!(val >= AL_EAXREVERB_MIN_GAIN && val <= AL_EAXREVERB_MAX_GAIN))
  1719. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1720. props->Reverb.Gain = val;
  1721. break;
  1722. case AL_EAXREVERB_GAINHF:
  1723. if(!(val >= AL_EAXREVERB_MIN_GAINHF && val <= AL_EAXREVERB_MAX_GAINHF))
  1724. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1725. props->Reverb.GainHF = val;
  1726. break;
  1727. case AL_EAXREVERB_GAINLF:
  1728. if(!(val >= AL_EAXREVERB_MIN_GAINLF && val <= AL_EAXREVERB_MAX_GAINLF))
  1729. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1730. props->Reverb.GainLF = val;
  1731. break;
  1732. case AL_EAXREVERB_DECAY_TIME:
  1733. if(!(val >= AL_EAXREVERB_MIN_DECAY_TIME && val <= AL_EAXREVERB_MAX_DECAY_TIME))
  1734. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1735. props->Reverb.DecayTime = val;
  1736. break;
  1737. case AL_EAXREVERB_DECAY_HFRATIO:
  1738. if(!(val >= AL_EAXREVERB_MIN_DECAY_HFRATIO && val <= AL_EAXREVERB_MAX_DECAY_HFRATIO))
  1739. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1740. props->Reverb.DecayHFRatio = val;
  1741. break;
  1742. case AL_EAXREVERB_DECAY_LFRATIO:
  1743. if(!(val >= AL_EAXREVERB_MIN_DECAY_LFRATIO && val <= AL_EAXREVERB_MAX_DECAY_LFRATIO))
  1744. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1745. props->Reverb.DecayLFRatio = val;
  1746. break;
  1747. case AL_EAXREVERB_REFLECTIONS_GAIN:
  1748. if(!(val >= AL_EAXREVERB_MIN_REFLECTIONS_GAIN && val <= AL_EAXREVERB_MAX_REFLECTIONS_GAIN))
  1749. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1750. props->Reverb.ReflectionsGain = val;
  1751. break;
  1752. case AL_EAXREVERB_REFLECTIONS_DELAY:
  1753. if(!(val >= AL_EAXREVERB_MIN_REFLECTIONS_DELAY && val <= AL_EAXREVERB_MAX_REFLECTIONS_DELAY))
  1754. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1755. props->Reverb.ReflectionsDelay = val;
  1756. break;
  1757. case AL_EAXREVERB_LATE_REVERB_GAIN:
  1758. if(!(val >= AL_EAXREVERB_MIN_LATE_REVERB_GAIN && val <= AL_EAXREVERB_MAX_LATE_REVERB_GAIN))
  1759. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1760. props->Reverb.LateReverbGain = val;
  1761. break;
  1762. case AL_EAXREVERB_LATE_REVERB_DELAY:
  1763. if(!(val >= AL_EAXREVERB_MIN_LATE_REVERB_DELAY && val <= AL_EAXREVERB_MAX_LATE_REVERB_DELAY))
  1764. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1765. props->Reverb.LateReverbDelay = val;
  1766. break;
  1767. case AL_EAXREVERB_AIR_ABSORPTION_GAINHF:
  1768. if(!(val >= AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF && val <= AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF))
  1769. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1770. props->Reverb.AirAbsorptionGainHF = val;
  1771. break;
  1772. case AL_EAXREVERB_ECHO_TIME:
  1773. if(!(val >= AL_EAXREVERB_MIN_ECHO_TIME && val <= AL_EAXREVERB_MAX_ECHO_TIME))
  1774. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1775. props->Reverb.EchoTime = val;
  1776. break;
  1777. case AL_EAXREVERB_ECHO_DEPTH:
  1778. if(!(val >= AL_EAXREVERB_MIN_ECHO_DEPTH && val <= AL_EAXREVERB_MAX_ECHO_DEPTH))
  1779. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1780. props->Reverb.EchoDepth = val;
  1781. break;
  1782. case AL_EAXREVERB_MODULATION_TIME:
  1783. if(!(val >= AL_EAXREVERB_MIN_MODULATION_TIME && val <= AL_EAXREVERB_MAX_MODULATION_TIME))
  1784. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1785. props->Reverb.ModulationTime = val;
  1786. break;
  1787. case AL_EAXREVERB_MODULATION_DEPTH:
  1788. if(!(val >= AL_EAXREVERB_MIN_MODULATION_DEPTH && val <= AL_EAXREVERB_MAX_MODULATION_DEPTH))
  1789. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1790. props->Reverb.ModulationDepth = val;
  1791. break;
  1792. case AL_EAXREVERB_HFREFERENCE:
  1793. if(!(val >= AL_EAXREVERB_MIN_HFREFERENCE && val <= AL_EAXREVERB_MAX_HFREFERENCE))
  1794. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1795. props->Reverb.HFReference = val;
  1796. break;
  1797. case AL_EAXREVERB_LFREFERENCE:
  1798. if(!(val >= AL_EAXREVERB_MIN_LFREFERENCE && val <= AL_EAXREVERB_MAX_LFREFERENCE))
  1799. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1800. props->Reverb.LFReference = val;
  1801. break;
  1802. case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR:
  1803. if(!(val >= AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR && val <= AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR))
  1804. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1805. props->Reverb.RoomRolloffFactor = val;
  1806. break;
  1807. default:
  1808. SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM);
  1809. }
  1810. }
  1811. void ALeaxreverb_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals)
  1812. {
  1813. ALeffectProps *props = &effect->Props;
  1814. switch(param)
  1815. {
  1816. case AL_EAXREVERB_REFLECTIONS_PAN:
  1817. if(!(isfinite(vals[0]) && isfinite(vals[1]) && isfinite(vals[2])))
  1818. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1819. props->Reverb.ReflectionsPan[0] = vals[0];
  1820. props->Reverb.ReflectionsPan[1] = vals[1];
  1821. props->Reverb.ReflectionsPan[2] = vals[2];
  1822. break;
  1823. case AL_EAXREVERB_LATE_REVERB_PAN:
  1824. if(!(isfinite(vals[0]) && isfinite(vals[1]) && isfinite(vals[2])))
  1825. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1826. props->Reverb.LateReverbPan[0] = vals[0];
  1827. props->Reverb.LateReverbPan[1] = vals[1];
  1828. props->Reverb.LateReverbPan[2] = vals[2];
  1829. break;
  1830. default:
  1831. ALeaxreverb_setParamf(effect, context, param, vals[0]);
  1832. break;
  1833. }
  1834. }
  1835. void ALeaxreverb_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *val)
  1836. {
  1837. const ALeffectProps *props = &effect->Props;
  1838. switch(param)
  1839. {
  1840. case AL_EAXREVERB_DECAY_HFLIMIT:
  1841. *val = props->Reverb.DecayHFLimit;
  1842. break;
  1843. default:
  1844. SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM);
  1845. }
  1846. }
  1847. void ALeaxreverb_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals)
  1848. {
  1849. ALeaxreverb_getParami(effect, context, param, vals);
  1850. }
  1851. void ALeaxreverb_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val)
  1852. {
  1853. const ALeffectProps *props = &effect->Props;
  1854. switch(param)
  1855. {
  1856. case AL_EAXREVERB_DENSITY:
  1857. *val = props->Reverb.Density;
  1858. break;
  1859. case AL_EAXREVERB_DIFFUSION:
  1860. *val = props->Reverb.Diffusion;
  1861. break;
  1862. case AL_EAXREVERB_GAIN:
  1863. *val = props->Reverb.Gain;
  1864. break;
  1865. case AL_EAXREVERB_GAINHF:
  1866. *val = props->Reverb.GainHF;
  1867. break;
  1868. case AL_EAXREVERB_GAINLF:
  1869. *val = props->Reverb.GainLF;
  1870. break;
  1871. case AL_EAXREVERB_DECAY_TIME:
  1872. *val = props->Reverb.DecayTime;
  1873. break;
  1874. case AL_EAXREVERB_DECAY_HFRATIO:
  1875. *val = props->Reverb.DecayHFRatio;
  1876. break;
  1877. case AL_EAXREVERB_DECAY_LFRATIO:
  1878. *val = props->Reverb.DecayLFRatio;
  1879. break;
  1880. case AL_EAXREVERB_REFLECTIONS_GAIN:
  1881. *val = props->Reverb.ReflectionsGain;
  1882. break;
  1883. case AL_EAXREVERB_REFLECTIONS_DELAY:
  1884. *val = props->Reverb.ReflectionsDelay;
  1885. break;
  1886. case AL_EAXREVERB_LATE_REVERB_GAIN:
  1887. *val = props->Reverb.LateReverbGain;
  1888. break;
  1889. case AL_EAXREVERB_LATE_REVERB_DELAY:
  1890. *val = props->Reverb.LateReverbDelay;
  1891. break;
  1892. case AL_EAXREVERB_AIR_ABSORPTION_GAINHF:
  1893. *val = props->Reverb.AirAbsorptionGainHF;
  1894. break;
  1895. case AL_EAXREVERB_ECHO_TIME:
  1896. *val = props->Reverb.EchoTime;
  1897. break;
  1898. case AL_EAXREVERB_ECHO_DEPTH:
  1899. *val = props->Reverb.EchoDepth;
  1900. break;
  1901. case AL_EAXREVERB_MODULATION_TIME:
  1902. *val = props->Reverb.ModulationTime;
  1903. break;
  1904. case AL_EAXREVERB_MODULATION_DEPTH:
  1905. *val = props->Reverb.ModulationDepth;
  1906. break;
  1907. case AL_EAXREVERB_HFREFERENCE:
  1908. *val = props->Reverb.HFReference;
  1909. break;
  1910. case AL_EAXREVERB_LFREFERENCE:
  1911. *val = props->Reverb.LFReference;
  1912. break;
  1913. case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR:
  1914. *val = props->Reverb.RoomRolloffFactor;
  1915. break;
  1916. default:
  1917. SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM);
  1918. }
  1919. }
  1920. void ALeaxreverb_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals)
  1921. {
  1922. const ALeffectProps *props = &effect->Props;
  1923. switch(param)
  1924. {
  1925. case AL_EAXREVERB_REFLECTIONS_PAN:
  1926. vals[0] = props->Reverb.ReflectionsPan[0];
  1927. vals[1] = props->Reverb.ReflectionsPan[1];
  1928. vals[2] = props->Reverb.ReflectionsPan[2];
  1929. break;
  1930. case AL_EAXREVERB_LATE_REVERB_PAN:
  1931. vals[0] = props->Reverb.LateReverbPan[0];
  1932. vals[1] = props->Reverb.LateReverbPan[1];
  1933. vals[2] = props->Reverb.LateReverbPan[2];
  1934. break;
  1935. default:
  1936. ALeaxreverb_getParamf(effect, context, param, vals);
  1937. break;
  1938. }
  1939. }
  1940. DEFINE_ALEFFECT_VTABLE(ALeaxreverb);
  1941. void ALreverb_setParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val)
  1942. {
  1943. ALeffectProps *props = &effect->Props;
  1944. switch(param)
  1945. {
  1946. case AL_REVERB_DECAY_HFLIMIT:
  1947. if(!(val >= AL_REVERB_MIN_DECAY_HFLIMIT && val <= AL_REVERB_MAX_DECAY_HFLIMIT))
  1948. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1949. props->Reverb.DecayHFLimit = val;
  1950. break;
  1951. default:
  1952. SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM);
  1953. }
  1954. }
  1955. void ALreverb_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals)
  1956. {
  1957. ALreverb_setParami(effect, context, param, vals[0]);
  1958. }
  1959. void ALreverb_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val)
  1960. {
  1961. ALeffectProps *props = &effect->Props;
  1962. switch(param)
  1963. {
  1964. case AL_REVERB_DENSITY:
  1965. if(!(val >= AL_REVERB_MIN_DENSITY && val <= AL_REVERB_MAX_DENSITY))
  1966. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1967. props->Reverb.Density = val;
  1968. break;
  1969. case AL_REVERB_DIFFUSION:
  1970. if(!(val >= AL_REVERB_MIN_DIFFUSION && val <= AL_REVERB_MAX_DIFFUSION))
  1971. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1972. props->Reverb.Diffusion = val;
  1973. break;
  1974. case AL_REVERB_GAIN:
  1975. if(!(val >= AL_REVERB_MIN_GAIN && val <= AL_REVERB_MAX_GAIN))
  1976. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1977. props->Reverb.Gain = val;
  1978. break;
  1979. case AL_REVERB_GAINHF:
  1980. if(!(val >= AL_REVERB_MIN_GAINHF && val <= AL_REVERB_MAX_GAINHF))
  1981. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1982. props->Reverb.GainHF = val;
  1983. break;
  1984. case AL_REVERB_DECAY_TIME:
  1985. if(!(val >= AL_REVERB_MIN_DECAY_TIME && val <= AL_REVERB_MAX_DECAY_TIME))
  1986. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1987. props->Reverb.DecayTime = val;
  1988. break;
  1989. case AL_REVERB_DECAY_HFRATIO:
  1990. if(!(val >= AL_REVERB_MIN_DECAY_HFRATIO && val <= AL_REVERB_MAX_DECAY_HFRATIO))
  1991. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1992. props->Reverb.DecayHFRatio = val;
  1993. break;
  1994. case AL_REVERB_REFLECTIONS_GAIN:
  1995. if(!(val >= AL_REVERB_MIN_REFLECTIONS_GAIN && val <= AL_REVERB_MAX_REFLECTIONS_GAIN))
  1996. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  1997. props->Reverb.ReflectionsGain = val;
  1998. break;
  1999. case AL_REVERB_REFLECTIONS_DELAY:
  2000. if(!(val >= AL_REVERB_MIN_REFLECTIONS_DELAY && val <= AL_REVERB_MAX_REFLECTIONS_DELAY))
  2001. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  2002. props->Reverb.ReflectionsDelay = val;
  2003. break;
  2004. case AL_REVERB_LATE_REVERB_GAIN:
  2005. if(!(val >= AL_REVERB_MIN_LATE_REVERB_GAIN && val <= AL_REVERB_MAX_LATE_REVERB_GAIN))
  2006. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  2007. props->Reverb.LateReverbGain = val;
  2008. break;
  2009. case AL_REVERB_LATE_REVERB_DELAY:
  2010. if(!(val >= AL_REVERB_MIN_LATE_REVERB_DELAY && val <= AL_REVERB_MAX_LATE_REVERB_DELAY))
  2011. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  2012. props->Reverb.LateReverbDelay = val;
  2013. break;
  2014. case AL_REVERB_AIR_ABSORPTION_GAINHF:
  2015. if(!(val >= AL_REVERB_MIN_AIR_ABSORPTION_GAINHF && val <= AL_REVERB_MAX_AIR_ABSORPTION_GAINHF))
  2016. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  2017. props->Reverb.AirAbsorptionGainHF = val;
  2018. break;
  2019. case AL_REVERB_ROOM_ROLLOFF_FACTOR:
  2020. if(!(val >= AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR && val <= AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR))
  2021. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  2022. props->Reverb.RoomRolloffFactor = val;
  2023. break;
  2024. default:
  2025. SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM);
  2026. }
  2027. }
  2028. void ALreverb_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals)
  2029. {
  2030. ALreverb_setParamf(effect, context, param, vals[0]);
  2031. }
  2032. void ALreverb_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *val)
  2033. {
  2034. const ALeffectProps *props = &effect->Props;
  2035. switch(param)
  2036. {
  2037. case AL_REVERB_DECAY_HFLIMIT:
  2038. *val = props->Reverb.DecayHFLimit;
  2039. break;
  2040. default:
  2041. SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM);
  2042. }
  2043. }
  2044. void ALreverb_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals)
  2045. {
  2046. ALreverb_getParami(effect, context, param, vals);
  2047. }
  2048. void ALreverb_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val)
  2049. {
  2050. const ALeffectProps *props = &effect->Props;
  2051. switch(param)
  2052. {
  2053. case AL_REVERB_DENSITY:
  2054. *val = props->Reverb.Density;
  2055. break;
  2056. case AL_REVERB_DIFFUSION:
  2057. *val = props->Reverb.Diffusion;
  2058. break;
  2059. case AL_REVERB_GAIN:
  2060. *val = props->Reverb.Gain;
  2061. break;
  2062. case AL_REVERB_GAINHF:
  2063. *val = props->Reverb.GainHF;
  2064. break;
  2065. case AL_REVERB_DECAY_TIME:
  2066. *val = props->Reverb.DecayTime;
  2067. break;
  2068. case AL_REVERB_DECAY_HFRATIO:
  2069. *val = props->Reverb.DecayHFRatio;
  2070. break;
  2071. case AL_REVERB_REFLECTIONS_GAIN:
  2072. *val = props->Reverb.ReflectionsGain;
  2073. break;
  2074. case AL_REVERB_REFLECTIONS_DELAY:
  2075. *val = props->Reverb.ReflectionsDelay;
  2076. break;
  2077. case AL_REVERB_LATE_REVERB_GAIN:
  2078. *val = props->Reverb.LateReverbGain;
  2079. break;
  2080. case AL_REVERB_LATE_REVERB_DELAY:
  2081. *val = props->Reverb.LateReverbDelay;
  2082. break;
  2083. case AL_REVERB_AIR_ABSORPTION_GAINHF:
  2084. *val = props->Reverb.AirAbsorptionGainHF;
  2085. break;
  2086. case AL_REVERB_ROOM_ROLLOFF_FACTOR:
  2087. *val = props->Reverb.RoomRolloffFactor;
  2088. break;
  2089. default:
  2090. SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM);
  2091. }
  2092. }
  2093. void ALreverb_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals)
  2094. {
  2095. ALreverb_getParamf(effect, context, param, vals);
  2096. }
  2097. DEFINE_ALEFFECT_VTABLE(ALreverb);