Don't access ALSource for every sample mix
[openal-soft.git] / Alc / ALu.c
blobbaf19976407fbd47660d20f4937d43f82df0bfc5
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.
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.
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
21 #define _CRT_SECURE_NO_DEPRECATE // get rid of sprintf security warnings on VS2005
23 #include "config.h"
25 #include <math.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 "bs2b.h"
36 #if defined(HAVE_STDINT_H)
37 #include <stdint.h>
38 typedef int64_t ALint64;
39 #elif defined(HAVE___INT64)
40 typedef __int64 ALint64;
41 #elif (SIZEOF_LONG == 8)
42 typedef long ALint64;
43 #elif (SIZEOF_LONG_LONG == 8)
44 typedef long long ALint64;
45 #endif
47 #ifdef HAVE_SQRTF
48 #define aluSqrt(x) ((ALfloat)sqrtf((float)(x)))
49 #else
50 #define aluSqrt(x) ((ALfloat)sqrt((double)(x)))
51 #endif
53 #ifdef HAVE_ACOSF
54 #define aluAcos(x) ((ALfloat)acosf((float)(x)))
55 #else
56 #define aluAcos(x) ((ALfloat)acos((double)(x)))
57 #endif
59 // fixes for mingw32.
60 #if defined(max) && !defined(__max)
61 #define __max max
62 #endif
63 #if defined(min) && !defined(__min)
64 #define __min min
65 #endif
67 #define BUFFERSIZE 48000
68 #define FRACTIONBITS 14
69 #define FRACTIONMASK ((1L<<FRACTIONBITS)-1)
70 #define MAX_PITCH 4
72 enum {
73 FRONT_LEFT = 0,
74 FRONT_RIGHT,
75 SIDE_LEFT,
76 SIDE_RIGHT,
77 BACK_LEFT,
78 BACK_RIGHT,
79 CENTER,
80 LFE,
82 OUTPUTCHANNELS
85 /* NOTE: The AL_FORMAT_REAR* enums aren't handled here be cause they're
86 * converted to AL_FORMAT_QUAD* when loaded */
87 __inline ALuint aluBytesFromFormat(ALenum format)
89 switch(format)
91 case AL_FORMAT_MONO8:
92 case AL_FORMAT_STEREO8:
93 case AL_FORMAT_QUAD8_LOKI:
94 case AL_FORMAT_QUAD8:
95 case AL_FORMAT_51CHN8:
96 case AL_FORMAT_61CHN8:
97 case AL_FORMAT_71CHN8:
98 return 1;
100 case AL_FORMAT_MONO16:
101 case AL_FORMAT_STEREO16:
102 case AL_FORMAT_QUAD16_LOKI:
103 case AL_FORMAT_QUAD16:
104 case AL_FORMAT_51CHN16:
105 case AL_FORMAT_61CHN16:
106 case AL_FORMAT_71CHN16:
107 return 2;
109 case AL_FORMAT_MONO_FLOAT32:
110 case AL_FORMAT_STEREO_FLOAT32:
111 case AL_FORMAT_QUAD32:
112 case AL_FORMAT_51CHN32:
113 case AL_FORMAT_61CHN32:
114 case AL_FORMAT_71CHN32:
115 return 4;
117 default:
118 return 0;
122 __inline ALuint aluChannelsFromFormat(ALenum format)
124 switch(format)
126 case AL_FORMAT_MONO8:
127 case AL_FORMAT_MONO16:
128 case AL_FORMAT_MONO_FLOAT32:
129 return 1;
131 case AL_FORMAT_STEREO8:
132 case AL_FORMAT_STEREO16:
133 case AL_FORMAT_STEREO_FLOAT32:
134 return 2;
136 case AL_FORMAT_QUAD8_LOKI:
137 case AL_FORMAT_QUAD16_LOKI:
138 case AL_FORMAT_QUAD8:
139 case AL_FORMAT_QUAD16:
140 case AL_FORMAT_QUAD32:
141 return 4;
143 case AL_FORMAT_51CHN8:
144 case AL_FORMAT_51CHN16:
145 case AL_FORMAT_51CHN32:
146 return 6;
148 case AL_FORMAT_61CHN8:
149 case AL_FORMAT_61CHN16:
150 case AL_FORMAT_61CHN32:
151 return 7;
153 case AL_FORMAT_71CHN8:
154 case AL_FORMAT_71CHN16:
155 case AL_FORMAT_71CHN32:
156 return 8;
158 default:
159 return 0;
163 static __inline ALint aluF2L(ALfloat Value)
165 #if 0
166 if(sizeof(ALint) == 4 && sizeof(double) == 8)
168 double temp;
169 temp = Value + (((65536.0*65536.0*16.0)+(65536.0*65536.0*8.0))*65536.0);
170 return *((ALint*)&temp);
172 #endif
173 return (ALint)Value;
176 static __inline ALshort aluF2S(ALfloat Value)
178 ALint i;
180 i = aluF2L(Value);
181 i = __min( 32767, i);
182 i = __max(-32768, i);
183 return ((ALshort)i);
186 static __inline ALvoid aluCrossproduct(ALfloat *inVector1,ALfloat *inVector2,ALfloat *outVector)
188 outVector[0] = inVector1[1]*inVector2[2] - inVector1[2]*inVector2[1];
189 outVector[1] = inVector1[2]*inVector2[0] - inVector1[0]*inVector2[2];
190 outVector[2] = inVector1[0]*inVector2[1] - inVector1[1]*inVector2[0];
193 static __inline ALfloat aluDotproduct(ALfloat *inVector1,ALfloat *inVector2)
195 return inVector1[0]*inVector2[0] + inVector1[1]*inVector2[1] +
196 inVector1[2]*inVector2[2];
199 static __inline ALvoid aluNormalize(ALfloat *inVector)
201 ALfloat length, inverse_length;
203 length = (ALfloat)aluSqrt(aluDotproduct(inVector, inVector));
204 if(length != 0)
206 inverse_length = 1.0f/length;
207 inVector[0] *= inverse_length;
208 inVector[1] *= inverse_length;
209 inVector[2] *= inverse_length;
213 static __inline ALvoid aluMatrixVector(ALfloat *vector,ALfloat matrix[3][3])
215 ALfloat result[3];
217 result[0] = vector[0]*matrix[0][0] + vector[1]*matrix[1][0] + vector[2]*matrix[2][0];
218 result[1] = vector[0]*matrix[0][1] + vector[1]*matrix[1][1] + vector[2]*matrix[2][1];
219 result[2] = vector[0]*matrix[0][2] + vector[1]*matrix[1][2] + vector[2]*matrix[2][2];
220 memcpy(vector, result, sizeof(result));
223 static __inline ALfloat aluComputeDrySample(ALfloat DryGainHF, ALfloat sample, ALfloat LastDrySample)
225 if(DryGainHF < 1.0f)
227 if(DryGainHF > 0.0f)
229 sample *= DryGainHF;
230 sample += LastDrySample * (1.0f-DryGainHF);
232 else
233 sample = 0.0f;
236 return sample;
239 static __inline ALfloat aluComputeWetSample(ALfloat WetGainHF, ALfloat sample, ALfloat LastWetSample)
241 if(WetGainHF < 1.0f)
243 if(WetGainHF > 0.0f)
245 sample *= WetGainHF;
246 sample += LastWetSample * (1.0f-WetGainHF);
248 else
249 sample = 0.0f;
252 return sample;
255 static ALvoid CalcSourceParams(ALCcontext *ALContext, ALsource *ALSource,
256 ALenum isMono, ALenum OutputFormat,
257 ALfloat *drysend, ALfloat *wetsend,
258 ALfloat *pitch, ALfloat *drygainhf,
259 ALfloat *wetgainhf)
261 ALfloat InnerAngle,OuterAngle,Angle,Distance,DryMix,WetMix=0.0f;
262 ALfloat Direction[3],Position[3],SourceToListener[3];
263 ALfloat MinVolume,MaxVolume,MinDist,MaxDist,Rolloff,OuterGainHF;
264 ALfloat ConeVolume,SourceVolume,PanningFB,PanningLR,ListenerGain;
265 ALfloat U[3],V[3],N[3];
266 ALfloat DopplerFactor, DopplerVelocity, flSpeedOfSound, flMaxVelocity;
267 ALfloat Matrix[3][3];
268 ALfloat flAttenuation;
269 ALfloat RoomAttenuation;
270 ALfloat MetersPerUnit;
271 ALfloat RoomRolloff;
272 ALfloat DryGainHF = 1.0f;
273 ALfloat WetGainHF = 1.0f;
275 //Get context properties
276 DopplerFactor = ALContext->DopplerFactor;
277 DopplerVelocity = ALContext->DopplerVelocity;
278 flSpeedOfSound = ALContext->flSpeedOfSound;
280 //Get listener properties
281 ListenerGain = ALContext->Listener.Gain;
282 MetersPerUnit = ALContext->Listener.MetersPerUnit;
284 //Get source properties
285 SourceVolume = ALSource->flGain;
286 memcpy(Position, ALSource->vPosition, sizeof(ALSource->vPosition));
287 memcpy(Direction, ALSource->vOrientation, sizeof(ALSource->vOrientation));
288 MinVolume = ALSource->flMinGain;
289 MaxVolume = ALSource->flMaxGain;
290 MinDist = ALSource->flRefDistance;
291 MaxDist = ALSource->flMaxDistance;
292 Rolloff = ALSource->flRollOffFactor;
293 InnerAngle = ALSource->flInnerAngle;
294 OuterAngle = ALSource->flOuterAngle;
295 OuterGainHF = ALSource->OuterGainHF;
296 RoomRolloff = ALSource->RoomRolloffFactor;
298 //Only apply 3D calculations for mono buffers
299 if(isMono != AL_FALSE)
301 //1. Translate Listener to origin (convert to head relative)
302 if(ALSource->bHeadRelative==AL_FALSE)
304 Position[0] -= ALContext->Listener.Position[0];
305 Position[1] -= ALContext->Listener.Position[1];
306 Position[2] -= ALContext->Listener.Position[2];
309 //2. Calculate distance attenuation
310 Distance = aluSqrt(aluDotproduct(Position, Position));
312 if(ALSource->Send[0].Slot && !ALSource->Send[0].Slot->AuxSendAuto)
314 if(ALSource->Send[0].Slot->effect.type == AL_EFFECT_REVERB)
315 RoomRolloff = ALSource->Send[0].Slot->effect.Reverb.RoomRolloffFactor;
318 flAttenuation = 1.0f;
319 RoomAttenuation = 1.0f;
320 switch (ALContext->DistanceModel)
322 case AL_INVERSE_DISTANCE_CLAMPED:
323 Distance=__max(Distance,MinDist);
324 Distance=__min(Distance,MaxDist);
325 if (MaxDist < MinDist)
326 break;
327 //fall-through
328 case AL_INVERSE_DISTANCE:
329 if (MinDist > 0.0f)
331 if ((MinDist + (Rolloff * (Distance - MinDist))) > 0.0f)
332 flAttenuation = MinDist / (MinDist + (Rolloff * (Distance - MinDist)));
333 if ((MinDist + (RoomRolloff * (Distance - MinDist))) > 0.0f)
334 RoomAttenuation = MinDist / (MinDist + (RoomRolloff * (Distance - MinDist)));
336 break;
338 case AL_LINEAR_DISTANCE_CLAMPED:
339 Distance=__max(Distance,MinDist);
340 Distance=__min(Distance,MaxDist);
341 if (MaxDist < MinDist)
342 break;
343 //fall-through
344 case AL_LINEAR_DISTANCE:
345 Distance=__min(Distance,MaxDist);
346 if (MaxDist != MinDist)
348 flAttenuation = 1.0f - (Rolloff*(Distance-MinDist)/(MaxDist - MinDist));
349 RoomAttenuation = 1.0f - (RoomRolloff*(Distance-MinDist)/(MaxDist - MinDist));
351 break;
353 case AL_EXPONENT_DISTANCE_CLAMPED:
354 Distance=__max(Distance,MinDist);
355 Distance=__min(Distance,MaxDist);
356 if (MaxDist < MinDist)
357 break;
358 //fall-through
359 case AL_EXPONENT_DISTANCE:
360 if ((Distance > 0.0f) && (MinDist > 0.0f))
362 flAttenuation = (ALfloat)pow(Distance/MinDist, -Rolloff);
363 RoomAttenuation = (ALfloat)pow(Distance/MinDist, -RoomRolloff);
365 break;
367 case AL_NONE:
368 default:
369 flAttenuation = 1.0f;
370 RoomAttenuation = 1.0f;
371 break;
374 // Source Gain + Attenuation and clamp to Min/Max Gain
375 DryMix = SourceVolume * flAttenuation;
376 DryMix = __min(DryMix,MaxVolume);
377 DryMix = __max(DryMix,MinVolume);
379 WetMix = SourceVolume * (ALSource->WetGainAuto ?
380 RoomAttenuation : 1.0f);
381 WetMix = __min(WetMix,MaxVolume);
382 WetMix = __max(WetMix,MinVolume);
384 //3. Apply directional soundcones
385 SourceToListener[0] = -Position[0];
386 SourceToListener[1] = -Position[1];
387 SourceToListener[2] = -Position[2];
388 aluNormalize(Direction);
389 aluNormalize(SourceToListener);
390 Angle = aluAcos(aluDotproduct(Direction,SourceToListener)) * 180.0f /
391 3.141592654f;
392 if(Angle >= InnerAngle && Angle <= OuterAngle)
394 ALfloat scale = (Angle-InnerAngle) / (OuterAngle-InnerAngle);
395 ConeVolume = (1.0f+(ALSource->flOuterGain-1.0f)*scale);
396 if(ALSource->WetGainAuto)
397 WetMix *= ConeVolume;
398 if(ALSource->DryGainHFAuto)
399 DryGainHF *= (1.0f+(OuterGainHF-1.0f)*scale);
400 if(ALSource->WetGainHFAuto)
401 WetGainHF *= (1.0f+(OuterGainHF-1.0f)*scale);
403 else if(Angle > OuterAngle)
405 ConeVolume = (1.0f+(ALSource->flOuterGain-1.0f));
406 if(ALSource->WetGainAuto)
407 WetMix *= ConeVolume;
408 if(ALSource->DryGainHFAuto)
409 DryGainHF *= (1.0f+(OuterGainHF-1.0f));
410 if(ALSource->WetGainHFAuto)
411 WetGainHF *= (1.0f+(OuterGainHF-1.0f));
413 else
414 ConeVolume = 1.0f;
416 //4. Calculate Velocity
417 if(DopplerFactor != 0.0f)
419 ALfloat flVSS, flVLS;
421 flVLS = aluDotproduct(ALContext->Listener.Velocity,
422 SourceToListener);
423 flVSS = aluDotproduct(ALSource->vVelocity, SourceToListener);
425 flMaxVelocity = (DopplerVelocity * flSpeedOfSound) / DopplerFactor;
427 if (flVSS >= flMaxVelocity)
428 flVSS = (flMaxVelocity - 1.0f);
429 else if (flVSS <= -flMaxVelocity)
430 flVSS = -flMaxVelocity + 1.0f;
432 if (flVLS >= flMaxVelocity)
433 flVLS = (flMaxVelocity - 1.0f);
434 else if (flVLS <= -flMaxVelocity)
435 flVLS = -flMaxVelocity + 1.0f;
437 pitch[0] = ALSource->flPitch *
438 ((flSpeedOfSound * DopplerVelocity) - (DopplerFactor * flVLS)) /
439 ((flSpeedOfSound * DopplerVelocity) - (DopplerFactor * flVSS));
441 else
442 pitch[0] = ALSource->flPitch;
444 //5. Align coordinate system axes
445 aluCrossproduct(ALContext->Listener.Forward, ALContext->Listener.Up, U); // Right-vector
446 aluNormalize(U); // Normalized Right-vector
447 memcpy(V, ALContext->Listener.Up, sizeof(V)); // Up-vector
448 aluNormalize(V); // Normalized Up-vector
449 memcpy(N, ALContext->Listener.Forward, sizeof(N)); // At-vector
450 aluNormalize(N); // Normalized At-vector
451 Matrix[0][0] = U[0]; Matrix[0][1] = V[0]; Matrix[0][2] = -N[0];
452 Matrix[1][0] = U[1]; Matrix[1][1] = V[1]; Matrix[1][2] = -N[1];
453 Matrix[2][0] = U[2]; Matrix[2][1] = V[2]; Matrix[2][2] = -N[2];
454 aluMatrixVector(Position, Matrix);
456 //6. Apply filter gains and filters
457 switch(ALSource->DirectFilter.filter)
459 case AL_FILTER_LOWPASS:
460 DryMix *= ALSource->DirectFilter.Gain;
461 DryGainHF *= ALSource->DirectFilter.GainHF;
462 break;
465 switch(ALSource->Send[0].WetFilter.filter)
467 case AL_FILTER_LOWPASS:
468 WetMix *= ALSource->Send[0].WetFilter.Gain;
469 WetGainHF *= ALSource->Send[0].WetFilter.GainHF;
470 break;
473 if(ALSource->AirAbsorptionFactor > 0.0f)
474 DryGainHF *= pow(ALSource->AirAbsorptionFactor * AIRABSORBGAINHF,
475 Distance * MetersPerUnit);
477 if(ALSource->Send[0].Slot)
479 WetMix *= ALSource->Send[0].Slot->Gain;
481 if(ALSource->Send[0].Slot->effect.type == AL_EFFECT_REVERB)
483 WetGainHF *= ALSource->Send[0].Slot->effect.Reverb.GainHF;
484 WetGainHF *= pow(ALSource->Send[0].Slot->effect.Reverb.AirAbsorptionGainHF,
485 Distance * MetersPerUnit);
488 else
490 WetMix = 0.0f;
491 WetGainHF = 1.0f;
494 DryMix *= ListenerGain * ConeVolume;
495 WetMix *= ListenerGain;
497 //7. Convert normalized position into pannings, then into channel volumes
498 aluNormalize(Position);
499 switch(aluChannelsFromFormat(OutputFormat))
501 case 1:
502 drysend[FRONT_LEFT] = DryMix * aluSqrt(1.0f); //Direct
503 drysend[FRONT_RIGHT] = DryMix * aluSqrt(1.0f); //Direct
504 wetsend[FRONT_LEFT] = WetMix * aluSqrt(1.0f); //Room
505 wetsend[FRONT_RIGHT] = WetMix * aluSqrt(1.0f); //Room
506 break;
507 case 2:
508 PanningLR = 0.5f + 0.5f*Position[0];
509 drysend[FRONT_LEFT] = DryMix * aluSqrt(1.0f-PanningLR); //L Direct
510 drysend[FRONT_RIGHT] = DryMix * aluSqrt( PanningLR); //R Direct
511 wetsend[FRONT_LEFT] = WetMix * aluSqrt(1.0f-PanningLR); //L Room
512 wetsend[FRONT_RIGHT] = WetMix * aluSqrt( PanningLR); //R Room
513 break;
514 case 4:
515 /* TODO: Add center/lfe channel in spatial calculations? */
516 case 6:
517 // Apply a scalar so each individual speaker has more weight
518 PanningLR = 0.5f + (0.5f*Position[0]*1.41421356f);
519 PanningLR = __min(1.0f, PanningLR);
520 PanningLR = __max(0.0f, PanningLR);
521 PanningFB = 0.5f + (0.5f*Position[2]*1.41421356f);
522 PanningFB = __min(1.0f, PanningFB);
523 PanningFB = __max(0.0f, PanningFB);
524 drysend[FRONT_LEFT] = DryMix * aluSqrt((1.0f-PanningLR)*(1.0f-PanningFB));
525 drysend[FRONT_RIGHT] = DryMix * aluSqrt(( PanningLR)*(1.0f-PanningFB));
526 drysend[BACK_LEFT] = DryMix * aluSqrt((1.0f-PanningLR)*( PanningFB));
527 drysend[BACK_RIGHT] = DryMix * aluSqrt(( PanningLR)*( PanningFB));
528 wetsend[FRONT_LEFT] = WetMix * aluSqrt((1.0f-PanningLR)*(1.0f-PanningFB));
529 wetsend[FRONT_RIGHT] = WetMix * aluSqrt(( PanningLR)*(1.0f-PanningFB));
530 wetsend[BACK_LEFT] = WetMix * aluSqrt((1.0f-PanningLR)*( PanningFB));
531 wetsend[BACK_RIGHT] = WetMix * aluSqrt(( PanningLR)*( PanningFB));
532 break;
533 case 7:
534 case 8:
535 PanningFB = 1.0f - fabs(Position[2]*1.15470054f);
536 PanningFB = __min(1.0f, PanningFB);
537 PanningFB = __max(0.0f, PanningFB);
538 PanningLR = 0.5f + (0.5*Position[0]*((1.0f-PanningFB)*2.0f));
539 PanningLR = __min(1.0f, PanningLR);
540 PanningLR = __max(0.0f, PanningLR);
541 if(Position[2] > 0.0f)
543 drysend[BACK_LEFT] = DryMix * aluSqrt((1.0f-PanningLR)*(1.0f-PanningFB));
544 drysend[BACK_RIGHT] = DryMix * aluSqrt(( PanningLR)*(1.0f-PanningFB));
545 drysend[SIDE_LEFT] = DryMix * aluSqrt((1.0f-PanningLR)*( PanningFB));
546 drysend[SIDE_RIGHT] = DryMix * aluSqrt(( PanningLR)*( PanningFB));
547 drysend[FRONT_LEFT] = 0.0f;
548 drysend[FRONT_RIGHT] = 0.0f;
549 wetsend[BACK_LEFT] = WetMix * aluSqrt((1.0f-PanningLR)*(1.0f-PanningFB));
550 wetsend[BACK_RIGHT] = WetMix * aluSqrt(( PanningLR)*(1.0f-PanningFB));
551 wetsend[SIDE_LEFT] = WetMix * aluSqrt((1.0f-PanningLR)*( PanningFB));
552 wetsend[SIDE_RIGHT] = WetMix * aluSqrt(( PanningLR)*( PanningFB));
553 wetsend[FRONT_LEFT] = 0.0f;
554 wetsend[FRONT_RIGHT] = 0.0f;
556 else
558 drysend[FRONT_LEFT] = DryMix * aluSqrt((1.0f-PanningLR)*(1.0f-PanningFB));
559 drysend[FRONT_RIGHT] = DryMix * aluSqrt(( PanningLR)*(1.0f-PanningFB));
560 drysend[SIDE_LEFT] = DryMix * aluSqrt((1.0f-PanningLR)*( PanningFB));
561 drysend[SIDE_RIGHT] = DryMix * aluSqrt(( PanningLR)*( PanningFB));
562 drysend[BACK_LEFT] = 0.0f;
563 drysend[BACK_RIGHT] = 0.0f;
564 wetsend[FRONT_LEFT] = WetMix * aluSqrt((1.0f-PanningLR)*(1.0f-PanningFB));
565 wetsend[FRONT_RIGHT] = WetMix * aluSqrt(( PanningLR)*(1.0f-PanningFB));
566 wetsend[SIDE_LEFT] = WetMix * aluSqrt((1.0f-PanningLR)*( PanningFB));
567 wetsend[SIDE_RIGHT] = WetMix * aluSqrt(( PanningLR)*( PanningFB));
568 wetsend[BACK_LEFT] = 0.0f;
569 wetsend[BACK_RIGHT] = 0.0f;
571 default:
572 break;
575 *drygainhf = DryGainHF;
576 *wetgainhf = WetGainHF;
578 else
580 //1. Multi-channel buffers always play "normal"
581 pitch[0] = ALSource->flPitch;
583 drysend[FRONT_LEFT] = SourceVolume * ListenerGain;
584 drysend[FRONT_RIGHT] = SourceVolume * ListenerGain;
585 drysend[SIDE_LEFT] = SourceVolume * ListenerGain;
586 drysend[SIDE_RIGHT] = SourceVolume * ListenerGain;
587 drysend[BACK_LEFT] = SourceVolume * ListenerGain;
588 drysend[BACK_RIGHT] = SourceVolume * ListenerGain;
589 drysend[CENTER] = SourceVolume * ListenerGain;
590 drysend[LFE] = SourceVolume * ListenerGain;
591 wetsend[FRONT_LEFT] = 0.0f;
592 wetsend[FRONT_RIGHT] = 0.0f;
593 wetsend[SIDE_LEFT] = 0.0f;
594 wetsend[SIDE_RIGHT] = 0.0f;
595 wetsend[BACK_LEFT] = 0.0f;
596 wetsend[BACK_RIGHT] = 0.0f;
597 wetsend[CENTER] = 0.0f;
598 wetsend[LFE] = 0.0f;
599 WetGainHF = 1.0f;
601 *drygainhf = DryGainHF;
602 *wetgainhf = WetGainHF;
606 ALvoid aluMixData(ALCcontext *ALContext,ALvoid *buffer,ALsizei size,ALenum format)
608 static float DryBuffer[BUFFERSIZE][OUTPUTCHANNELS];
609 static float WetBuffer[BUFFERSIZE][OUTPUTCHANNELS];
610 static float ReverbBuffer[BUFFERSIZE];
611 ALfloat DrySend[OUTPUTCHANNELS] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
612 ALfloat WetSend[OUTPUTCHANNELS] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
613 ALfloat DryGainHF = 0.0f;
614 ALfloat WetGainHF = 0.0f;
615 ALuint BlockAlign,BufferSize;
616 ALuint DataSize=0,DataPosInt=0,DataPosFrac=0;
617 ALuint Channels,Frequency,ulExtraSamples;
618 ALfloat DrySample, WetSample;
619 ALboolean doReverb;
620 ALfloat Pitch;
621 ALint Looping,increment,State;
622 ALuint Buffer,fraction;
623 ALuint SamplesToDo;
624 ALsource *ALSource;
625 ALbuffer *ALBuffer;
626 ALeffectslot *ALEffectSlot;
627 ALfloat value;
628 ALshort *Data;
629 ALuint i,j,k;
630 ALbufferlistitem *BufferListItem;
631 ALuint loop;
632 ALint64 DataSize64,DataPos64;
634 SuspendContext(ALContext);
636 if(buffer)
638 //Figure output format variables
639 BlockAlign = aluChannelsFromFormat(format);
640 BlockAlign *= aluBytesFromFormat(format);
642 size /= BlockAlign;
643 while(size > 0)
645 //Setup variables
646 ALSource = (ALContext ? ALContext->Source : NULL);
647 SamplesToDo = min(size, BUFFERSIZE);
649 //Clear mixing buffer
650 memset(DryBuffer, 0, SamplesToDo*OUTPUTCHANNELS*sizeof(ALfloat));
651 memset(WetBuffer, 0, SamplesToDo*OUTPUTCHANNELS*sizeof(ALfloat));
652 memset(ReverbBuffer, 0, SamplesToDo*sizeof(ALfloat));
654 //Actual mixing loop
655 while(ALSource)
657 j = 0;
658 State = ALSource->state;
660 doReverb = ((ALSource->Send[0].Slot &&
661 ALSource->Send[0].Slot->effect.type == AL_EFFECT_REVERB) ?
662 AL_TRUE : AL_FALSE);
664 while(State == AL_PLAYING && j < SamplesToDo)
666 DataSize = 0;
667 DataPosInt = 0;
668 DataPosFrac = 0;
670 //Get buffer info
671 if((Buffer = ALSource->ulBufferID))
673 ALBuffer = (ALbuffer*)ALTHUNK_LOOKUPENTRY(Buffer);
675 Data = ALBuffer->data;
676 Channels = aluChannelsFromFormat(ALBuffer->format);
677 DataSize = ALBuffer->size;
678 Frequency = ALBuffer->frequency;
680 CalcSourceParams(ALContext, ALSource,
681 (Channels==1) ? AL_TRUE : AL_FALSE,
682 format, DrySend, WetSend, &Pitch,
683 &DryGainHF, &WetGainHF);
686 Pitch = (Pitch*Frequency) / ALContext->Frequency;
687 DataSize /= Channels * aluBytesFromFormat(ALBuffer->format);
689 //Get source info
690 DataPosInt = ALSource->position;
691 DataPosFrac = ALSource->position_fraction;
692 DrySample = ALSource->LastDrySample;
693 WetSample = ALSource->LastWetSample;
695 //Compute 18.14 fixed point step
696 increment = aluF2L(Pitch*(1L<<FRACTIONBITS));
697 if(increment > (MAX_PITCH<<FRACTIONBITS))
698 increment = (MAX_PITCH<<FRACTIONBITS);
700 //Figure out how many samples we can mix.
701 //Pitch must be <= 4 (the number below !)
702 DataSize64 = DataSize+MAX_PITCH;
703 DataSize64 <<= FRACTIONBITS;
704 DataPos64 = DataPosInt;
705 DataPos64 <<= FRACTIONBITS;
706 DataPos64 += DataPosFrac;
707 BufferSize = (ALuint)((DataSize64-DataPos64) / increment);
708 BufferListItem = ALSource->queue;
709 for(loop = 0; loop < ALSource->BuffersPlayed; loop++)
711 if(BufferListItem)
712 BufferListItem = BufferListItem->next;
714 if (BufferListItem)
716 if (BufferListItem->next)
718 if(BufferListItem->next->buffer &&
719 ((ALbuffer*)ALTHUNK_LOOKUPENTRY(BufferListItem->next->buffer))->data)
721 ulExtraSamples = min(((ALbuffer*)ALTHUNK_LOOKUPENTRY(BufferListItem->next->buffer))->size, (ALint)(16*Channels));
722 memcpy(&Data[DataSize*Channels], ((ALbuffer*)ALTHUNK_LOOKUPENTRY(BufferListItem->next->buffer))->data, ulExtraSamples);
725 else if (ALSource->bLooping)
727 if (ALSource->queue->buffer)
729 if(((ALbuffer*)ALTHUNK_LOOKUPENTRY(ALSource->queue->buffer))->data)
731 ulExtraSamples = min(((ALbuffer*)ALTHUNK_LOOKUPENTRY(ALSource->queue->buffer))->size, (ALint)(16*Channels));
732 memcpy(&Data[DataSize*Channels], ((ALbuffer*)ALTHUNK_LOOKUPENTRY(ALSource->queue->buffer))->data, ulExtraSamples);
737 BufferSize = min(BufferSize, (SamplesToDo-j));
739 //Actual sample mixing loop
740 Data += DataPosInt*Channels;
741 while(BufferSize--)
743 k = DataPosFrac>>FRACTIONBITS;
744 fraction = DataPosFrac&FRACTIONMASK;
745 if(Channels==1)
747 //First order interpolator
748 ALfloat sample = (ALfloat)((ALshort)(((Data[k]*((1L<<FRACTIONBITS)-fraction))+(Data[k+1]*(fraction)))>>FRACTIONBITS));
750 //Direct path final mix buffer and panning
751 DrySample = aluComputeDrySample(DryGainHF, sample, DrySample);
752 DryBuffer[j][FRONT_LEFT] += DrySample*DrySend[FRONT_LEFT];
753 DryBuffer[j][FRONT_RIGHT] += DrySample*DrySend[FRONT_RIGHT];
754 DryBuffer[j][SIDE_LEFT] += DrySample*DrySend[SIDE_LEFT];
755 DryBuffer[j][SIDE_RIGHT] += DrySample*DrySend[SIDE_RIGHT];
756 DryBuffer[j][BACK_LEFT] += DrySample*DrySend[BACK_LEFT];
757 DryBuffer[j][BACK_RIGHT] += DrySample*DrySend[BACK_RIGHT];
758 //Room path final mix buffer and panning
759 WetSample = aluComputeWetSample(WetGainHF, sample, WetSample);
760 if(doReverb)
761 ReverbBuffer[j] += WetSample;
762 else
764 WetBuffer[j][FRONT_LEFT] += WetSample*WetSend[FRONT_LEFT];
765 WetBuffer[j][FRONT_RIGHT] += WetSample*WetSend[FRONT_RIGHT];
766 WetBuffer[j][SIDE_LEFT] += WetSample*WetSend[SIDE_LEFT];
767 WetBuffer[j][SIDE_RIGHT] += WetSample*WetSend[SIDE_RIGHT];
768 WetBuffer[j][BACK_LEFT] += WetSample*WetSend[BACK_LEFT];
769 WetBuffer[j][BACK_RIGHT] += WetSample*WetSend[BACK_RIGHT];
772 else
774 //First order interpolator (front left)
775 value = (ALfloat)((ALshort)(((Data[k*Channels ]*((1L<<FRACTIONBITS)-fraction))+(Data[(k+1)*Channels ]*(fraction)))>>FRACTIONBITS));
776 DryBuffer[j][FRONT_LEFT] += value*DrySend[FRONT_LEFT];
777 WetBuffer[j][FRONT_LEFT] += value*WetSend[FRONT_LEFT];
778 //First order interpolator (front right)
779 value = (ALfloat)((ALshort)(((Data[k*Channels+1]*((1L<<FRACTIONBITS)-fraction))+(Data[(k+1)*Channels+1]*(fraction)))>>FRACTIONBITS));
780 DryBuffer[j][FRONT_RIGHT] += value*DrySend[FRONT_RIGHT];
781 WetBuffer[j][FRONT_RIGHT] += value*WetSend[FRONT_RIGHT];
782 if(Channels >= 4)
784 int i = 2;
785 if(Channels >= 6)
787 if(Channels != 7)
789 //First order interpolator (center)
790 value = (ALfloat)((ALshort)(((Data[k*Channels+i]*((1L<<FRACTIONBITS)-fraction))+(Data[(k+1)*Channels+i]*(fraction)))>>FRACTIONBITS));
791 DryBuffer[j][CENTER] += value*DrySend[CENTER];
792 WetBuffer[j][CENTER] += value*WetSend[CENTER];
793 i++;
795 //First order interpolator (lfe)
796 value = (ALfloat)((ALshort)(((Data[k*Channels+i]*((1L<<FRACTIONBITS)-fraction))+(Data[(k+1)*Channels+i]*(fraction)))>>FRACTIONBITS));
797 DryBuffer[j][LFE] += value*DrySend[LFE];
798 WetBuffer[j][LFE] += value*WetSend[LFE];
799 i++;
801 //First order interpolator (back left)
802 value = (ALfloat)((ALshort)(((Data[k*Channels+i]*((1L<<FRACTIONBITS)-fraction))+(Data[(k+1)*Channels+i]*(fraction)))>>FRACTIONBITS));
803 DryBuffer[j][BACK_LEFT] += value*DrySend[BACK_LEFT];
804 WetBuffer[j][BACK_LEFT] += value*WetSend[BACK_LEFT];
805 i++;
806 //First order interpolator (back right)
807 value = (ALfloat)((ALshort)(((Data[k*Channels+i]*((1L<<FRACTIONBITS)-fraction))+(Data[(k+1)*Channels+i]*(fraction)))>>FRACTIONBITS));
808 DryBuffer[j][BACK_RIGHT] += value*DrySend[BACK_RIGHT];
809 WetBuffer[j][BACK_RIGHT] += value*WetSend[BACK_RIGHT];
810 i++;
811 if(Channels >= 7)
813 //First order interpolator (side left)
814 value = (ALfloat)((ALshort)(((Data[k*Channels+i]*((1L<<FRACTIONBITS)-fraction))+(Data[(k+1)*Channels+i]*(fraction)))>>FRACTIONBITS));
815 DryBuffer[j][SIDE_LEFT] += value*DrySend[SIDE_LEFT];
816 WetBuffer[j][SIDE_LEFT] += value*WetSend[SIDE_LEFT];
817 i++;
818 //First order interpolator (side right)
819 value = (ALfloat)((ALshort)(((Data[k*Channels+i]*((1L<<FRACTIONBITS)-fraction))+(Data[(k+1)*Channels+i]*(fraction)))>>FRACTIONBITS));
820 DryBuffer[j][SIDE_RIGHT] += value*DrySend[SIDE_RIGHT];
821 WetBuffer[j][SIDE_RIGHT] += value*WetSend[SIDE_RIGHT];
822 i++;
826 DataPosFrac += increment;
827 j++;
829 DataPosInt += (DataPosFrac>>FRACTIONBITS);
830 DataPosFrac = (DataPosFrac&FRACTIONMASK);
832 //Update source info
833 ALSource->position = DataPosInt;
834 ALSource->position_fraction = DataPosFrac;
835 ALSource->LastDrySample = DrySample;
836 ALSource->LastWetSample = WetSample;
839 //Handle looping sources
840 if(!Buffer || DataPosInt >= DataSize)
842 //queueing
843 if(ALSource->queue)
845 Looping = ALSource->bLooping;
846 if(ALSource->BuffersPlayed < (ALSource->BuffersInQueue-1))
848 BufferListItem = ALSource->queue;
849 for(loop = 0; loop <= ALSource->BuffersPlayed; loop++)
851 if(BufferListItem)
853 if(!Looping)
854 BufferListItem->bufferstate = PROCESSED;
855 BufferListItem = BufferListItem->next;
858 if(!Looping)
859 ALSource->BuffersProcessed++;
860 if(BufferListItem)
861 ALSource->ulBufferID = BufferListItem->buffer;
862 ALSource->position = DataPosInt-DataSize;
863 ALSource->position_fraction = DataPosFrac;
864 ALSource->BuffersPlayed++;
866 else
868 if(!Looping)
870 /* alSourceStop */
871 ALSource->state = AL_STOPPED;
872 ALSource->inuse = AL_FALSE;
873 ALSource->BuffersPlayed = ALSource->BuffersProcessed = ALSource->BuffersInQueue;
874 BufferListItem = ALSource->queue;
875 while(BufferListItem != NULL)
877 BufferListItem->bufferstate = PROCESSED;
878 BufferListItem = BufferListItem->next;
881 else
883 /* alSourceRewind */
884 /* alSourcePlay */
885 ALSource->state = AL_PLAYING;
886 ALSource->inuse = AL_TRUE;
887 ALSource->play = AL_TRUE;
888 ALSource->BuffersPlayed = 0;
889 ALSource->BufferPosition = 0;
890 ALSource->lBytesPlayed = 0;
891 ALSource->BuffersProcessed = 0;
892 BufferListItem = ALSource->queue;
893 while(BufferListItem != NULL)
895 BufferListItem->bufferstate = PENDING;
896 BufferListItem = BufferListItem->next;
898 ALSource->ulBufferID = ALSource->queue->buffer;
900 ALSource->position = DataPosInt-DataSize;
901 ALSource->position_fraction = DataPosFrac;
907 //Get source state
908 State = ALSource->state;
911 ALSource = ALSource->next;
914 ALEffectSlot = (ALContext ? ALContext->AuxiliaryEffectSlot : NULL);
915 while(ALEffectSlot)
917 if(ALEffectSlot->effect.type == AL_EFFECT_REVERB)
919 ALfloat *DelayBuffer = ALEffectSlot->ReverbBuffer;
920 ALuint Pos = ALEffectSlot->ReverbPos;
921 ALuint LatePos = ALEffectSlot->ReverbLatePos;
922 ALuint ReflectPos = ALEffectSlot->ReverbReflectPos;
923 ALuint Length = ALEffectSlot->ReverbLength;
924 ALfloat DecayGain = ALEffectSlot->ReverbDecayGain;
925 ALfloat DecayHFRatio = ALEffectSlot->effect.Reverb.DecayHFRatio;
926 ALfloat Gain = ALEffectSlot->effect.Reverb.Gain;
927 ALfloat ReflectGain = ALEffectSlot->effect.Reverb.ReflectionsGain;
928 ALfloat LateReverbGain = ALEffectSlot->effect.Reverb.LateReverbGain;
929 ALfloat LastDecaySample = ALEffectSlot->LastDecaySample;
930 ALfloat sample;
932 for(i = 0;i < SamplesToDo;i++)
934 DelayBuffer[Pos] = ReverbBuffer[i] * Gain;
936 sample = DelayBuffer[ReflectPos] * ReflectGain;
938 DelayBuffer[LatePos] *= LateReverbGain;
940 Pos = (Pos+1) % Length;
941 DelayBuffer[Pos] *= DecayHFRatio;
942 DelayBuffer[Pos] += LastDecaySample * (1.0f-DecayHFRatio);
943 LastDecaySample = DelayBuffer[Pos];
944 DelayBuffer[Pos] *= DecayGain;
946 DelayBuffer[LatePos] += DelayBuffer[Pos];
948 sample += DelayBuffer[LatePos];
950 WetBuffer[i][FRONT_LEFT] += sample;
951 WetBuffer[i][FRONT_RIGHT] += sample;
952 WetBuffer[i][SIDE_LEFT] += sample;
953 WetBuffer[i][SIDE_RIGHT] += sample;
954 WetBuffer[i][BACK_LEFT] += sample;
955 WetBuffer[i][BACK_RIGHT] += sample;
957 LatePos = (LatePos+1) % Length;
958 ReflectPos = (ReflectPos+1) % Length;
961 ALEffectSlot->ReverbPos = Pos;
962 ALEffectSlot->ReverbLatePos = LatePos;
963 ALEffectSlot->ReverbReflectPos = ReflectPos;
964 ALEffectSlot->LastDecaySample = LastDecaySample;
966 ALEffectSlot = ALEffectSlot->next;
969 //Post processing loop
970 switch(format)
972 case AL_FORMAT_MONO8:
973 for(i = 0;i < SamplesToDo;i++)
975 ((ALubyte*)buffer)[0] = (ALubyte)((aluF2S(DryBuffer[i][FRONT_LEFT]+DryBuffer[i][FRONT_RIGHT]+
976 WetBuffer[i][FRONT_LEFT]+WetBuffer[i][FRONT_RIGHT])>>8)+128);
977 buffer = ((ALubyte*)buffer) + 1;
979 break;
980 case AL_FORMAT_STEREO8:
981 if(ALContext && ALContext->bs2b)
983 for(i = 0;i < SamplesToDo;i++)
985 float samples[2];
986 samples[0] = DryBuffer[i][FRONT_LEFT] +WetBuffer[i][FRONT_LEFT];
987 samples[1] = DryBuffer[i][FRONT_RIGHT]+WetBuffer[i][FRONT_RIGHT];
988 bs2b_cross_feed(ALContext->bs2b, samples);
989 ((ALubyte*)buffer)[0] = (ALubyte)((aluF2S(samples[0])>>8)+128);
990 ((ALubyte*)buffer)[1] = (ALubyte)((aluF2S(samples[1])>>8)+128);
991 buffer = ((ALubyte*)buffer) + 2;
994 else
996 for(i = 0;i < SamplesToDo;i++)
998 ((ALubyte*)buffer)[0] = (ALubyte)((aluF2S(DryBuffer[i][FRONT_LEFT] +WetBuffer[i][FRONT_LEFT])>>8)+128);
999 ((ALubyte*)buffer)[1] = (ALubyte)((aluF2S(DryBuffer[i][FRONT_RIGHT]+WetBuffer[i][FRONT_RIGHT])>>8)+128);
1000 buffer = ((ALubyte*)buffer) + 2;
1003 break;
1004 case AL_FORMAT_QUAD8:
1005 for(i = 0;i < SamplesToDo;i++)
1007 ((ALubyte*)buffer)[0] = (ALubyte)((aluF2S(DryBuffer[i][FRONT_LEFT] +WetBuffer[i][FRONT_LEFT])>>8)+128);
1008 ((ALubyte*)buffer)[1] = (ALubyte)((aluF2S(DryBuffer[i][FRONT_RIGHT]+WetBuffer[i][FRONT_RIGHT])>>8)+128);
1009 ((ALubyte*)buffer)[2] = (ALubyte)((aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT])>>8)+128);
1010 ((ALubyte*)buffer)[3] = (ALubyte)((aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT])>>8)+128);
1011 buffer = ((ALubyte*)buffer) + 4;
1013 break;
1014 case AL_FORMAT_51CHN8:
1015 for(i = 0;i < SamplesToDo;i++)
1017 ((ALubyte*)buffer)[0] = (ALubyte)((aluF2S(DryBuffer[i][FRONT_LEFT] +WetBuffer[i][FRONT_LEFT])>>8)+128);
1018 ((ALubyte*)buffer)[1] = (ALubyte)((aluF2S(DryBuffer[i][FRONT_RIGHT]+WetBuffer[i][FRONT_RIGHT])>>8)+128);
1019 ((ALubyte*)buffer)[2] = (ALubyte)((aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT])>>8)+128);
1020 ((ALubyte*)buffer)[3] = (ALubyte)((aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT])>>8)+128);
1021 ((ALubyte*)buffer)[4] = (ALubyte)((aluF2S(DryBuffer[i][CENTER] +WetBuffer[i][CENTER])>>8)+128);
1022 ((ALubyte*)buffer)[5] = (ALubyte)((aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE])>>8)+128);
1023 buffer = ((ALubyte*)buffer) + 6;
1025 break;
1026 case AL_FORMAT_61CHN8:
1027 for(i = 0;i < SamplesToDo;i++)
1029 ((ALubyte*)buffer)[0] = (ALubyte)((aluF2S(DryBuffer[i][FRONT_LEFT] +WetBuffer[i][FRONT_LEFT])>>8)+128);
1030 ((ALubyte*)buffer)[1] = (ALubyte)((aluF2S(DryBuffer[i][FRONT_RIGHT]+WetBuffer[i][FRONT_RIGHT])>>8)+128);
1031 ((ALubyte*)buffer)[2] = (ALubyte)((aluF2S(DryBuffer[i][SIDE_LEFT] +WetBuffer[i][SIDE_LEFT])>>8)+128);
1032 ((ALubyte*)buffer)[3] = (ALubyte)((aluF2S(DryBuffer[i][SIDE_RIGHT] +WetBuffer[i][SIDE_RIGHT])>>8)+128);
1033 ((ALubyte*)buffer)[4] = (ALubyte)((aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT])>>8)+128);
1034 ((ALubyte*)buffer)[5] = (ALubyte)((aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT])>>8)+128);
1035 ((ALubyte*)buffer)[6] = (ALubyte)((aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE])>>8)+128);
1036 buffer = ((ALubyte*)buffer) + 7;
1038 break;
1039 case AL_FORMAT_71CHN8:
1040 for(i = 0;i < SamplesToDo;i++)
1042 ((ALubyte*)buffer)[0] = (ALubyte)((aluF2S(DryBuffer[i][FRONT_LEFT] +WetBuffer[i][FRONT_LEFT])>>8)+128);
1043 ((ALubyte*)buffer)[1] = (ALubyte)((aluF2S(DryBuffer[i][FRONT_RIGHT]+WetBuffer[i][FRONT_RIGHT])>>8)+128);
1044 ((ALubyte*)buffer)[2] = (ALubyte)((aluF2S(DryBuffer[i][SIDE_LEFT] +WetBuffer[i][SIDE_LEFT])>>8)+128);
1045 ((ALubyte*)buffer)[3] = (ALubyte)((aluF2S(DryBuffer[i][SIDE_RIGHT] +WetBuffer[i][SIDE_RIGHT])>>8)+128);
1046 ((ALubyte*)buffer)[4] = (ALubyte)((aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT])>>8)+128);
1047 ((ALubyte*)buffer)[5] = (ALubyte)((aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT])>>8)+128);
1048 ((ALubyte*)buffer)[6] = (ALubyte)((aluF2S(DryBuffer[i][CENTER] +WetBuffer[i][CENTER])>>8)+128);
1049 ((ALubyte*)buffer)[7] = (ALubyte)((aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE])>>8)+128);
1050 buffer = ((ALubyte*)buffer) + 8;
1052 break;
1054 case AL_FORMAT_MONO16:
1055 for(i = 0;i < SamplesToDo;i++)
1057 ((ALshort*)buffer)[0] = aluF2S(DryBuffer[i][FRONT_LEFT]+DryBuffer[i][FRONT_RIGHT]+
1058 WetBuffer[i][FRONT_LEFT]+WetBuffer[i][FRONT_RIGHT]);
1059 buffer = ((ALshort*)buffer) + 1;
1061 break;
1062 case AL_FORMAT_STEREO16:
1063 if(ALContext && ALContext->bs2b)
1065 for(i = 0;i < SamplesToDo;i++)
1067 float samples[2];
1068 samples[0] = DryBuffer[i][FRONT_LEFT] +WetBuffer[i][FRONT_LEFT];
1069 samples[1] = DryBuffer[i][FRONT_RIGHT]+WetBuffer[i][FRONT_RIGHT];
1070 bs2b_cross_feed(ALContext->bs2b, samples);
1071 ((ALshort*)buffer)[0] = aluF2S(samples[0]);
1072 ((ALshort*)buffer)[1] = aluF2S(samples[1]);
1073 buffer = ((ALshort*)buffer) + 2;
1076 else
1078 for(i = 0;i < SamplesToDo;i++)
1080 ((ALshort*)buffer)[0] = aluF2S(DryBuffer[i][FRONT_LEFT] +WetBuffer[i][FRONT_LEFT]);
1081 ((ALshort*)buffer)[1] = aluF2S(DryBuffer[i][FRONT_RIGHT]+WetBuffer[i][FRONT_RIGHT]);
1082 buffer = ((ALshort*)buffer) + 2;
1085 break;
1086 case AL_FORMAT_QUAD16:
1087 for(i = 0;i < SamplesToDo;i++)
1089 ((ALshort*)buffer)[0] = aluF2S(DryBuffer[i][FRONT_LEFT] +WetBuffer[i][FRONT_LEFT]);
1090 ((ALshort*)buffer)[1] = aluF2S(DryBuffer[i][FRONT_RIGHT]+WetBuffer[i][FRONT_RIGHT]);
1091 ((ALshort*)buffer)[2] = aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT]);
1092 ((ALshort*)buffer)[3] = aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT]);
1093 buffer = ((ALshort*)buffer) + 4;
1095 break;
1096 case AL_FORMAT_51CHN16:
1097 for(i = 0;i < SamplesToDo;i++)
1099 ((ALshort*)buffer)[0] = aluF2S(DryBuffer[i][FRONT_LEFT] +WetBuffer[i][FRONT_LEFT]);
1100 ((ALshort*)buffer)[1] = aluF2S(DryBuffer[i][FRONT_RIGHT]+WetBuffer[i][FRONT_RIGHT]);
1101 ((ALshort*)buffer)[2] = aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT]);
1102 ((ALshort*)buffer)[3] = aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT]);
1103 ((ALshort*)buffer)[4] = aluF2S(DryBuffer[i][CENTER] +WetBuffer[i][CENTER]);
1104 ((ALshort*)buffer)[5] = aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE]);
1105 buffer = ((ALshort*)buffer) + 6;
1107 break;
1108 case AL_FORMAT_61CHN16:
1109 for(i = 0;i < SamplesToDo;i++)
1111 ((ALshort*)buffer)[0] = aluF2S(DryBuffer[i][FRONT_LEFT] +WetBuffer[i][FRONT_LEFT]);
1112 ((ALshort*)buffer)[1] = aluF2S(DryBuffer[i][FRONT_RIGHT]+WetBuffer[i][FRONT_RIGHT]);
1113 ((ALshort*)buffer)[2] = aluF2S(DryBuffer[i][SIDE_LEFT] +WetBuffer[i][SIDE_LEFT]);
1114 ((ALshort*)buffer)[3] = aluF2S(DryBuffer[i][SIDE_RIGHT] +WetBuffer[i][SIDE_RIGHT]);
1115 ((ALshort*)buffer)[4] = aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT]);
1116 ((ALshort*)buffer)[5] = aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT]);
1117 ((ALshort*)buffer)[6] = aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE]);
1118 buffer = ((ALshort*)buffer) + 7;
1120 break;
1121 case AL_FORMAT_71CHN16:
1122 for(i = 0;i < SamplesToDo;i++)
1124 ((ALshort*)buffer)[0] = aluF2S(DryBuffer[i][FRONT_LEFT] +WetBuffer[i][FRONT_LEFT]);
1125 ((ALshort*)buffer)[1] = aluF2S(DryBuffer[i][FRONT_RIGHT]+WetBuffer[i][FRONT_RIGHT]);
1126 ((ALshort*)buffer)[2] = aluF2S(DryBuffer[i][SIDE_LEFT] +WetBuffer[i][SIDE_LEFT]);
1127 ((ALshort*)buffer)[3] = aluF2S(DryBuffer[i][SIDE_RIGHT] +WetBuffer[i][SIDE_RIGHT]);
1128 ((ALshort*)buffer)[4] = aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT]);
1129 ((ALshort*)buffer)[5] = aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT]);
1130 ((ALshort*)buffer)[6] = aluF2S(DryBuffer[i][CENTER] +WetBuffer[i][CENTER]);
1131 ((ALshort*)buffer)[7] = aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE]);
1132 buffer = ((ALshort*)buffer) + 8;
1134 break;
1136 default:
1137 break;
1140 size -= SamplesToDo;
1144 ProcessContext(ALContext);