ALu.c 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656
  1. /**
  2. * OpenAL cross platform audio library
  3. * Copyright (C) 1999-2007 by authors.
  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., 59 Temple Place - Suite 330,
  17. * Boston, MA 02111-1307, USA.
  18. * Or go to http://www.gnu.org/copyleft/lgpl.html
  19. */
  20. #include "config.h"
  21. #include <math.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <ctype.h>
  25. #include <assert.h>
  26. #include "alMain.h"
  27. #include "AL/al.h"
  28. #include "AL/alc.h"
  29. #include "alSource.h"
  30. #include "alBuffer.h"
  31. #include "alThunk.h"
  32. #include "alListener.h"
  33. #include "alAuxEffectSlot.h"
  34. #include "alu.h"
  35. #include "bs2b.h"
  36. #define FRACTIONBITS 14
  37. #define FRACTIONMASK ((1L<<FRACTIONBITS)-1)
  38. #define MAX_PITCH 65536
  39. /* Minimum ramp length in milliseconds. The value below was chosen to
  40. * adequately reduce clicks and pops from harsh gain changes. */
  41. #define MIN_RAMP_LENGTH 16
  42. static __inline ALfloat aluF2F(ALfloat Value)
  43. {
  44. return Value;
  45. }
  46. static __inline ALshort aluF2S(ALfloat Value)
  47. {
  48. ALint i;
  49. if(Value < 0.0f)
  50. {
  51. i = (ALint)(Value*32768.0f);
  52. i = max(-32768, i);
  53. }
  54. else
  55. {
  56. i = (ALint)(Value*32767.0f);
  57. i = min( 32767, i);
  58. }
  59. return ((ALshort)i);
  60. }
  61. static __inline ALubyte aluF2UB(ALfloat Value)
  62. {
  63. ALshort i = aluF2S(Value);
  64. return (i>>8)+128;
  65. }
  66. static __inline ALvoid aluCrossproduct(const ALfloat *inVector1, const ALfloat *inVector2, ALfloat *outVector)
  67. {
  68. outVector[0] = inVector1[1]*inVector2[2] - inVector1[2]*inVector2[1];
  69. outVector[1] = inVector1[2]*inVector2[0] - inVector1[0]*inVector2[2];
  70. outVector[2] = inVector1[0]*inVector2[1] - inVector1[1]*inVector2[0];
  71. }
  72. static __inline ALfloat aluDotproduct(const ALfloat *inVector1, const ALfloat *inVector2)
  73. {
  74. return inVector1[0]*inVector2[0] + inVector1[1]*inVector2[1] +
  75. inVector1[2]*inVector2[2];
  76. }
  77. static __inline ALvoid aluNormalize(ALfloat *inVector)
  78. {
  79. ALfloat length, inverse_length;
  80. length = aluSqrt(aluDotproduct(inVector, inVector));
  81. if(length != 0.0f)
  82. {
  83. inverse_length = 1.0f/length;
  84. inVector[0] *= inverse_length;
  85. inVector[1] *= inverse_length;
  86. inVector[2] *= inverse_length;
  87. }
  88. }
  89. static __inline ALvoid aluMatrixVector(ALfloat *vector,ALfloat w,ALfloat matrix[4][4])
  90. {
  91. ALfloat temp[4] = {
  92. vector[0], vector[1], vector[2], w
  93. };
  94. vector[0] = temp[0]*matrix[0][0] + temp[1]*matrix[1][0] + temp[2]*matrix[2][0] + temp[3]*matrix[3][0];
  95. vector[1] = temp[0]*matrix[0][1] + temp[1]*matrix[1][1] + temp[2]*matrix[2][1] + temp[3]*matrix[3][1];
  96. vector[2] = temp[0]*matrix[0][2] + temp[1]*matrix[1][2] + temp[2]*matrix[2][2] + temp[3]*matrix[3][2];
  97. }
  98. static ALvoid SetSpeakerArrangement(const char *name, ALfloat SpeakerAngle[OUTPUTCHANNELS],
  99. Channel Speaker2Chan[OUTPUTCHANNELS], ALint chans)
  100. {
  101. char layout_str[256];
  102. char *confkey, *next;
  103. char *sep, *end;
  104. Channel val;
  105. int i;
  106. strncpy(layout_str, GetConfigValue(NULL, name, ""), sizeof(layout_str));
  107. layout_str[255] = 0;
  108. if(!layout_str[0])
  109. return;
  110. next = confkey = layout_str;
  111. while(next && *next)
  112. {
  113. confkey = next;
  114. next = strchr(confkey, ',');
  115. if(next)
  116. {
  117. *next = 0;
  118. do {
  119. next++;
  120. } while(isspace(*next) || *next == ',');
  121. }
  122. sep = strchr(confkey, '=');
  123. if(!sep || confkey == sep)
  124. continue;
  125. end = sep - 1;
  126. while(isspace(*end) && end != confkey)
  127. end--;
  128. *(++end) = 0;
  129. if(strcmp(confkey, "fl") == 0 || strcmp(confkey, "front-left") == 0)
  130. val = FRONT_LEFT;
  131. else if(strcmp(confkey, "fr") == 0 || strcmp(confkey, "front-right") == 0)
  132. val = FRONT_RIGHT;
  133. else if(strcmp(confkey, "fc") == 0 || strcmp(confkey, "front-center") == 0)
  134. val = FRONT_CENTER;
  135. else if(strcmp(confkey, "bl") == 0 || strcmp(confkey, "back-left") == 0)
  136. val = BACK_LEFT;
  137. else if(strcmp(confkey, "br") == 0 || strcmp(confkey, "back-right") == 0)
  138. val = BACK_RIGHT;
  139. else if(strcmp(confkey, "bc") == 0 || strcmp(confkey, "back-center") == 0)
  140. val = BACK_CENTER;
  141. else if(strcmp(confkey, "sl") == 0 || strcmp(confkey, "side-left") == 0)
  142. val = SIDE_LEFT;
  143. else if(strcmp(confkey, "sr") == 0 || strcmp(confkey, "side-right") == 0)
  144. val = SIDE_RIGHT;
  145. else
  146. {
  147. AL_PRINT("Unknown speaker for %s: \"%s\"\n", name, confkey);
  148. continue;
  149. }
  150. *(sep++) = 0;
  151. while(isspace(*sep))
  152. sep++;
  153. for(i = 0;i < chans;i++)
  154. {
  155. if(Speaker2Chan[i] == val)
  156. {
  157. long angle = strtol(sep, NULL, 10);
  158. if(angle >= -180 && angle <= 180)
  159. SpeakerAngle[i] = angle * M_PI/180.0f;
  160. else
  161. AL_PRINT("Invalid angle for speaker \"%s\": %ld\n", confkey, angle);
  162. break;
  163. }
  164. }
  165. }
  166. for(i = 0;i < chans;i++)
  167. {
  168. int min = i;
  169. int i2;
  170. for(i2 = i+1;i2 < chans;i2++)
  171. {
  172. if(SpeakerAngle[i2] < SpeakerAngle[min])
  173. min = i2;
  174. }
  175. if(min != i)
  176. {
  177. ALfloat tmpf;
  178. Channel tmpc;
  179. tmpf = SpeakerAngle[i];
  180. SpeakerAngle[i] = SpeakerAngle[min];
  181. SpeakerAngle[min] = tmpf;
  182. tmpc = Speaker2Chan[i];
  183. Speaker2Chan[i] = Speaker2Chan[min];
  184. Speaker2Chan[min] = tmpc;
  185. }
  186. }
  187. }
  188. static __inline ALfloat aluLUTpos2Angle(ALint pos)
  189. {
  190. if(pos < QUADRANT_NUM)
  191. return aluAtan((ALfloat)pos / (ALfloat)(QUADRANT_NUM - pos));
  192. if(pos < 2 * QUADRANT_NUM)
  193. return M_PI_2 + aluAtan((ALfloat)(pos - QUADRANT_NUM) / (ALfloat)(2 * QUADRANT_NUM - pos));
  194. if(pos < 3 * QUADRANT_NUM)
  195. return aluAtan((ALfloat)(pos - 2 * QUADRANT_NUM) / (ALfloat)(3 * QUADRANT_NUM - pos)) - M_PI;
  196. return aluAtan((ALfloat)(pos - 3 * QUADRANT_NUM) / (ALfloat)(4 * QUADRANT_NUM - pos)) - M_PI_2;
  197. }
  198. ALvoid aluInitPanning(ALCdevice *Device)
  199. {
  200. ALfloat SpeakerAngle[OUTPUTCHANNELS];
  201. Channel *Speaker2Chan;
  202. ALfloat Alpha, Theta;
  203. ALint pos, offset;
  204. ALuint s, s2;
  205. for(s = 0;s < OUTPUTCHANNELS;s++)
  206. {
  207. for(s2 = 0;s2 < OUTPUTCHANNELS;s2++)
  208. Device->ChannelMatrix[s][s2] = ((s==s2) ? 1.0f : 0.0f);
  209. }
  210. Speaker2Chan = Device->Speaker2Chan;
  211. switch(Device->Format)
  212. {
  213. case AL_FORMAT_MONO8:
  214. case AL_FORMAT_MONO16:
  215. case AL_FORMAT_MONO_FLOAT32:
  216. Device->DuplicateStereo = AL_FALSE;
  217. Device->ChannelMatrix[FRONT_LEFT][FRONT_CENTER] = aluSqrt(0.5);
  218. Device->ChannelMatrix[FRONT_RIGHT][FRONT_CENTER] = aluSqrt(0.5);
  219. Device->ChannelMatrix[SIDE_LEFT][FRONT_CENTER] = aluSqrt(0.5);
  220. Device->ChannelMatrix[SIDE_RIGHT][FRONT_CENTER] = aluSqrt(0.5);
  221. Device->ChannelMatrix[BACK_LEFT][FRONT_CENTER] = aluSqrt(0.5);
  222. Device->ChannelMatrix[BACK_RIGHT][FRONT_CENTER] = aluSqrt(0.5);
  223. Device->ChannelMatrix[BACK_CENTER][FRONT_CENTER] = 1.0f;
  224. Device->NumChan = 1;
  225. Speaker2Chan[0] = FRONT_CENTER;
  226. SpeakerAngle[0] = 0.0f * M_PI/180.0f;
  227. break;
  228. case AL_FORMAT_STEREO8:
  229. case AL_FORMAT_STEREO16:
  230. case AL_FORMAT_STEREO_FLOAT32:
  231. Device->DuplicateStereo = AL_FALSE;
  232. Device->ChannelMatrix[FRONT_CENTER][FRONT_LEFT] = aluSqrt(0.5);
  233. Device->ChannelMatrix[FRONT_CENTER][FRONT_RIGHT] = aluSqrt(0.5);
  234. Device->ChannelMatrix[SIDE_LEFT][FRONT_LEFT] = 1.0f;
  235. Device->ChannelMatrix[SIDE_RIGHT][FRONT_RIGHT] = 1.0f;
  236. Device->ChannelMatrix[BACK_LEFT][FRONT_LEFT] = 1.0f;
  237. Device->ChannelMatrix[BACK_RIGHT][FRONT_RIGHT] = 1.0f;
  238. Device->ChannelMatrix[BACK_CENTER][FRONT_LEFT] = aluSqrt(0.5);
  239. Device->ChannelMatrix[BACK_CENTER][FRONT_RIGHT] = aluSqrt(0.5);
  240. Device->NumChan = 2;
  241. Speaker2Chan[0] = FRONT_LEFT;
  242. Speaker2Chan[1] = FRONT_RIGHT;
  243. SpeakerAngle[0] = -90.0f * M_PI/180.0f;
  244. SpeakerAngle[1] = 90.0f * M_PI/180.0f;
  245. SetSpeakerArrangement("layout", SpeakerAngle, Speaker2Chan, Device->NumChan);
  246. break;
  247. case AL_FORMAT_QUAD8:
  248. case AL_FORMAT_QUAD16:
  249. case AL_FORMAT_QUAD32:
  250. Device->DuplicateStereo = GetConfigValueBool(NULL, "stereodup", 0);
  251. Device->ChannelMatrix[FRONT_CENTER][FRONT_LEFT] = aluSqrt(0.5);
  252. Device->ChannelMatrix[FRONT_CENTER][FRONT_RIGHT] = aluSqrt(0.5);
  253. Device->ChannelMatrix[SIDE_LEFT][FRONT_LEFT] = aluSqrt(0.5);
  254. Device->ChannelMatrix[SIDE_LEFT][BACK_LEFT] = aluSqrt(0.5);
  255. Device->ChannelMatrix[SIDE_RIGHT][FRONT_RIGHT] = aluSqrt(0.5);
  256. Device->ChannelMatrix[SIDE_RIGHT][BACK_RIGHT] = aluSqrt(0.5);
  257. Device->ChannelMatrix[BACK_CENTER][BACK_LEFT] = aluSqrt(0.5);
  258. Device->ChannelMatrix[BACK_CENTER][BACK_RIGHT] = aluSqrt(0.5);
  259. Device->NumChan = 4;
  260. Speaker2Chan[0] = BACK_LEFT;
  261. Speaker2Chan[1] = FRONT_LEFT;
  262. Speaker2Chan[2] = FRONT_RIGHT;
  263. Speaker2Chan[3] = BACK_RIGHT;
  264. SpeakerAngle[0] = -135.0f * M_PI/180.0f;
  265. SpeakerAngle[1] = -45.0f * M_PI/180.0f;
  266. SpeakerAngle[2] = 45.0f * M_PI/180.0f;
  267. SpeakerAngle[3] = 135.0f * M_PI/180.0f;
  268. SetSpeakerArrangement("layout", SpeakerAngle, Speaker2Chan, Device->NumChan);
  269. break;
  270. case AL_FORMAT_51CHN8:
  271. case AL_FORMAT_51CHN16:
  272. case AL_FORMAT_51CHN32:
  273. Device->DuplicateStereo = GetConfigValueBool(NULL, "stereodup", 0);
  274. Device->ChannelMatrix[SIDE_LEFT][FRONT_LEFT] = aluSqrt(0.5);
  275. Device->ChannelMatrix[SIDE_LEFT][BACK_LEFT] = aluSqrt(0.5);
  276. Device->ChannelMatrix[SIDE_RIGHT][FRONT_RIGHT] = aluSqrt(0.5);
  277. Device->ChannelMatrix[SIDE_RIGHT][BACK_RIGHT] = aluSqrt(0.5);
  278. Device->ChannelMatrix[BACK_CENTER][BACK_LEFT] = aluSqrt(0.5);
  279. Device->ChannelMatrix[BACK_CENTER][BACK_RIGHT] = aluSqrt(0.5);
  280. Device->NumChan = 5;
  281. Speaker2Chan[0] = BACK_LEFT;
  282. Speaker2Chan[1] = FRONT_LEFT;
  283. Speaker2Chan[2] = FRONT_CENTER;
  284. Speaker2Chan[3] = FRONT_RIGHT;
  285. Speaker2Chan[4] = BACK_RIGHT;
  286. SpeakerAngle[0] = -110.0f * M_PI/180.0f;
  287. SpeakerAngle[1] = -30.0f * M_PI/180.0f;
  288. SpeakerAngle[2] = 0.0f * M_PI/180.0f;
  289. SpeakerAngle[3] = 30.0f * M_PI/180.0f;
  290. SpeakerAngle[4] = 110.0f * M_PI/180.0f;
  291. SetSpeakerArrangement("layout", SpeakerAngle, Speaker2Chan, Device->NumChan);
  292. break;
  293. case AL_FORMAT_61CHN8:
  294. case AL_FORMAT_61CHN16:
  295. case AL_FORMAT_61CHN32:
  296. Device->DuplicateStereo = GetConfigValueBool(NULL, "stereodup", 0);
  297. Device->ChannelMatrix[BACK_LEFT][BACK_CENTER] = aluSqrt(0.5);
  298. Device->ChannelMatrix[BACK_LEFT][SIDE_LEFT] = aluSqrt(0.5);
  299. Device->ChannelMatrix[BACK_RIGHT][BACK_CENTER] = aluSqrt(0.5);
  300. Device->ChannelMatrix[BACK_RIGHT][SIDE_RIGHT] = aluSqrt(0.5);
  301. Device->NumChan = 6;
  302. Speaker2Chan[0] = SIDE_LEFT;
  303. Speaker2Chan[1] = FRONT_LEFT;
  304. Speaker2Chan[2] = FRONT_CENTER;
  305. Speaker2Chan[3] = FRONT_RIGHT;
  306. Speaker2Chan[4] = SIDE_RIGHT;
  307. Speaker2Chan[5] = BACK_CENTER;
  308. SpeakerAngle[0] = -90.0f * M_PI/180.0f;
  309. SpeakerAngle[1] = -30.0f * M_PI/180.0f;
  310. SpeakerAngle[2] = 0.0f * M_PI/180.0f;
  311. SpeakerAngle[3] = 30.0f * M_PI/180.0f;
  312. SpeakerAngle[4] = 90.0f * M_PI/180.0f;
  313. SpeakerAngle[5] = 180.0f * M_PI/180.0f;
  314. SetSpeakerArrangement("layout", SpeakerAngle, Speaker2Chan, Device->NumChan);
  315. break;
  316. case AL_FORMAT_71CHN8:
  317. case AL_FORMAT_71CHN16:
  318. case AL_FORMAT_71CHN32:
  319. Device->DuplicateStereo = GetConfigValueBool(NULL, "stereodup", 0);
  320. Device->ChannelMatrix[BACK_CENTER][BACK_LEFT] = aluSqrt(0.5);
  321. Device->ChannelMatrix[BACK_CENTER][BACK_RIGHT] = aluSqrt(0.5);
  322. Device->NumChan = 7;
  323. Speaker2Chan[0] = BACK_LEFT;
  324. Speaker2Chan[1] = SIDE_LEFT;
  325. Speaker2Chan[2] = FRONT_LEFT;
  326. Speaker2Chan[3] = FRONT_CENTER;
  327. Speaker2Chan[4] = FRONT_RIGHT;
  328. Speaker2Chan[5] = SIDE_RIGHT;
  329. Speaker2Chan[6] = BACK_RIGHT;
  330. SpeakerAngle[0] = -150.0f * M_PI/180.0f;
  331. SpeakerAngle[1] = -90.0f * M_PI/180.0f;
  332. SpeakerAngle[2] = -30.0f * M_PI/180.0f;
  333. SpeakerAngle[3] = 0.0f * M_PI/180.0f;
  334. SpeakerAngle[4] = 30.0f * M_PI/180.0f;
  335. SpeakerAngle[5] = 90.0f * M_PI/180.0f;
  336. SpeakerAngle[6] = 150.0f * M_PI/180.0f;
  337. SetSpeakerArrangement("layout", SpeakerAngle, Speaker2Chan, Device->NumChan);
  338. break;
  339. default:
  340. assert(0);
  341. }
  342. if(GetConfigValueBool(NULL, "scalemix", 0))
  343. {
  344. ALfloat maxout = 1.0f;
  345. for(s = 0;s < OUTPUTCHANNELS;s++)
  346. {
  347. ALfloat out = 0.0f;
  348. for(s2 = 0;s2 < OUTPUTCHANNELS;s2++)
  349. out += Device->ChannelMatrix[s2][s];
  350. maxout = __max(maxout, out);
  351. }
  352. maxout = 1.0f/maxout;
  353. for(s = 0;s < OUTPUTCHANNELS;s++)
  354. {
  355. for(s2 = 0;s2 < OUTPUTCHANNELS;s2++)
  356. Device->ChannelMatrix[s2][s] *= maxout;
  357. }
  358. }
  359. for(pos = 0; pos < LUT_NUM; pos++)
  360. {
  361. /* clear all values */
  362. offset = OUTPUTCHANNELS * pos;
  363. for(s = 0; s < OUTPUTCHANNELS; s++)
  364. Device->PanningLUT[offset+s] = 0.0f;
  365. if(Device->NumChan == 1)
  366. {
  367. Device->PanningLUT[offset + Speaker2Chan[0]] = 1.0f;
  368. continue;
  369. }
  370. /* source angle */
  371. Theta = aluLUTpos2Angle(pos);
  372. /* set panning values */
  373. for(s = 0; s < Device->NumChan - 1; s++)
  374. {
  375. if(Theta >= SpeakerAngle[s] && Theta < SpeakerAngle[s+1])
  376. {
  377. /* source between speaker s and speaker s+1 */
  378. Alpha = M_PI_2 * (Theta-SpeakerAngle[s]) /
  379. (SpeakerAngle[s+1]-SpeakerAngle[s]);
  380. Device->PanningLUT[offset + Speaker2Chan[s]] = cos(Alpha);
  381. Device->PanningLUT[offset + Speaker2Chan[s+1]] = sin(Alpha);
  382. break;
  383. }
  384. }
  385. if(s == Device->NumChan - 1)
  386. {
  387. /* source between last and first speaker */
  388. if(Theta < SpeakerAngle[0])
  389. Theta += 2.0f * M_PI;
  390. Alpha = M_PI_2 * (Theta-SpeakerAngle[s]) /
  391. (2.0f * M_PI + SpeakerAngle[0]-SpeakerAngle[s]);
  392. Device->PanningLUT[offset + Speaker2Chan[s]] = cos(Alpha);
  393. Device->PanningLUT[offset + Speaker2Chan[0]] = sin(Alpha);
  394. }
  395. }
  396. }
  397. static ALvoid CalcNonAttnSourceParams(const ALCcontext *ALContext, ALsource *ALSource)
  398. {
  399. ALfloat SourceVolume,ListenerGain,MinVolume,MaxVolume;
  400. ALfloat DryGain, DryGainHF;
  401. ALfloat WetGain[MAX_SENDS];
  402. ALfloat WetGainHF[MAX_SENDS];
  403. ALint NumSends, Frequency;
  404. ALfloat cw;
  405. ALint i;
  406. //Get context properties
  407. NumSends = ALContext->Device->NumAuxSends;
  408. Frequency = ALContext->Device->Frequency;
  409. //Get listener properties
  410. ListenerGain = ALContext->Listener.Gain;
  411. //Get source properties
  412. SourceVolume = ALSource->flGain;
  413. MinVolume = ALSource->flMinGain;
  414. MaxVolume = ALSource->flMaxGain;
  415. //1. Multi-channel buffers always play "normal"
  416. ALSource->Params.Pitch = ALSource->flPitch;
  417. DryGain = SourceVolume;
  418. DryGain = __min(DryGain,MaxVolume);
  419. DryGain = __max(DryGain,MinVolume);
  420. DryGainHF = 1.0f;
  421. switch(ALSource->DirectFilter.type)
  422. {
  423. case AL_FILTER_LOWPASS:
  424. DryGain *= ALSource->DirectFilter.Gain;
  425. DryGainHF *= ALSource->DirectFilter.GainHF;
  426. break;
  427. }
  428. for(i = 0;i < OUTPUTCHANNELS;i++)
  429. ALSource->Params.DryGains[i] = DryGain * ListenerGain;
  430. for(i = 0;i < NumSends;i++)
  431. {
  432. WetGain[i] = SourceVolume;
  433. WetGain[i] = __min(WetGain[i],MaxVolume);
  434. WetGain[i] = __max(WetGain[i],MinVolume);
  435. WetGainHF[i] = 1.0f;
  436. switch(ALSource->Send[i].WetFilter.type)
  437. {
  438. case AL_FILTER_LOWPASS:
  439. WetGain[i] *= ALSource->Send[i].WetFilter.Gain;
  440. WetGainHF[i] *= ALSource->Send[i].WetFilter.GainHF;
  441. break;
  442. }
  443. ALSource->Params.WetGains[i] = WetGain[i] * ListenerGain;
  444. }
  445. for(i = NumSends;i < MAX_SENDS;i++)
  446. {
  447. ALSource->Params.WetGains[i] = 0.0f;
  448. WetGainHF[i] = 1.0f;
  449. }
  450. /* Update filter coefficients. Calculations based on the I3DL2
  451. * spec. */
  452. cw = cos(2.0*M_PI * LOWPASSFREQCUTOFF / Frequency);
  453. /* We use two chained one-pole filters, so we need to take the
  454. * square root of the squared gain, which is the same as the base
  455. * gain. */
  456. ALSource->Params.iirFilter.coeff = lpCoeffCalc(DryGainHF, cw);
  457. for(i = 0;i < NumSends;i++)
  458. {
  459. /* We use a one-pole filter, so we need to take the squared gain */
  460. ALfloat a = lpCoeffCalc(WetGainHF[i]*WetGainHF[i], cw);
  461. ALSource->Params.Send[i].iirFilter.coeff = a;
  462. }
  463. }
  464. static ALvoid CalcSourceParams(const ALCcontext *ALContext, ALsource *ALSource)
  465. {
  466. const ALCdevice *Device = ALContext->Device;
  467. ALfloat InnerAngle,OuterAngle,Angle,Distance,DryMix,OrigDist;
  468. ALfloat Direction[3],Position[3],SourceToListener[3];
  469. ALfloat Velocity[3],ListenerVel[3];
  470. ALfloat MinVolume,MaxVolume,MinDist,MaxDist,Rolloff,OuterGainHF;
  471. ALfloat ConeVolume,ConeHF,SourceVolume,ListenerGain;
  472. ALfloat DopplerFactor, DopplerVelocity, flSpeedOfSound;
  473. ALfloat Matrix[4][4];
  474. ALfloat flAttenuation, effectiveDist;
  475. ALfloat RoomAttenuation[MAX_SENDS];
  476. ALfloat MetersPerUnit;
  477. ALfloat RoomRolloff[MAX_SENDS];
  478. ALfloat DryGainHF = 1.0f;
  479. ALfloat WetGain[MAX_SENDS];
  480. ALfloat WetGainHF[MAX_SENDS];
  481. ALfloat DirGain, AmbientGain;
  482. const ALfloat *SpeakerGain;
  483. ALfloat length;
  484. ALuint Frequency;
  485. ALint NumSends;
  486. ALint pos, s, i;
  487. ALfloat cw;
  488. for(i = 0;i < MAX_SENDS;i++)
  489. WetGainHF[i] = 1.0f;
  490. //Get context properties
  491. DopplerFactor = ALContext->DopplerFactor * ALSource->DopplerFactor;
  492. DopplerVelocity = ALContext->DopplerVelocity;
  493. flSpeedOfSound = ALContext->flSpeedOfSound;
  494. NumSends = Device->NumAuxSends;
  495. Frequency = Device->Frequency;
  496. //Get listener properties
  497. ListenerGain = ALContext->Listener.Gain;
  498. MetersPerUnit = ALContext->Listener.MetersPerUnit;
  499. memcpy(ListenerVel, ALContext->Listener.Velocity, sizeof(ALContext->Listener.Velocity));
  500. //Get source properties
  501. SourceVolume = ALSource->flGain;
  502. memcpy(Position, ALSource->vPosition, sizeof(ALSource->vPosition));
  503. memcpy(Direction, ALSource->vOrientation, sizeof(ALSource->vOrientation));
  504. memcpy(Velocity, ALSource->vVelocity, sizeof(ALSource->vVelocity));
  505. MinVolume = ALSource->flMinGain;
  506. MaxVolume = ALSource->flMaxGain;
  507. MinDist = ALSource->flRefDistance;
  508. MaxDist = ALSource->flMaxDistance;
  509. Rolloff = ALSource->flRollOffFactor;
  510. InnerAngle = ALSource->flInnerAngle;
  511. OuterAngle = ALSource->flOuterAngle;
  512. OuterGainHF = ALSource->OuterGainHF;
  513. //1. Translate Listener to origin (convert to head relative)
  514. if(ALSource->bHeadRelative==AL_FALSE)
  515. {
  516. ALfloat U[3],V[3],N[3];
  517. // Build transform matrix
  518. memcpy(N, ALContext->Listener.Forward, sizeof(N)); // At-vector
  519. aluNormalize(N); // Normalized At-vector
  520. memcpy(V, ALContext->Listener.Up, sizeof(V)); // Up-vector
  521. aluNormalize(V); // Normalized Up-vector
  522. aluCrossproduct(N, V, U); // Right-vector
  523. aluNormalize(U); // Normalized Right-vector
  524. Matrix[0][0] = U[0]; Matrix[0][1] = V[0]; Matrix[0][2] = -N[0]; Matrix[0][3] = 0.0f;
  525. Matrix[1][0] = U[1]; Matrix[1][1] = V[1]; Matrix[1][2] = -N[1]; Matrix[1][3] = 0.0f;
  526. Matrix[2][0] = U[2]; Matrix[2][1] = V[2]; Matrix[2][2] = -N[2]; Matrix[2][3] = 0.0f;
  527. Matrix[3][0] = 0.0f; Matrix[3][1] = 0.0f; Matrix[3][2] = 0.0f; Matrix[3][3] = 1.0f;
  528. // Translate position
  529. Position[0] -= ALContext->Listener.Position[0];
  530. Position[1] -= ALContext->Listener.Position[1];
  531. Position[2] -= ALContext->Listener.Position[2];
  532. // Transform source position and direction into listener space
  533. aluMatrixVector(Position, 1.0f, Matrix);
  534. aluMatrixVector(Direction, 0.0f, Matrix);
  535. // Transform source and listener velocity into listener space
  536. aluMatrixVector(Velocity, 0.0f, Matrix);
  537. aluMatrixVector(ListenerVel, 0.0f, Matrix);
  538. }
  539. else
  540. ListenerVel[0] = ListenerVel[1] = ListenerVel[2] = 0.0f;
  541. SourceToListener[0] = -Position[0];
  542. SourceToListener[1] = -Position[1];
  543. SourceToListener[2] = -Position[2];
  544. aluNormalize(SourceToListener);
  545. aluNormalize(Direction);
  546. //2. Calculate distance attenuation
  547. Distance = aluSqrt(aluDotproduct(Position, Position));
  548. OrigDist = Distance;
  549. flAttenuation = 1.0f;
  550. for(i = 0;i < NumSends;i++)
  551. {
  552. RoomAttenuation[i] = 1.0f;
  553. RoomRolloff[i] = ALSource->RoomRolloffFactor;
  554. if(ALSource->Send[i].Slot &&
  555. (ALSource->Send[i].Slot->effect.type == AL_EFFECT_REVERB ||
  556. ALSource->Send[i].Slot->effect.type == AL_EFFECT_EAXREVERB))
  557. RoomRolloff[i] += ALSource->Send[i].Slot->effect.Reverb.RoomRolloffFactor;
  558. }
  559. switch(ALContext->SourceDistanceModel ? ALSource->DistanceModel :
  560. ALContext->DistanceModel)
  561. {
  562. case AL_INVERSE_DISTANCE_CLAMPED:
  563. Distance=__max(Distance,MinDist);
  564. Distance=__min(Distance,MaxDist);
  565. if(MaxDist < MinDist)
  566. break;
  567. //fall-through
  568. case AL_INVERSE_DISTANCE:
  569. if(MinDist > 0.0f)
  570. {
  571. if((MinDist + (Rolloff * (Distance - MinDist))) > 0.0f)
  572. flAttenuation = MinDist / (MinDist + (Rolloff * (Distance - MinDist)));
  573. for(i = 0;i < NumSends;i++)
  574. {
  575. if((MinDist + (RoomRolloff[i] * (Distance - MinDist))) > 0.0f)
  576. RoomAttenuation[i] = MinDist / (MinDist + (RoomRolloff[i] * (Distance - MinDist)));
  577. }
  578. }
  579. break;
  580. case AL_LINEAR_DISTANCE_CLAMPED:
  581. Distance=__max(Distance,MinDist);
  582. Distance=__min(Distance,MaxDist);
  583. if(MaxDist < MinDist)
  584. break;
  585. //fall-through
  586. case AL_LINEAR_DISTANCE:
  587. Distance=__min(Distance,MaxDist);
  588. if(MaxDist != MinDist)
  589. {
  590. flAttenuation = 1.0f - (Rolloff*(Distance-MinDist)/(MaxDist - MinDist));
  591. for(i = 0;i < NumSends;i++)
  592. RoomAttenuation[i] = 1.0f - (RoomRolloff[i]*(Distance-MinDist)/(MaxDist - MinDist));
  593. }
  594. break;
  595. case AL_EXPONENT_DISTANCE_CLAMPED:
  596. Distance=__max(Distance,MinDist);
  597. Distance=__min(Distance,MaxDist);
  598. if(MaxDist < MinDist)
  599. break;
  600. //fall-through
  601. case AL_EXPONENT_DISTANCE:
  602. if(Distance > 0.0f && MinDist > 0.0f)
  603. {
  604. flAttenuation = aluPow(Distance/MinDist, -Rolloff);
  605. for(i = 0;i < NumSends;i++)
  606. RoomAttenuation[i] = aluPow(Distance/MinDist, -RoomRolloff[i]);
  607. }
  608. break;
  609. case AL_NONE:
  610. break;
  611. }
  612. // Source Gain + Attenuation
  613. DryMix = SourceVolume * flAttenuation;
  614. for(i = 0;i < NumSends;i++)
  615. WetGain[i] = SourceVolume * RoomAttenuation[i];
  616. effectiveDist = 0.0f;
  617. if(MinDist > 0.0f)
  618. effectiveDist = (MinDist/flAttenuation - MinDist)*MetersPerUnit;
  619. // Distance-based air absorption
  620. if(ALSource->AirAbsorptionFactor > 0.0f && effectiveDist > 0.0f)
  621. {
  622. ALfloat absorb;
  623. // Absorption calculation is done in dB
  624. absorb = (ALSource->AirAbsorptionFactor*AIRABSORBGAINDBHF) *
  625. effectiveDist;
  626. // Convert dB to linear gain before applying
  627. absorb = aluPow(10.0f, absorb/20.0f);
  628. DryGainHF *= absorb;
  629. }
  630. //3. Apply directional soundcones
  631. Angle = aluAcos(aluDotproduct(Direction,SourceToListener)) * 180.0f/M_PI;
  632. if(Angle >= InnerAngle && Angle <= OuterAngle)
  633. {
  634. ALfloat scale = (Angle-InnerAngle) / (OuterAngle-InnerAngle);
  635. ConeVolume = (1.0f+(ALSource->flOuterGain-1.0f)*scale);
  636. ConeHF = (1.0f+(OuterGainHF-1.0f)*scale);
  637. }
  638. else if(Angle > OuterAngle)
  639. {
  640. ConeVolume = (1.0f+(ALSource->flOuterGain-1.0f));
  641. ConeHF = (1.0f+(OuterGainHF-1.0f));
  642. }
  643. else
  644. {
  645. ConeVolume = 1.0f;
  646. ConeHF = 1.0f;
  647. }
  648. // Apply some high-frequency attenuation for sources behind the listener
  649. // NOTE: This should be aluDotproduct({0,0,-1}, ListenerToSource), however
  650. // that is equivalent to aluDotproduct({0,0,1}, SourceToListener), which is
  651. // the same as SourceToListener[2]
  652. Angle = aluAcos(SourceToListener[2]) * 180.0f/M_PI;
  653. // Sources within the minimum distance attenuate less
  654. if(OrigDist < MinDist)
  655. Angle *= OrigDist/MinDist;
  656. if(Angle > 90.0f)
  657. {
  658. ALfloat scale = (Angle-90.0f) / (180.1f-90.0f); // .1 to account for fp errors
  659. ConeHF *= 1.0f - (Device->HeadDampen*scale);
  660. }
  661. DryMix *= ConeVolume;
  662. if(ALSource->DryGainHFAuto)
  663. DryGainHF *= ConeHF;
  664. // Clamp to Min/Max Gain
  665. DryMix = __min(DryMix,MaxVolume);
  666. DryMix = __max(DryMix,MinVolume);
  667. for(i = 0;i < NumSends;i++)
  668. {
  669. ALeffectslot *Slot = ALSource->Send[i].Slot;
  670. if(!Slot || Slot->effect.type == AL_EFFECT_NULL)
  671. {
  672. ALSource->Params.WetGains[i] = 0.0f;
  673. WetGainHF[i] = 1.0f;
  674. continue;
  675. }
  676. if(Slot->AuxSendAuto)
  677. {
  678. if(ALSource->WetGainAuto)
  679. WetGain[i] *= ConeVolume;
  680. if(ALSource->WetGainHFAuto)
  681. WetGainHF[i] *= ConeHF;
  682. // Clamp to Min/Max Gain
  683. WetGain[i] = __min(WetGain[i],MaxVolume);
  684. WetGain[i] = __max(WetGain[i],MinVolume);
  685. if(Slot->effect.type == AL_EFFECT_REVERB ||
  686. Slot->effect.type == AL_EFFECT_EAXREVERB)
  687. {
  688. /* Apply a decay-time transformation to the wet path, based on
  689. * the attenuation of the dry path.
  690. *
  691. * Using the approximate (effective) source to listener
  692. * distance, the initial decay of the reverb effect is
  693. * calculated and applied to the wet path.
  694. */
  695. WetGain[i] *= aluPow(10.0f, effectiveDist /
  696. (SPEEDOFSOUNDMETRESPERSEC *
  697. Slot->effect.Reverb.DecayTime) *
  698. -60.0 / 20.0);
  699. WetGainHF[i] *= aluPow(10.0f,
  700. log10(Slot->effect.Reverb.AirAbsorptionGainHF) *
  701. ALSource->AirAbsorptionFactor * effectiveDist);
  702. }
  703. }
  704. else
  705. {
  706. /* If the slot's auxiliary send auto is off, the data sent to the
  707. * effect slot is the same as the dry path, sans filter effects */
  708. WetGain[i] = DryMix;
  709. WetGainHF[i] = DryGainHF;
  710. }
  711. switch(ALSource->Send[i].WetFilter.type)
  712. {
  713. case AL_FILTER_LOWPASS:
  714. WetGain[i] *= ALSource->Send[i].WetFilter.Gain;
  715. WetGainHF[i] *= ALSource->Send[i].WetFilter.GainHF;
  716. break;
  717. }
  718. ALSource->Params.WetGains[i] = WetGain[i] * ListenerGain;
  719. }
  720. for(i = NumSends;i < MAX_SENDS;i++)
  721. {
  722. ALSource->Params.WetGains[i] = 0.0f;
  723. WetGainHF[i] = 1.0f;
  724. }
  725. // Apply filter gains and filters
  726. switch(ALSource->DirectFilter.type)
  727. {
  728. case AL_FILTER_LOWPASS:
  729. DryMix *= ALSource->DirectFilter.Gain;
  730. DryGainHF *= ALSource->DirectFilter.GainHF;
  731. break;
  732. }
  733. DryMix *= ListenerGain;
  734. // Calculate Velocity
  735. if(DopplerFactor != 0.0f)
  736. {
  737. ALfloat flVSS, flVLS;
  738. ALfloat flMaxVelocity = (DopplerVelocity * flSpeedOfSound) /
  739. DopplerFactor;
  740. flVSS = aluDotproduct(Velocity, SourceToListener);
  741. if(flVSS >= flMaxVelocity)
  742. flVSS = (flMaxVelocity - 1.0f);
  743. else if(flVSS <= -flMaxVelocity)
  744. flVSS = -flMaxVelocity + 1.0f;
  745. flVLS = aluDotproduct(ListenerVel, SourceToListener);
  746. if(flVLS >= flMaxVelocity)
  747. flVLS = (flMaxVelocity - 1.0f);
  748. else if(flVLS <= -flMaxVelocity)
  749. flVLS = -flMaxVelocity + 1.0f;
  750. ALSource->Params.Pitch = ALSource->flPitch *
  751. ((flSpeedOfSound * DopplerVelocity) - (DopplerFactor * flVLS)) /
  752. ((flSpeedOfSound * DopplerVelocity) - (DopplerFactor * flVSS));
  753. }
  754. else
  755. ALSource->Params.Pitch = ALSource->flPitch;
  756. // Use energy-preserving panning algorithm for multi-speaker playback
  757. length = __max(OrigDist, MinDist);
  758. if(length > 0.0f)
  759. {
  760. ALfloat invlen = 1.0f/length;
  761. Position[0] *= invlen;
  762. Position[1] *= invlen;
  763. Position[2] *= invlen;
  764. }
  765. pos = aluCart2LUTpos(-Position[2], Position[0]);
  766. SpeakerGain = &Device->PanningLUT[OUTPUTCHANNELS * pos];
  767. DirGain = aluSqrt(Position[0]*Position[0] + Position[2]*Position[2]);
  768. // elevation adjustment for directional gain. this sucks, but
  769. // has low complexity
  770. AmbientGain = 1.0/aluSqrt(Device->NumChan) * (1.0-DirGain);
  771. for(s = 0;s < OUTPUTCHANNELS;s++)
  772. ALSource->Params.DryGains[s] = 0.0f;
  773. for(s = 0;s < (ALsizei)Device->NumChan;s++)
  774. {
  775. Channel chan = Device->Speaker2Chan[s];
  776. ALfloat gain = SpeakerGain[chan]*DirGain + AmbientGain;
  777. ALSource->Params.DryGains[chan] = DryMix * gain;
  778. }
  779. /* Update filter coefficients. */
  780. cw = cos(2.0*M_PI * LOWPASSFREQCUTOFF / Frequency);
  781. /* Spatialized sources use four chained one-pole filters, so we need to
  782. * take the fourth root of the squared gain, which is the same as the
  783. * square root of the base gain. */
  784. ALSource->Params.iirFilter.coeff = lpCoeffCalc(aluSqrt(DryGainHF), cw);
  785. for(i = 0;i < NumSends;i++)
  786. {
  787. /* The wet path uses two chained one-pole filters, so take the
  788. * base gain (square root of the squared gain) */
  789. ALSource->Params.Send[i].iirFilter.coeff = lpCoeffCalc(WetGainHF[i], cw);
  790. }
  791. }
  792. static __inline ALfloat point(ALfloat val1, ALfloat val2, ALint frac)
  793. {
  794. return val1;
  795. (void)val2;
  796. (void)frac;
  797. }
  798. static __inline ALfloat lerp(ALfloat val1, ALfloat val2, ALint frac)
  799. {
  800. return val1 + ((val2-val1)*(frac * (1.0f/(1<<FRACTIONBITS))));
  801. }
  802. static __inline ALfloat cos_lerp(ALfloat val1, ALfloat val2, ALint frac)
  803. {
  804. ALfloat mult = (1.0f-cos(frac * (1.0f/(1<<FRACTIONBITS)) * M_PI)) * 0.5f;
  805. return val1 + ((val2-val1)*mult);
  806. }
  807. static void MixSomeSources(ALCcontext *ALContext, float (*DryBuffer)[OUTPUTCHANNELS], ALuint SamplesToDo)
  808. {
  809. static float DummyBuffer[BUFFERSIZE];
  810. ALfloat *WetBuffer[MAX_SENDS];
  811. ALfloat DrySend[OUTPUTCHANNELS];
  812. ALfloat dryGainStep[OUTPUTCHANNELS];
  813. ALfloat wetGainStep[MAX_SENDS];
  814. ALuint i, j, k, out;
  815. ALsource *ALSource;
  816. ALfloat value, outsamp;
  817. ALbufferlistitem *BufferListItem;
  818. ALint64 DataSize64,DataPos64;
  819. FILTER *DryFilter, *WetFilter[MAX_SENDS];
  820. ALfloat WetSend[MAX_SENDS];
  821. ALuint rampLength;
  822. ALboolean DuplicateStereo;
  823. ALuint DeviceFreq;
  824. ALint increment;
  825. ALuint DataPosInt, DataPosFrac;
  826. ALuint Channels, Bytes;
  827. ALuint Frequency;
  828. resampler_t Resampler;
  829. ALuint BuffersPlayed;
  830. ALboolean Looping;
  831. ALfloat Pitch;
  832. ALenum State;
  833. ALsizei pos;
  834. DuplicateStereo = ALContext->Device->DuplicateStereo;
  835. DeviceFreq = ALContext->Device->Frequency;
  836. rampLength = DeviceFreq * MIN_RAMP_LENGTH / 1000;
  837. rampLength = max(rampLength, SamplesToDo);
  838. pos = 0;
  839. next_source:
  840. while(ALContext->ActiveSourceCount > pos)
  841. {
  842. ALsizei end;
  843. ALSource = ALContext->ActiveSources[pos];
  844. if(ALSource->state == AL_PLAYING)
  845. break;
  846. end = --(ALContext->ActiveSourceCount);
  847. ALContext->ActiveSources[pos] = ALContext->ActiveSources[end];
  848. }
  849. if(pos >= ALContext->ActiveSourceCount)
  850. return;
  851. /* Find buffer format */
  852. Frequency = 0;
  853. Channels = 0;
  854. Bytes = 0;
  855. BufferListItem = ALSource->queue;
  856. while(BufferListItem != NULL)
  857. {
  858. ALbuffer *ALBuffer;
  859. if((ALBuffer=BufferListItem->buffer) != NULL)
  860. {
  861. Channels = aluChannelsFromFormat(ALBuffer->format);
  862. Bytes = aluBytesFromFormat(ALBuffer->format);
  863. Frequency = ALBuffer->frequency;
  864. break;
  865. }
  866. BufferListItem = BufferListItem->next;
  867. }
  868. if(ALSource->NeedsUpdate)
  869. {
  870. //Only apply 3D calculations for mono buffers
  871. if(Channels == 1)
  872. CalcSourceParams(ALContext, ALSource);
  873. else
  874. CalcNonAttnSourceParams(ALContext, ALSource);
  875. ALSource->NeedsUpdate = AL_FALSE;
  876. }
  877. /* Get source info */
  878. Resampler = ALSource->Resampler;
  879. State = ALSource->state;
  880. BuffersPlayed = ALSource->BuffersPlayed;
  881. DataPosInt = ALSource->position;
  882. DataPosFrac = ALSource->position_fraction;
  883. Looping = ALSource->bLooping;
  884. /* Compute 18.14 fixed point step */
  885. Pitch = (ALSource->Params.Pitch*Frequency) / DeviceFreq;
  886. if(Pitch > (float)MAX_PITCH) Pitch = (float)MAX_PITCH;
  887. increment = (ALint)(Pitch*(ALfloat)(1L<<FRACTIONBITS));
  888. if(increment <= 0) increment = (1<<FRACTIONBITS);
  889. if(ALSource->FirstStart)
  890. {
  891. for(i = 0;i < OUTPUTCHANNELS;i++)
  892. DrySend[i] = ALSource->Params.DryGains[i];
  893. for(i = 0;i < MAX_SENDS;i++)
  894. WetSend[i] = ALSource->Params.WetGains[i];
  895. }
  896. else
  897. {
  898. for(i = 0;i < OUTPUTCHANNELS;i++)
  899. DrySend[i] = ALSource->DryGains[i];
  900. for(i = 0;i < MAX_SENDS;i++)
  901. WetSend[i] = ALSource->WetGains[i];
  902. }
  903. DryFilter = &ALSource->Params.iirFilter;
  904. for(i = 0;i < MAX_SENDS;i++)
  905. {
  906. WetFilter[i] = &ALSource->Params.Send[i].iirFilter;
  907. WetBuffer[i] = (ALSource->Send[i].Slot ?
  908. ALSource->Send[i].Slot->WetBuffer :
  909. DummyBuffer);
  910. }
  911. /* Get current buffer queue item */
  912. BufferListItem = ALSource->queue;
  913. for(i = 0;i < BuffersPlayed && BufferListItem;i++)
  914. BufferListItem = BufferListItem->next;
  915. j = 0;
  916. do {
  917. ALfloat *Data = NULL;
  918. ALuint LoopStart = 0;
  919. ALuint LoopEnd = 0;
  920. ALuint DataSize = 0;
  921. ALbuffer *ALBuffer;
  922. ALuint BufferSize;
  923. /* Get buffer info */
  924. if((ALBuffer=BufferListItem->buffer) != NULL)
  925. {
  926. Data = ALBuffer->data;
  927. DataSize = ALBuffer->size;
  928. DataSize /= Channels * Bytes;
  929. LoopStart = ALBuffer->LoopStart;
  930. LoopEnd = ALBuffer->LoopEnd;
  931. }
  932. if(Looping && ALSource->lSourceType == AL_STATIC)
  933. {
  934. /* If current offset is beyond the loop range, do not loop */
  935. if(DataPosInt >= LoopEnd)
  936. Looping = AL_FALSE;
  937. }
  938. if(!Looping || ALSource->lSourceType != AL_STATIC)
  939. {
  940. /* Non-looping and non-static sources ignore loop points */
  941. LoopStart = 0;
  942. LoopEnd = DataSize;
  943. }
  944. if(DataPosInt >= DataSize)
  945. goto skipmix;
  946. if(BufferListItem->next)
  947. {
  948. ALbuffer *NextBuf = BufferListItem->next->buffer;
  949. if(NextBuf && NextBuf->size)
  950. {
  951. ALint ulExtraSamples = BUFFER_PADDING*Channels*Bytes;
  952. ulExtraSamples = min(NextBuf->size, ulExtraSamples);
  953. memcpy(&Data[DataSize*Channels], NextBuf->data, ulExtraSamples);
  954. }
  955. }
  956. else if(Looping)
  957. {
  958. ALbuffer *NextBuf = ALSource->queue->buffer;
  959. if(NextBuf && NextBuf->size)
  960. {
  961. ALint ulExtraSamples = BUFFER_PADDING*Channels*Bytes;
  962. ulExtraSamples = min(NextBuf->size, ulExtraSamples);
  963. memcpy(&Data[DataSize*Channels], &NextBuf->data[LoopStart*Channels], ulExtraSamples);
  964. }
  965. }
  966. else
  967. memset(&Data[DataSize*Channels], 0, (BUFFER_PADDING*Channels*Bytes));
  968. /* Compute the gain steps for each output channel */
  969. for(i = 0;i < OUTPUTCHANNELS;i++)
  970. dryGainStep[i] = (ALSource->Params.DryGains[i]-DrySend[i]) /
  971. rampLength;
  972. for(i = 0;i < MAX_SENDS;i++)
  973. wetGainStep[i] = (ALSource->Params.WetGains[i]-WetSend[i]) /
  974. rampLength;
  975. /* Figure out how many samples we can mix. */
  976. DataSize64 = LoopEnd;
  977. DataSize64 <<= FRACTIONBITS;
  978. DataPos64 = DataPosInt;
  979. DataPos64 <<= FRACTIONBITS;
  980. DataPos64 += DataPosFrac;
  981. BufferSize = (ALuint)((DataSize64-DataPos64+(increment-1)) / increment);
  982. BufferSize = min(BufferSize, (SamplesToDo-j));
  983. /* Actual sample mixing loop */
  984. k = 0;
  985. Data += DataPosInt*Channels;
  986. if(Channels == 1) /* Mono */
  987. {
  988. #define DO_MIX(resampler) do { \
  989. while(BufferSize--) \
  990. { \
  991. for(i = 0;i < OUTPUTCHANNELS;i++) \
  992. DrySend[i] += dryGainStep[i]; \
  993. for(i = 0;i < MAX_SENDS;i++) \
  994. WetSend[i] += wetGainStep[i]; \
  995. \
  996. /* First order interpolator */ \
  997. value = (resampler)(Data[k], Data[k+1], DataPosFrac); \
  998. \
  999. /* Direct path final mix buffer and panning */ \
  1000. outsamp = lpFilter4P(DryFilter, 0, value); \
  1001. DryBuffer[j][FRONT_LEFT] += outsamp*DrySend[FRONT_LEFT]; \
  1002. DryBuffer[j][FRONT_RIGHT] += outsamp*DrySend[FRONT_RIGHT]; \
  1003. DryBuffer[j][SIDE_LEFT] += outsamp*DrySend[SIDE_LEFT]; \
  1004. DryBuffer[j][SIDE_RIGHT] += outsamp*DrySend[SIDE_RIGHT]; \
  1005. DryBuffer[j][BACK_LEFT] += outsamp*DrySend[BACK_LEFT]; \
  1006. DryBuffer[j][BACK_RIGHT] += outsamp*DrySend[BACK_RIGHT]; \
  1007. DryBuffer[j][FRONT_CENTER] += outsamp*DrySend[FRONT_CENTER]; \
  1008. DryBuffer[j][BACK_CENTER] += outsamp*DrySend[BACK_CENTER]; \
  1009. \
  1010. /* Room path final mix buffer and panning */ \
  1011. for(i = 0;i < MAX_SENDS;i++) \
  1012. { \
  1013. outsamp = lpFilter2P(WetFilter[i], 0, value); \
  1014. WetBuffer[i][j] += outsamp*WetSend[i]; \
  1015. } \
  1016. \
  1017. DataPosFrac += increment; \
  1018. k += DataPosFrac>>FRACTIONBITS; \
  1019. DataPosFrac &= FRACTIONMASK; \
  1020. j++; \
  1021. } \
  1022. } while(0)
  1023. switch(Resampler)
  1024. {
  1025. case POINT_RESAMPLER:
  1026. DO_MIX(point); break;
  1027. case LINEAR_RESAMPLER:
  1028. DO_MIX(lerp); break;
  1029. case COSINE_RESAMPLER:
  1030. DO_MIX(cos_lerp); break;
  1031. case RESAMPLER_MIN:
  1032. case RESAMPLER_MAX:
  1033. break;
  1034. }
  1035. #undef DO_MIX
  1036. }
  1037. else if(Channels == 2 && DuplicateStereo) /* Stereo */
  1038. {
  1039. const int chans[] = {
  1040. FRONT_LEFT, FRONT_RIGHT
  1041. };
  1042. const int chans2[] = {
  1043. BACK_LEFT, SIDE_LEFT, BACK_RIGHT, SIDE_RIGHT
  1044. };
  1045. const ALfloat scaler = 1.0f/Channels;
  1046. const ALfloat dupscaler = aluSqrt(1.0f/3.0f);
  1047. #define DO_MIX(resampler) do { \
  1048. while(BufferSize--) \
  1049. { \
  1050. for(i = 0;i < OUTPUTCHANNELS;i++) \
  1051. DrySend[i] += dryGainStep[i]; \
  1052. for(i = 0;i < MAX_SENDS;i++) \
  1053. WetSend[i] += wetGainStep[i]; \
  1054. \
  1055. for(i = 0;i < Channels;i++) \
  1056. { \
  1057. value = (resampler)(Data[k*Channels + i],Data[(k+1)*Channels + i],\
  1058. DataPosFrac); \
  1059. outsamp = lpFilter2P(DryFilter, chans[i]*2, value) * dupscaler; \
  1060. DryBuffer[j][chans[i]] += outsamp*DrySend[chans[i]]; \
  1061. DryBuffer[j][chans2[i*2+0]] += outsamp*DrySend[chans2[i*2+0]]; \
  1062. DryBuffer[j][chans2[i*2+1]] += outsamp*DrySend[chans2[i*2+1]]; \
  1063. for(out = 0;out < MAX_SENDS;out++) \
  1064. { \
  1065. outsamp = lpFilter1P(WetFilter[out], chans[i], value); \
  1066. WetBuffer[out][j] += outsamp*WetSend[out]*scaler; \
  1067. } \
  1068. } \
  1069. \
  1070. DataPosFrac += increment; \
  1071. k += DataPosFrac>>FRACTIONBITS; \
  1072. DataPosFrac &= FRACTIONMASK; \
  1073. j++; \
  1074. } \
  1075. } while(0)
  1076. switch(Resampler)
  1077. {
  1078. case POINT_RESAMPLER:
  1079. DO_MIX(point); break;
  1080. case LINEAR_RESAMPLER:
  1081. DO_MIX(lerp); break;
  1082. case COSINE_RESAMPLER:
  1083. DO_MIX(cos_lerp); break;
  1084. case RESAMPLER_MIN:
  1085. case RESAMPLER_MAX:
  1086. break;
  1087. }
  1088. #undef DO_MIX
  1089. }
  1090. else if(Channels == 2) /* Stereo */
  1091. {
  1092. const int chans[] = {
  1093. FRONT_LEFT, FRONT_RIGHT
  1094. };
  1095. const ALfloat scaler = 1.0f/Channels;
  1096. #define DO_MIX(resampler) do { \
  1097. while(BufferSize--) \
  1098. { \
  1099. for(i = 0;i < OUTPUTCHANNELS;i++) \
  1100. DrySend[i] += dryGainStep[i]; \
  1101. for(i = 0;i < MAX_SENDS;i++) \
  1102. WetSend[i] += wetGainStep[i]; \
  1103. \
  1104. for(i = 0;i < Channels;i++) \
  1105. { \
  1106. value = (resampler)(Data[k*Channels + i],Data[(k+1)*Channels + i],\
  1107. DataPosFrac); \
  1108. outsamp = lpFilter2P(DryFilter, chans[i]*2, value); \
  1109. DryBuffer[j][chans[i]] += outsamp*DrySend[chans[i]]; \
  1110. for(out = 0;out < MAX_SENDS;out++) \
  1111. { \
  1112. outsamp = lpFilter1P(WetFilter[out], chans[i], value); \
  1113. WetBuffer[out][j] += outsamp*WetSend[out]*scaler; \
  1114. } \
  1115. } \
  1116. \
  1117. DataPosFrac += increment; \
  1118. k += DataPosFrac>>FRACTIONBITS; \
  1119. DataPosFrac &= FRACTIONMASK; \
  1120. j++; \
  1121. } \
  1122. } while(0)
  1123. switch(Resampler)
  1124. {
  1125. case POINT_RESAMPLER:
  1126. DO_MIX(point); break;
  1127. case LINEAR_RESAMPLER:
  1128. DO_MIX(lerp); break;
  1129. case COSINE_RESAMPLER:
  1130. DO_MIX(cos_lerp); break;
  1131. case RESAMPLER_MIN:
  1132. case RESAMPLER_MAX:
  1133. break;
  1134. }
  1135. }
  1136. else if(Channels == 4) /* Quad */
  1137. {
  1138. const int chans[] = {
  1139. FRONT_LEFT, FRONT_RIGHT,
  1140. BACK_LEFT, BACK_RIGHT
  1141. };
  1142. const ALfloat scaler = 1.0f/Channels;
  1143. switch(Resampler)
  1144. {
  1145. case POINT_RESAMPLER:
  1146. DO_MIX(point); break;
  1147. case LINEAR_RESAMPLER:
  1148. DO_MIX(lerp); break;
  1149. case COSINE_RESAMPLER:
  1150. DO_MIX(cos_lerp); break;
  1151. case RESAMPLER_MIN:
  1152. case RESAMPLER_MAX:
  1153. break;
  1154. }
  1155. }
  1156. else if(Channels == 6) /* 5.1 */
  1157. {
  1158. const int chans[] = {
  1159. FRONT_LEFT, FRONT_RIGHT,
  1160. FRONT_CENTER, LFE,
  1161. BACK_LEFT, BACK_RIGHT
  1162. };
  1163. const ALfloat scaler = 1.0f/Channels;
  1164. switch(Resampler)
  1165. {
  1166. case POINT_RESAMPLER:
  1167. DO_MIX(point); break;
  1168. case LINEAR_RESAMPLER:
  1169. DO_MIX(lerp); break;
  1170. case COSINE_RESAMPLER:
  1171. DO_MIX(cos_lerp); break;
  1172. case RESAMPLER_MIN:
  1173. case RESAMPLER_MAX:
  1174. break;
  1175. }
  1176. }
  1177. else if(Channels == 7) /* 6.1 */
  1178. {
  1179. const int chans[] = {
  1180. FRONT_LEFT, FRONT_RIGHT,
  1181. FRONT_CENTER, LFE,
  1182. BACK_CENTER,
  1183. SIDE_LEFT, SIDE_RIGHT
  1184. };
  1185. const ALfloat scaler = 1.0f/Channels;
  1186. switch(Resampler)
  1187. {
  1188. case POINT_RESAMPLER:
  1189. DO_MIX(point); break;
  1190. case LINEAR_RESAMPLER:
  1191. DO_MIX(lerp); break;
  1192. case COSINE_RESAMPLER:
  1193. DO_MIX(cos_lerp); break;
  1194. case RESAMPLER_MIN:
  1195. case RESAMPLER_MAX:
  1196. break;
  1197. }
  1198. }
  1199. else if(Channels == 8) /* 7.1 */
  1200. {
  1201. const int chans[] = {
  1202. FRONT_LEFT, FRONT_RIGHT,
  1203. FRONT_CENTER, LFE,
  1204. BACK_LEFT, BACK_RIGHT,
  1205. SIDE_LEFT, SIDE_RIGHT
  1206. };
  1207. const ALfloat scaler = 1.0f/Channels;
  1208. switch(Resampler)
  1209. {
  1210. case POINT_RESAMPLER:
  1211. DO_MIX(point); break;
  1212. case LINEAR_RESAMPLER:
  1213. DO_MIX(lerp); break;
  1214. case COSINE_RESAMPLER:
  1215. DO_MIX(cos_lerp); break;
  1216. case RESAMPLER_MIN:
  1217. case RESAMPLER_MAX:
  1218. break;
  1219. }
  1220. #undef DO_MIX
  1221. }
  1222. else /* Unknown? */
  1223. {
  1224. for(i = 0;i < OUTPUTCHANNELS;i++)
  1225. DrySend[i] += dryGainStep[i]*BufferSize;
  1226. for(i = 0;i < MAX_SENDS;i++)
  1227. WetSend[i] += wetGainStep[i]*BufferSize;
  1228. while(BufferSize--)
  1229. {
  1230. DataPosFrac += increment;
  1231. k += DataPosFrac>>FRACTIONBITS;
  1232. DataPosFrac &= FRACTIONMASK;
  1233. j++;
  1234. }
  1235. }
  1236. DataPosInt += k;
  1237. skipmix:
  1238. /* Handle looping sources */
  1239. if(DataPosInt >= LoopEnd)
  1240. {
  1241. if(BuffersPlayed < (ALSource->BuffersInQueue-1))
  1242. {
  1243. BufferListItem = BufferListItem->next;
  1244. BuffersPlayed++;
  1245. DataPosInt -= DataSize;
  1246. }
  1247. else if(Looping)
  1248. {
  1249. BufferListItem = ALSource->queue;
  1250. BuffersPlayed = 0;
  1251. if(ALSource->lSourceType == AL_STATIC)
  1252. DataPosInt = ((DataPosInt-LoopStart)%(LoopEnd-LoopStart)) + LoopStart;
  1253. else
  1254. DataPosInt -= DataSize;
  1255. }
  1256. else
  1257. {
  1258. State = AL_STOPPED;
  1259. BufferListItem = ALSource->queue;
  1260. BuffersPlayed = ALSource->BuffersInQueue;
  1261. DataPosInt = 0;
  1262. DataPosFrac = 0;
  1263. }
  1264. }
  1265. } while(State == AL_PLAYING && j < SamplesToDo);
  1266. /* Update source info */
  1267. ALSource->state = State;
  1268. ALSource->BuffersPlayed = BuffersPlayed;
  1269. ALSource->position = DataPosInt;
  1270. ALSource->position_fraction = DataPosFrac;
  1271. ALSource->Buffer = BufferListItem->buffer;
  1272. for(i = 0;i < OUTPUTCHANNELS;i++)
  1273. ALSource->DryGains[i] = DrySend[i];
  1274. for(i = 0;i < MAX_SENDS;i++)
  1275. ALSource->WetGains[i] = WetSend[i];
  1276. ALSource->FirstStart = AL_FALSE;
  1277. if(ALSource->state == AL_PLAYING)
  1278. pos++;
  1279. goto next_source;
  1280. }
  1281. ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
  1282. {
  1283. float (*DryBuffer)[OUTPUTCHANNELS];
  1284. ALfloat (*Matrix)[OUTPUTCHANNELS];
  1285. const ALuint *ChanMap;
  1286. ALuint SamplesToDo;
  1287. ALeffectslot *ALEffectSlot;
  1288. ALCcontext *ALContext;
  1289. ALfloat samp;
  1290. int fpuState;
  1291. ALuint i, j, c;
  1292. ALsizei e;
  1293. #if defined(HAVE_FESETROUND)
  1294. fpuState = fegetround();
  1295. fesetround(FE_TOWARDZERO);
  1296. #elif defined(HAVE__CONTROLFP)
  1297. fpuState = _controlfp(0, 0);
  1298. _controlfp(_RC_CHOP, _MCW_RC);
  1299. #else
  1300. (void)fpuState;
  1301. #endif
  1302. DryBuffer = device->DryBuffer;
  1303. while(size > 0)
  1304. {
  1305. /* Setup variables */
  1306. SamplesToDo = min(size, BUFFERSIZE);
  1307. /* Clear mixing buffer */
  1308. memset(DryBuffer, 0, SamplesToDo*OUTPUTCHANNELS*sizeof(ALfloat));
  1309. SuspendContext(NULL);
  1310. for(c = 0;c < device->NumContexts;c++)
  1311. {
  1312. ALContext = device->Contexts[c];
  1313. SuspendContext(ALContext);
  1314. MixSomeSources(ALContext, DryBuffer, SamplesToDo);
  1315. /* effect slot processing */
  1316. for(e = 0;e < ALContext->EffectSlotMap.size;e++)
  1317. {
  1318. ALEffectSlot = ALContext->EffectSlotMap.array[e].value;
  1319. if(ALEffectSlot->EffectState)
  1320. ALEffect_Process(ALEffectSlot->EffectState, ALEffectSlot, SamplesToDo, ALEffectSlot->WetBuffer, DryBuffer);
  1321. for(i = 0;i < SamplesToDo;i++)
  1322. ALEffectSlot->WetBuffer[i] = 0.0f;
  1323. }
  1324. ProcessContext(ALContext);
  1325. }
  1326. ProcessContext(NULL);
  1327. //Post processing loop
  1328. ChanMap = device->DevChannels;
  1329. Matrix = device->ChannelMatrix;
  1330. switch(device->Format)
  1331. {
  1332. #define CHECK_WRITE_FORMAT(bits, type, func) \
  1333. case AL_FORMAT_MONO##bits: \
  1334. for(i = 0;i < SamplesToDo;i++) \
  1335. { \
  1336. samp = 0.0f; \
  1337. for(c = 0;c < OUTPUTCHANNELS;c++) \
  1338. samp += DryBuffer[i][c] * Matrix[c][FRONT_CENTER]; \
  1339. ((type*)buffer)[ChanMap[FRONT_CENTER]] = (func)(samp); \
  1340. buffer = ((type*)buffer) + 1; \
  1341. } \
  1342. break; \
  1343. case AL_FORMAT_STEREO##bits: \
  1344. if(device->Bs2b) \
  1345. { \
  1346. for(i = 0;i < SamplesToDo;i++) \
  1347. { \
  1348. float samples[2] = { 0.0f, 0.0f }; \
  1349. for(c = 0;c < OUTPUTCHANNELS;c++) \
  1350. { \
  1351. samples[0] += DryBuffer[i][c]*Matrix[c][FRONT_LEFT]; \
  1352. samples[1] += DryBuffer[i][c]*Matrix[c][FRONT_RIGHT]; \
  1353. } \
  1354. bs2b_cross_feed(device->Bs2b, samples); \
  1355. ((type*)buffer)[ChanMap[FRONT_LEFT]] = (func)(samples[0]);\
  1356. ((type*)buffer)[ChanMap[FRONT_RIGHT]]= (func)(samples[1]);\
  1357. buffer = ((type*)buffer) + 2; \
  1358. } \
  1359. } \
  1360. else \
  1361. { \
  1362. for(i = 0;i < SamplesToDo;i++) \
  1363. { \
  1364. static const Channel chans[] = { \
  1365. FRONT_LEFT, FRONT_RIGHT \
  1366. }; \
  1367. for(j = 0;j < 2;j++) \
  1368. { \
  1369. samp = 0.0f; \
  1370. for(c = 0;c < OUTPUTCHANNELS;c++) \
  1371. samp += DryBuffer[i][c] * Matrix[c][chans[j]]; \
  1372. ((type*)buffer)[ChanMap[chans[j]]] = (func)(samp); \
  1373. } \
  1374. buffer = ((type*)buffer) + 2; \
  1375. } \
  1376. } \
  1377. break; \
  1378. case AL_FORMAT_QUAD##bits: \
  1379. for(i = 0;i < SamplesToDo;i++) \
  1380. { \
  1381. static const Channel chans[] = { \
  1382. FRONT_LEFT, FRONT_RIGHT, \
  1383. BACK_LEFT, BACK_RIGHT, \
  1384. }; \
  1385. for(j = 0;j < 4;j++) \
  1386. { \
  1387. samp = 0.0f; \
  1388. for(c = 0;c < OUTPUTCHANNELS;c++) \
  1389. samp += DryBuffer[i][c] * Matrix[c][chans[j]]; \
  1390. ((type*)buffer)[ChanMap[chans[j]]] = (func)(samp); \
  1391. } \
  1392. buffer = ((type*)buffer) + 4; \
  1393. } \
  1394. break; \
  1395. case AL_FORMAT_51CHN##bits: \
  1396. for(i = 0;i < SamplesToDo;i++) \
  1397. { \
  1398. static const Channel chans[] = { \
  1399. FRONT_LEFT, FRONT_RIGHT, \
  1400. FRONT_CENTER, LFE, \
  1401. BACK_LEFT, BACK_RIGHT, \
  1402. }; \
  1403. for(j = 0;j < 6;j++) \
  1404. { \
  1405. samp = 0.0f; \
  1406. for(c = 0;c < OUTPUTCHANNELS;c++) \
  1407. samp += DryBuffer[i][c] * Matrix[c][chans[j]]; \
  1408. ((type*)buffer)[ChanMap[chans[j]]] = (func)(samp); \
  1409. } \
  1410. buffer = ((type*)buffer) + 6; \
  1411. } \
  1412. break; \
  1413. case AL_FORMAT_61CHN##bits: \
  1414. for(i = 0;i < SamplesToDo;i++) \
  1415. { \
  1416. static const Channel chans[] = { \
  1417. FRONT_LEFT, FRONT_RIGHT, \
  1418. FRONT_CENTER, LFE, BACK_CENTER, \
  1419. SIDE_LEFT, SIDE_RIGHT, \
  1420. }; \
  1421. for(j = 0;j < 7;j++) \
  1422. { \
  1423. samp = 0.0f; \
  1424. for(c = 0;c < OUTPUTCHANNELS;c++) \
  1425. samp += DryBuffer[i][c] * Matrix[c][chans[j]]; \
  1426. ((type*)buffer)[ChanMap[chans[j]]] = (func)(samp); \
  1427. } \
  1428. buffer = ((type*)buffer) + 7; \
  1429. } \
  1430. break; \
  1431. case AL_FORMAT_71CHN##bits: \
  1432. for(i = 0;i < SamplesToDo;i++) \
  1433. { \
  1434. static const Channel chans[] = { \
  1435. FRONT_LEFT, FRONT_RIGHT, \
  1436. FRONT_CENTER, LFE, \
  1437. BACK_LEFT, BACK_RIGHT, \
  1438. SIDE_LEFT, SIDE_RIGHT \
  1439. }; \
  1440. for(j = 0;j < 8;j++) \
  1441. { \
  1442. samp = 0.0f; \
  1443. for(c = 0;c < OUTPUTCHANNELS;c++) \
  1444. samp += DryBuffer[i][c] * Matrix[c][chans[j]]; \
  1445. ((type*)buffer)[ChanMap[chans[j]]] = (func)(samp); \
  1446. } \
  1447. buffer = ((type*)buffer) + 8; \
  1448. } \
  1449. break;
  1450. #define AL_FORMAT_MONO32 AL_FORMAT_MONO_FLOAT32
  1451. #define AL_FORMAT_STEREO32 AL_FORMAT_STEREO_FLOAT32
  1452. CHECK_WRITE_FORMAT(8, ALubyte, aluF2UB)
  1453. CHECK_WRITE_FORMAT(16, ALshort, aluF2S)
  1454. CHECK_WRITE_FORMAT(32, ALfloat, aluF2F)
  1455. #undef AL_FORMAT_STEREO32
  1456. #undef AL_FORMAT_MONO32
  1457. #undef CHECK_WRITE_FORMAT
  1458. default:
  1459. break;
  1460. }
  1461. size -= SamplesToDo;
  1462. }
  1463. #if defined(HAVE_FESETROUND)
  1464. fesetround(fpuState);
  1465. #elif defined(HAVE__CONTROLFP)
  1466. _controlfp(fpuState, 0xfffff);
  1467. #endif
  1468. }
  1469. ALvoid aluHandleDisconnect(ALCdevice *device)
  1470. {
  1471. ALuint i;
  1472. SuspendContext(NULL);
  1473. for(i = 0;i < device->NumContexts;i++)
  1474. {
  1475. ALCcontext *Context = device->Contexts[i];
  1476. ALsource *source;
  1477. ALsizei pos;
  1478. SuspendContext(Context);
  1479. for(pos = 0;pos < Context->SourceMap.size;pos++)
  1480. {
  1481. source = Context->SourceMap.array[pos].value;
  1482. if(source->state == AL_PLAYING)
  1483. {
  1484. source->state = AL_STOPPED;
  1485. source->BuffersPlayed = source->BuffersInQueue;
  1486. source->position = 0;
  1487. source->position_fraction = 0;
  1488. }
  1489. }
  1490. ProcessContext(Context);
  1491. }
  1492. device->Connected = ALC_FALSE;
  1493. ProcessContext(NULL);
  1494. }