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
32 #include "alListener.h"
33 #include "alAuxEffectSlot.h"
36 #if defined(HAVE_STDINT_H)
38 typedef int64_t ALint64
;
39 #elif defined(HAVE___INT64)
40 typedef __int64 ALint64
;
41 #elif (SIZEOF_LONG == 8)
43 #elif (SIZEOF_LONG_LONG == 8)
44 typedef long long ALint64
;
48 #define aluSqrt(x) ((ALfloat)sqrtf((float)(x)))
50 #define aluSqrt(x) ((ALfloat)sqrt((double)(x)))
54 #define aluAcos(x) ((ALfloat)acosf((float)(x)))
56 #define aluAcos(x) ((ALfloat)acos((double)(x)))
60 #if defined(max) && !defined(__max)
63 #if defined(min) && !defined(__min)
67 #define BUFFERSIZE 48000
68 #define FRACTIONBITS 14
69 #define FRACTIONMASK ((1L<<FRACTIONBITS)-1)
85 ALboolean DuplicateStereo
= AL_FALSE
;
87 /* NOTE: The AL_FORMAT_REAR* enums aren't handled here be cause they're
88 * converted to AL_FORMAT_QUAD* when loaded */
89 __inline ALuint
aluBytesFromFormat(ALenum format
)
94 case AL_FORMAT_STEREO8
:
95 case AL_FORMAT_QUAD8_LOKI
:
97 case AL_FORMAT_51CHN8
:
98 case AL_FORMAT_61CHN8
:
99 case AL_FORMAT_71CHN8
:
102 case AL_FORMAT_MONO16
:
103 case AL_FORMAT_STEREO16
:
104 case AL_FORMAT_QUAD16_LOKI
:
105 case AL_FORMAT_QUAD16
:
106 case AL_FORMAT_51CHN16
:
107 case AL_FORMAT_61CHN16
:
108 case AL_FORMAT_71CHN16
:
111 case AL_FORMAT_MONO_FLOAT32
:
112 case AL_FORMAT_STEREO_FLOAT32
:
113 case AL_FORMAT_QUAD32
:
114 case AL_FORMAT_51CHN32
:
115 case AL_FORMAT_61CHN32
:
116 case AL_FORMAT_71CHN32
:
124 __inline ALuint
aluChannelsFromFormat(ALenum format
)
128 case AL_FORMAT_MONO8
:
129 case AL_FORMAT_MONO16
:
130 case AL_FORMAT_MONO_FLOAT32
:
133 case AL_FORMAT_STEREO8
:
134 case AL_FORMAT_STEREO16
:
135 case AL_FORMAT_STEREO_FLOAT32
:
138 case AL_FORMAT_QUAD8_LOKI
:
139 case AL_FORMAT_QUAD16_LOKI
:
140 case AL_FORMAT_QUAD8
:
141 case AL_FORMAT_QUAD16
:
142 case AL_FORMAT_QUAD32
:
145 case AL_FORMAT_51CHN8
:
146 case AL_FORMAT_51CHN16
:
147 case AL_FORMAT_51CHN32
:
150 case AL_FORMAT_61CHN8
:
151 case AL_FORMAT_61CHN16
:
152 case AL_FORMAT_61CHN32
:
155 case AL_FORMAT_71CHN8
:
156 case AL_FORMAT_71CHN16
:
157 case AL_FORMAT_71CHN32
:
165 static __inline ALint
aluF2L(ALfloat Value
)
168 if(sizeof(ALint
) == 4 && sizeof(double) == 8)
171 temp
= Value
+ (((65536.0*65536.0*16.0)+(65536.0*65536.0*8.0))*65536.0);
172 return *((ALint
*)&temp
);
178 static __inline ALshort
aluF2S(ALfloat Value
)
183 i
= __min( 32767, i
);
184 i
= __max(-32768, i
);
188 static __inline ALvoid
aluCrossproduct(ALfloat
*inVector1
,ALfloat
*inVector2
,ALfloat
*outVector
)
190 outVector
[0] = inVector1
[1]*inVector2
[2] - inVector1
[2]*inVector2
[1];
191 outVector
[1] = inVector1
[2]*inVector2
[0] - inVector1
[0]*inVector2
[2];
192 outVector
[2] = inVector1
[0]*inVector2
[1] - inVector1
[1]*inVector2
[0];
195 static __inline ALfloat
aluDotproduct(ALfloat
*inVector1
,ALfloat
*inVector2
)
197 return inVector1
[0]*inVector2
[0] + inVector1
[1]*inVector2
[1] +
198 inVector1
[2]*inVector2
[2];
201 static __inline ALvoid
aluNormalize(ALfloat
*inVector
)
203 ALfloat length
, inverse_length
;
205 length
= (ALfloat
)aluSqrt(aluDotproduct(inVector
, inVector
));
208 inverse_length
= 1.0f
/length
;
209 inVector
[0] *= inverse_length
;
210 inVector
[1] *= inverse_length
;
211 inVector
[2] *= inverse_length
;
215 static __inline ALvoid
aluMatrixVector(ALfloat
*vector
,ALfloat matrix
[3][3])
219 result
[0] = vector
[0]*matrix
[0][0] + vector
[1]*matrix
[1][0] + vector
[2]*matrix
[2][0];
220 result
[1] = vector
[0]*matrix
[0][1] + vector
[1]*matrix
[1][1] + vector
[2]*matrix
[2][1];
221 result
[2] = vector
[0]*matrix
[0][2] + vector
[1]*matrix
[1][2] + vector
[2]*matrix
[2][2];
222 memcpy(vector
, result
, sizeof(result
));
225 static __inline ALfloat
aluComputeSample(ALfloat GainHF
, ALfloat sample
, ALfloat LastSample
)
232 sample
+= LastSample
* (1.0f
-GainHF
);
241 static ALvoid
CalcSourceParams(ALCcontext
*ALContext
, ALsource
*ALSource
,
242 ALenum isMono
, ALenum OutputFormat
,
243 ALfloat
*drysend
, ALfloat
*wetsend
,
244 ALfloat
*pitch
, ALfloat
*drygainhf
,
247 ALfloat InnerAngle
,OuterAngle
,Angle
,Distance
,DryMix
,WetMix
=0.0f
;
248 ALfloat Direction
[3],Position
[3],SourceToListener
[3];
249 ALfloat MinVolume
,MaxVolume
,MinDist
,MaxDist
,Rolloff
,OuterGainHF
;
250 ALfloat ConeVolume
,SourceVolume
,PanningFB
,PanningLR
,ListenerGain
;
251 ALfloat U
[3],V
[3],N
[3];
252 ALfloat DopplerFactor
, DopplerVelocity
, flSpeedOfSound
, flMaxVelocity
;
253 ALfloat Matrix
[3][3];
254 ALfloat flAttenuation
;
255 ALfloat RoomAttenuation
;
256 ALfloat MetersPerUnit
;
258 ALfloat DryGainHF
= 1.0f
;
259 ALfloat WetGainHF
= 1.0f
;
261 //Get context properties
262 DopplerFactor
= ALContext
->DopplerFactor
;
263 DopplerVelocity
= ALContext
->DopplerVelocity
;
264 flSpeedOfSound
= ALContext
->flSpeedOfSound
;
266 //Get listener properties
267 ListenerGain
= ALContext
->Listener
.Gain
;
268 MetersPerUnit
= ALContext
->Listener
.MetersPerUnit
;
270 //Get source properties
271 SourceVolume
= ALSource
->flGain
;
272 memcpy(Position
, ALSource
->vPosition
, sizeof(ALSource
->vPosition
));
273 memcpy(Direction
, ALSource
->vOrientation
, sizeof(ALSource
->vOrientation
));
274 MinVolume
= ALSource
->flMinGain
;
275 MaxVolume
= ALSource
->flMaxGain
;
276 MinDist
= ALSource
->flRefDistance
;
277 MaxDist
= ALSource
->flMaxDistance
;
278 Rolloff
= ALSource
->flRollOffFactor
;
279 InnerAngle
= ALSource
->flInnerAngle
;
280 OuterAngle
= ALSource
->flOuterAngle
;
281 OuterGainHF
= ALSource
->OuterGainHF
;
282 RoomRolloff
= ALSource
->RoomRolloffFactor
;
284 //Only apply 3D calculations for mono buffers
285 if(isMono
!= AL_FALSE
)
287 //1. Translate Listener to origin (convert to head relative)
288 if(ALSource
->bHeadRelative
==AL_FALSE
)
290 Position
[0] -= ALContext
->Listener
.Position
[0];
291 Position
[1] -= ALContext
->Listener
.Position
[1];
292 Position
[2] -= ALContext
->Listener
.Position
[2];
295 //2. Calculate distance attenuation
296 Distance
= aluSqrt(aluDotproduct(Position
, Position
));
298 if(ALSource
->Send
[0].Slot
&& !ALSource
->Send
[0].Slot
->AuxSendAuto
)
300 if(ALSource
->Send
[0].Slot
->effect
.type
== AL_EFFECT_REVERB
)
301 RoomRolloff
= ALSource
->Send
[0].Slot
->effect
.Reverb
.RoomRolloffFactor
;
304 flAttenuation
= 1.0f
;
305 RoomAttenuation
= 1.0f
;
306 switch (ALContext
->DistanceModel
)
308 case AL_INVERSE_DISTANCE_CLAMPED
:
309 Distance
=__max(Distance
,MinDist
);
310 Distance
=__min(Distance
,MaxDist
);
311 if (MaxDist
< MinDist
)
314 case AL_INVERSE_DISTANCE
:
317 if ((MinDist
+ (Rolloff
* (Distance
- MinDist
))) > 0.0f
)
318 flAttenuation
= MinDist
/ (MinDist
+ (Rolloff
* (Distance
- MinDist
)));
319 if ((MinDist
+ (RoomRolloff
* (Distance
- MinDist
))) > 0.0f
)
320 RoomAttenuation
= MinDist
/ (MinDist
+ (RoomRolloff
* (Distance
- MinDist
)));
324 case AL_LINEAR_DISTANCE_CLAMPED
:
325 Distance
=__max(Distance
,MinDist
);
326 Distance
=__min(Distance
,MaxDist
);
327 if (MaxDist
< MinDist
)
330 case AL_LINEAR_DISTANCE
:
331 Distance
=__min(Distance
,MaxDist
);
332 if (MaxDist
!= MinDist
)
334 flAttenuation
= 1.0f
- (Rolloff
*(Distance
-MinDist
)/(MaxDist
- MinDist
));
335 RoomAttenuation
= 1.0f
- (RoomRolloff
*(Distance
-MinDist
)/(MaxDist
- MinDist
));
339 case AL_EXPONENT_DISTANCE_CLAMPED
:
340 Distance
=__max(Distance
,MinDist
);
341 Distance
=__min(Distance
,MaxDist
);
342 if (MaxDist
< MinDist
)
345 case AL_EXPONENT_DISTANCE
:
346 if ((Distance
> 0.0f
) && (MinDist
> 0.0f
))
348 flAttenuation
= (ALfloat
)pow(Distance
/MinDist
, -Rolloff
);
349 RoomAttenuation
= (ALfloat
)pow(Distance
/MinDist
, -RoomRolloff
);
355 flAttenuation
= 1.0f
;
356 RoomAttenuation
= 1.0f
;
360 // Source Gain + Attenuation and clamp to Min/Max Gain
361 DryMix
= SourceVolume
* flAttenuation
;
362 DryMix
= __min(DryMix
,MaxVolume
);
363 DryMix
= __max(DryMix
,MinVolume
);
365 WetMix
= SourceVolume
* (ALSource
->WetGainAuto
?
366 RoomAttenuation
: 1.0f
);
367 WetMix
= __min(WetMix
,MaxVolume
);
368 WetMix
= __max(WetMix
,MinVolume
);
370 //3. Apply directional soundcones
371 SourceToListener
[0] = -Position
[0];
372 SourceToListener
[1] = -Position
[1];
373 SourceToListener
[2] = -Position
[2];
374 aluNormalize(Direction
);
375 aluNormalize(SourceToListener
);
376 Angle
= aluAcos(aluDotproduct(Direction
,SourceToListener
)) * 180.0f
/
378 if(Angle
>= InnerAngle
&& Angle
<= OuterAngle
)
380 ALfloat scale
= (Angle
-InnerAngle
) / (OuterAngle
-InnerAngle
);
381 ConeVolume
= (1.0f
+(ALSource
->flOuterGain
-1.0f
)*scale
);
382 if(ALSource
->WetGainAuto
)
383 WetMix
*= ConeVolume
;
384 if(ALSource
->DryGainHFAuto
)
385 DryGainHF
*= (1.0f
+(OuterGainHF
-1.0f
)*scale
);
386 if(ALSource
->WetGainHFAuto
)
387 WetGainHF
*= (1.0f
+(OuterGainHF
-1.0f
)*scale
);
389 else if(Angle
> OuterAngle
)
391 ConeVolume
= (1.0f
+(ALSource
->flOuterGain
-1.0f
));
392 if(ALSource
->WetGainAuto
)
393 WetMix
*= ConeVolume
;
394 if(ALSource
->DryGainHFAuto
)
395 DryGainHF
*= (1.0f
+(OuterGainHF
-1.0f
));
396 if(ALSource
->WetGainHFAuto
)
397 WetGainHF
*= (1.0f
+(OuterGainHF
-1.0f
));
402 //4. Calculate Velocity
403 if(DopplerFactor
!= 0.0f
)
405 ALfloat flVSS
, flVLS
;
407 flVLS
= aluDotproduct(ALContext
->Listener
.Velocity
,
409 flVSS
= aluDotproduct(ALSource
->vVelocity
, SourceToListener
);
411 flMaxVelocity
= (DopplerVelocity
* flSpeedOfSound
) / DopplerFactor
;
413 if (flVSS
>= flMaxVelocity
)
414 flVSS
= (flMaxVelocity
- 1.0f
);
415 else if (flVSS
<= -flMaxVelocity
)
416 flVSS
= -flMaxVelocity
+ 1.0f
;
418 if (flVLS
>= flMaxVelocity
)
419 flVLS
= (flMaxVelocity
- 1.0f
);
420 else if (flVLS
<= -flMaxVelocity
)
421 flVLS
= -flMaxVelocity
+ 1.0f
;
423 pitch
[0] = ALSource
->flPitch
*
424 ((flSpeedOfSound
* DopplerVelocity
) - (DopplerFactor
* flVLS
)) /
425 ((flSpeedOfSound
* DopplerVelocity
) - (DopplerFactor
* flVSS
));
428 pitch
[0] = ALSource
->flPitch
;
430 //5. Align coordinate system axes
431 aluCrossproduct(ALContext
->Listener
.Forward
, ALContext
->Listener
.Up
, U
); // Right-vector
432 aluNormalize(U
); // Normalized Right-vector
433 memcpy(V
, ALContext
->Listener
.Up
, sizeof(V
)); // Up-vector
434 aluNormalize(V
); // Normalized Up-vector
435 memcpy(N
, ALContext
->Listener
.Forward
, sizeof(N
)); // At-vector
436 aluNormalize(N
); // Normalized At-vector
437 Matrix
[0][0] = U
[0]; Matrix
[0][1] = V
[0]; Matrix
[0][2] = -N
[0];
438 Matrix
[1][0] = U
[1]; Matrix
[1][1] = V
[1]; Matrix
[1][2] = -N
[1];
439 Matrix
[2][0] = U
[2]; Matrix
[2][1] = V
[2]; Matrix
[2][2] = -N
[2];
440 aluMatrixVector(Position
, Matrix
);
442 //6. Apply filter gains and filters
443 switch(ALSource
->DirectFilter
.filter
)
445 case AL_FILTER_LOWPASS
:
446 DryMix
*= ALSource
->DirectFilter
.Gain
;
447 DryGainHF
*= ALSource
->DirectFilter
.GainHF
;
451 switch(ALSource
->Send
[0].WetFilter
.filter
)
453 case AL_FILTER_LOWPASS
:
454 WetMix
*= ALSource
->Send
[0].WetFilter
.Gain
;
455 WetGainHF
*= ALSource
->Send
[0].WetFilter
.GainHF
;
459 if(ALSource
->AirAbsorptionFactor
> 0.0f
)
460 DryGainHF
*= pow(ALSource
->AirAbsorptionFactor
* AIRABSORBGAINHF
,
461 Distance
* MetersPerUnit
);
463 if(ALSource
->Send
[0].Slot
)
465 WetMix
*= ALSource
->Send
[0].Slot
->Gain
;
467 if(ALSource
->Send
[0].Slot
->effect
.type
== AL_EFFECT_REVERB
)
469 WetGainHF
*= ALSource
->Send
[0].Slot
->effect
.Reverb
.GainHF
;
470 WetGainHF
*= pow(ALSource
->Send
[0].Slot
->effect
.Reverb
.AirAbsorptionGainHF
,
471 Distance
* MetersPerUnit
);
480 DryMix
*= ListenerGain
* ConeVolume
;
481 WetMix
*= ListenerGain
;
483 //7. Convert normalized position into pannings, then into channel volumes
484 aluNormalize(Position
);
485 switch(aluChannelsFromFormat(OutputFormat
))
488 drysend
[FRONT_LEFT
] = DryMix
* aluSqrt(1.0f
); //Direct
489 drysend
[FRONT_RIGHT
] = DryMix
* aluSqrt(1.0f
); //Direct
490 wetsend
[FRONT_LEFT
] = WetMix
* aluSqrt(1.0f
); //Room
491 wetsend
[FRONT_RIGHT
] = WetMix
* aluSqrt(1.0f
); //Room
494 PanningLR
= 0.5f
+ 0.5f
*Position
[0];
495 drysend
[FRONT_LEFT
] = DryMix
* aluSqrt(1.0f
-PanningLR
); //L Direct
496 drysend
[FRONT_RIGHT
] = DryMix
* aluSqrt( PanningLR
); //R Direct
497 wetsend
[FRONT_LEFT
] = WetMix
* aluSqrt(1.0f
-PanningLR
); //L Room
498 wetsend
[FRONT_RIGHT
] = WetMix
* aluSqrt( PanningLR
); //R Room
501 /* TODO: Add center/lfe channel in spatial calculations? */
503 // Apply a scalar so each individual speaker has more weight
504 PanningLR
= 0.5f
+ (0.5f
*Position
[0]*1.41421356f
);
505 PanningLR
= __min(1.0f
, PanningLR
);
506 PanningLR
= __max(0.0f
, PanningLR
);
507 PanningFB
= 0.5f
+ (0.5f
*Position
[2]*1.41421356f
);
508 PanningFB
= __min(1.0f
, PanningFB
);
509 PanningFB
= __max(0.0f
, PanningFB
);
510 drysend
[FRONT_LEFT
] = DryMix
* aluSqrt((1.0f
-PanningLR
)*(1.0f
-PanningFB
));
511 drysend
[FRONT_RIGHT
] = DryMix
* aluSqrt(( PanningLR
)*(1.0f
-PanningFB
));
512 drysend
[BACK_LEFT
] = DryMix
* aluSqrt((1.0f
-PanningLR
)*( PanningFB
));
513 drysend
[BACK_RIGHT
] = DryMix
* aluSqrt(( PanningLR
)*( PanningFB
));
514 wetsend
[FRONT_LEFT
] = WetMix
* aluSqrt((1.0f
-PanningLR
)*(1.0f
-PanningFB
));
515 wetsend
[FRONT_RIGHT
] = WetMix
* aluSqrt(( PanningLR
)*(1.0f
-PanningFB
));
516 wetsend
[BACK_LEFT
] = WetMix
* aluSqrt((1.0f
-PanningLR
)*( PanningFB
));
517 wetsend
[BACK_RIGHT
] = WetMix
* aluSqrt(( PanningLR
)*( PanningFB
));
521 PanningFB
= 1.0f
- fabs(Position
[2]*1.15470054f
);
522 PanningFB
= __min(1.0f
, PanningFB
);
523 PanningFB
= __max(0.0f
, PanningFB
);
524 PanningLR
= 0.5f
+ (0.5*Position
[0]*((1.0f
-PanningFB
)*2.0f
));
525 PanningLR
= __min(1.0f
, PanningLR
);
526 PanningLR
= __max(0.0f
, PanningLR
);
527 if(Position
[2] > 0.0f
)
529 drysend
[BACK_LEFT
] = DryMix
* aluSqrt((1.0f
-PanningLR
)*(1.0f
-PanningFB
));
530 drysend
[BACK_RIGHT
] = DryMix
* aluSqrt(( PanningLR
)*(1.0f
-PanningFB
));
531 drysend
[SIDE_LEFT
] = DryMix
* aluSqrt((1.0f
-PanningLR
)*( PanningFB
));
532 drysend
[SIDE_RIGHT
] = DryMix
* aluSqrt(( PanningLR
)*( PanningFB
));
533 drysend
[FRONT_LEFT
] = 0.0f
;
534 drysend
[FRONT_RIGHT
] = 0.0f
;
535 wetsend
[BACK_LEFT
] = WetMix
* aluSqrt((1.0f
-PanningLR
)*(1.0f
-PanningFB
));
536 wetsend
[BACK_RIGHT
] = WetMix
* aluSqrt(( PanningLR
)*(1.0f
-PanningFB
));
537 wetsend
[SIDE_LEFT
] = WetMix
* aluSqrt((1.0f
-PanningLR
)*( PanningFB
));
538 wetsend
[SIDE_RIGHT
] = WetMix
* aluSqrt(( PanningLR
)*( PanningFB
));
539 wetsend
[FRONT_LEFT
] = 0.0f
;
540 wetsend
[FRONT_RIGHT
] = 0.0f
;
544 drysend
[FRONT_LEFT
] = DryMix
* aluSqrt((1.0f
-PanningLR
)*(1.0f
-PanningFB
));
545 drysend
[FRONT_RIGHT
] = DryMix
* aluSqrt(( PanningLR
)*(1.0f
-PanningFB
));
546 drysend
[SIDE_LEFT
] = DryMix
* aluSqrt((1.0f
-PanningLR
)*( PanningFB
));
547 drysend
[SIDE_RIGHT
] = DryMix
* aluSqrt(( PanningLR
)*( PanningFB
));
548 drysend
[BACK_LEFT
] = 0.0f
;
549 drysend
[BACK_RIGHT
] = 0.0f
;
550 wetsend
[FRONT_LEFT
] = WetMix
* aluSqrt((1.0f
-PanningLR
)*(1.0f
-PanningFB
));
551 wetsend
[FRONT_RIGHT
] = WetMix
* aluSqrt(( PanningLR
)*(1.0f
-PanningFB
));
552 wetsend
[SIDE_LEFT
] = WetMix
* aluSqrt((1.0f
-PanningLR
)*( PanningFB
));
553 wetsend
[SIDE_RIGHT
] = WetMix
* aluSqrt(( PanningLR
)*( PanningFB
));
554 wetsend
[BACK_LEFT
] = 0.0f
;
555 wetsend
[BACK_RIGHT
] = 0.0f
;
561 *drygainhf
= DryGainHF
;
562 *wetgainhf
= WetGainHF
;
566 //1. Multi-channel buffers always play "normal"
567 pitch
[0] = ALSource
->flPitch
;
569 drysend
[FRONT_LEFT
] = SourceVolume
* ListenerGain
;
570 drysend
[FRONT_RIGHT
] = SourceVolume
* ListenerGain
;
571 drysend
[SIDE_LEFT
] = SourceVolume
* ListenerGain
;
572 drysend
[SIDE_RIGHT
] = SourceVolume
* ListenerGain
;
573 drysend
[BACK_LEFT
] = SourceVolume
* ListenerGain
;
574 drysend
[BACK_RIGHT
] = SourceVolume
* ListenerGain
;
575 drysend
[CENTER
] = SourceVolume
* ListenerGain
;
576 drysend
[LFE
] = SourceVolume
* ListenerGain
;
577 wetsend
[FRONT_LEFT
] = 0.0f
;
578 wetsend
[FRONT_RIGHT
] = 0.0f
;
579 wetsend
[SIDE_LEFT
] = 0.0f
;
580 wetsend
[SIDE_RIGHT
] = 0.0f
;
581 wetsend
[BACK_LEFT
] = 0.0f
;
582 wetsend
[BACK_RIGHT
] = 0.0f
;
583 wetsend
[CENTER
] = 0.0f
;
587 *drygainhf
= DryGainHF
;
588 *wetgainhf
= WetGainHF
;
592 ALvoid
aluMixData(ALCcontext
*ALContext
,ALvoid
*buffer
,ALsizei size
,ALenum format
)
594 static float DryBuffer
[BUFFERSIZE
][OUTPUTCHANNELS
];
595 static float WetBuffer
[BUFFERSIZE
][OUTPUTCHANNELS
];
596 static float ReverbBuffer
[BUFFERSIZE
];
597 ALfloat DrySend
[OUTPUTCHANNELS
] = { 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
};
598 ALfloat WetSend
[OUTPUTCHANNELS
] = { 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
};
599 ALfloat DryGainHF
= 0.0f
;
600 ALfloat WetGainHF
= 0.0f
;
601 ALuint BlockAlign
,BufferSize
;
602 ALuint DataSize
=0,DataPosInt
=0,DataPosFrac
=0;
603 ALuint Channels
,Frequency
,ulExtraSamples
;
604 ALfloat DrySample
, WetSample
;
607 ALint Looping
,increment
,State
;
608 ALuint Buffer
,fraction
;
612 ALeffectslot
*ALEffectSlot
;
616 ALbufferlistitem
*BufferListItem
;
618 ALint64 DataSize64
,DataPos64
;
620 SuspendContext(ALContext
);
622 //Figure output format variables
623 BlockAlign
= aluChannelsFromFormat(format
);
624 BlockAlign
*= aluBytesFromFormat(format
);
630 ALEffectSlot
= (ALContext
? ALContext
->AuxiliaryEffectSlot
: NULL
);
631 ALSource
= (ALContext
? ALContext
->Source
: NULL
);
632 SamplesToDo
= min(size
, BUFFERSIZE
);
634 //Clear mixing buffer
635 memset(DryBuffer
, 0, SamplesToDo
*OUTPUTCHANNELS
*sizeof(ALfloat
));
636 memset(WetBuffer
, 0, SamplesToDo
*OUTPUTCHANNELS
*sizeof(ALfloat
));
637 memset(ReverbBuffer
, 0, SamplesToDo
*sizeof(ALfloat
));
643 State
= ALSource
->state
;
645 doReverb
= ((ALSource
->Send
[0].Slot
&&
646 ALSource
->Send
[0].Slot
->effect
.type
== AL_EFFECT_REVERB
) ?
649 while(State
== AL_PLAYING
&& j
< SamplesToDo
)
656 if((Buffer
= ALSource
->ulBufferID
))
658 ALBuffer
= (ALbuffer
*)ALTHUNK_LOOKUPENTRY(Buffer
);
660 Data
= ALBuffer
->data
;
661 Channels
= aluChannelsFromFormat(ALBuffer
->format
);
662 DataSize
= ALBuffer
->size
;
663 Frequency
= ALBuffer
->frequency
;
665 CalcSourceParams(ALContext
, ALSource
,
666 (Channels
==1) ? AL_TRUE
: AL_FALSE
,
667 format
, DrySend
, WetSend
, &Pitch
,
668 &DryGainHF
, &WetGainHF
);
671 Pitch
= (Pitch
*Frequency
) / ALContext
->Frequency
;
672 DataSize
/= Channels
* aluBytesFromFormat(ALBuffer
->format
);
675 DataPosInt
= ALSource
->position
;
676 DataPosFrac
= ALSource
->position_fraction
;
677 DrySample
= ALSource
->LastDrySample
;
678 WetSample
= ALSource
->LastWetSample
;
680 //Compute 18.14 fixed point step
681 increment
= aluF2L(Pitch
*(1L<<FRACTIONBITS
));
682 if(increment
> (MAX_PITCH
<<FRACTIONBITS
))
683 increment
= (MAX_PITCH
<<FRACTIONBITS
);
685 //Figure out how many samples we can mix.
686 //Pitch must be <= 4 (the number below !)
687 DataSize64
= DataSize
+MAX_PITCH
;
688 DataSize64
<<= FRACTIONBITS
;
689 DataPos64
= DataPosInt
;
690 DataPos64
<<= FRACTIONBITS
;
691 DataPos64
+= DataPosFrac
;
692 BufferSize
= (ALuint
)((DataSize64
-DataPos64
) / increment
);
693 BufferListItem
= ALSource
->queue
;
694 for(loop
= 0; loop
< ALSource
->BuffersPlayed
; loop
++)
697 BufferListItem
= BufferListItem
->next
;
701 if (BufferListItem
->next
)
703 ALbuffer
*NextBuf
= (ALbuffer
*)ALTHUNK_LOOKUPENTRY(BufferListItem
->next
->buffer
);
704 if(NextBuf
&& NextBuf
->data
)
706 ulExtraSamples
= min(NextBuf
->size
, (ALint
)(16*Channels
));
707 memcpy(&Data
[DataSize
*Channels
], NextBuf
->data
, ulExtraSamples
);
710 else if (ALSource
->bLooping
)
712 ALbuffer
*NextBuf
= (ALbuffer
*)ALTHUNK_LOOKUPENTRY(ALSource
->queue
->buffer
);
713 if (NextBuf
&& NextBuf
->data
)
715 ulExtraSamples
= min(NextBuf
->size
, (ALint
)(16*Channels
));
716 memcpy(&Data
[DataSize
*Channels
], NextBuf
->data
, ulExtraSamples
);
720 BufferSize
= min(BufferSize
, (SamplesToDo
-j
));
722 //Actual sample mixing loop
723 Data
+= DataPosInt
*Channels
;
726 k
= DataPosFrac
>>FRACTIONBITS
;
727 fraction
= DataPosFrac
&FRACTIONMASK
;
730 //First order interpolator
731 ALfloat sample
= (ALfloat
)((ALshort
)(((Data
[k
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[k
+1]*(fraction
)))>>FRACTIONBITS
));
733 //Direct path final mix buffer and panning
734 DrySample
= aluComputeSample(DryGainHF
, sample
, DrySample
);
735 DryBuffer
[j
][FRONT_LEFT
] += DrySample
*DrySend
[FRONT_LEFT
];
736 DryBuffer
[j
][FRONT_RIGHT
] += DrySample
*DrySend
[FRONT_RIGHT
];
737 DryBuffer
[j
][SIDE_LEFT
] += DrySample
*DrySend
[SIDE_LEFT
];
738 DryBuffer
[j
][SIDE_RIGHT
] += DrySample
*DrySend
[SIDE_RIGHT
];
739 DryBuffer
[j
][BACK_LEFT
] += DrySample
*DrySend
[BACK_LEFT
];
740 DryBuffer
[j
][BACK_RIGHT
] += DrySample
*DrySend
[BACK_RIGHT
];
741 //Room path final mix buffer and panning
742 WetSample
= aluComputeSample(WetGainHF
, sample
, WetSample
);
744 ReverbBuffer
[j
] += WetSample
;
747 WetBuffer
[j
][FRONT_LEFT
] += WetSample
*WetSend
[FRONT_LEFT
];
748 WetBuffer
[j
][FRONT_RIGHT
] += WetSample
*WetSend
[FRONT_RIGHT
];
749 WetBuffer
[j
][SIDE_LEFT
] += WetSample
*WetSend
[SIDE_LEFT
];
750 WetBuffer
[j
][SIDE_RIGHT
] += WetSample
*WetSend
[SIDE_RIGHT
];
751 WetBuffer
[j
][BACK_LEFT
] += WetSample
*WetSend
[BACK_LEFT
];
752 WetBuffer
[j
][BACK_RIGHT
] += WetSample
*WetSend
[BACK_RIGHT
];
757 ALfloat samp1
, samp2
;
758 //First order interpolator (front left)
759 samp1
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
]*(fraction
)))>>FRACTIONBITS
));
760 DryBuffer
[j
][FRONT_LEFT
] += samp1
*DrySend
[FRONT_LEFT
];
761 WetBuffer
[j
][FRONT_LEFT
] += samp1
*WetSend
[FRONT_LEFT
];
762 //First order interpolator (front right)
763 samp2
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+1]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+1]*(fraction
)))>>FRACTIONBITS
));
764 DryBuffer
[j
][FRONT_RIGHT
] += samp2
*DrySend
[FRONT_RIGHT
];
765 WetBuffer
[j
][FRONT_RIGHT
] += samp2
*WetSend
[FRONT_RIGHT
];
773 //First order interpolator (center)
774 value
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+i
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+i
]*(fraction
)))>>FRACTIONBITS
));
775 DryBuffer
[j
][CENTER
] += value
*DrySend
[CENTER
];
776 WetBuffer
[j
][CENTER
] += value
*WetSend
[CENTER
];
779 //First order interpolator (lfe)
780 value
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+i
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+i
]*(fraction
)))>>FRACTIONBITS
));
781 DryBuffer
[j
][LFE
] += value
*DrySend
[LFE
];
782 WetBuffer
[j
][LFE
] += value
*WetSend
[LFE
];
785 //First order interpolator (back left)
786 value
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+i
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+i
]*(fraction
)))>>FRACTIONBITS
));
787 DryBuffer
[j
][BACK_LEFT
] += value
*DrySend
[BACK_LEFT
];
788 WetBuffer
[j
][BACK_LEFT
] += value
*WetSend
[BACK_LEFT
];
790 //First order interpolator (back right)
791 value
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+i
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+i
]*(fraction
)))>>FRACTIONBITS
));
792 DryBuffer
[j
][BACK_RIGHT
] += value
*DrySend
[BACK_RIGHT
];
793 WetBuffer
[j
][BACK_RIGHT
] += value
*WetSend
[BACK_RIGHT
];
797 //First order interpolator (side left)
798 value
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+i
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+i
]*(fraction
)))>>FRACTIONBITS
));
799 DryBuffer
[j
][SIDE_LEFT
] += value
*DrySend
[SIDE_LEFT
];
800 WetBuffer
[j
][SIDE_LEFT
] += value
*WetSend
[SIDE_LEFT
];
802 //First order interpolator (side right)
803 value
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+i
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+i
]*(fraction
)))>>FRACTIONBITS
));
804 DryBuffer
[j
][SIDE_RIGHT
] += value
*DrySend
[SIDE_RIGHT
];
805 WetBuffer
[j
][SIDE_RIGHT
] += value
*WetSend
[SIDE_RIGHT
];
809 else if(DuplicateStereo
)
811 //Duplicate stereo channels on the back speakers
812 DryBuffer
[j
][BACK_LEFT
] += samp1
*DrySend
[BACK_LEFT
];
813 WetBuffer
[j
][BACK_LEFT
] += samp1
*WetSend
[BACK_LEFT
];
814 DryBuffer
[j
][BACK_RIGHT
] += samp2
*DrySend
[BACK_RIGHT
];
815 WetBuffer
[j
][BACK_RIGHT
] += samp2
*WetSend
[BACK_RIGHT
];
818 DataPosFrac
+= increment
;
821 DataPosInt
+= (DataPosFrac
>>FRACTIONBITS
);
822 DataPosFrac
= (DataPosFrac
&FRACTIONMASK
);
825 ALSource
->position
= DataPosInt
;
826 ALSource
->position_fraction
= DataPosFrac
;
827 ALSource
->LastDrySample
= DrySample
;
828 ALSource
->LastWetSample
= WetSample
;
831 //Handle looping sources
832 if(!Buffer
|| DataPosInt
>= DataSize
)
837 Looping
= ALSource
->bLooping
;
838 if(ALSource
->BuffersPlayed
< (ALSource
->BuffersInQueue
-1))
840 BufferListItem
= ALSource
->queue
;
841 for(loop
= 0; loop
<= ALSource
->BuffersPlayed
; loop
++)
846 BufferListItem
->bufferstate
= PROCESSED
;
847 BufferListItem
= BufferListItem
->next
;
851 ALSource
->BuffersProcessed
++;
853 ALSource
->ulBufferID
= BufferListItem
->buffer
;
854 ALSource
->position
= DataPosInt
-DataSize
;
855 ALSource
->position_fraction
= DataPosFrac
;
856 ALSource
->BuffersPlayed
++;
863 ALSource
->state
= AL_STOPPED
;
864 ALSource
->inuse
= AL_FALSE
;
865 ALSource
->BuffersPlayed
= ALSource
->BuffersProcessed
= ALSource
->BuffersInQueue
;
866 BufferListItem
= ALSource
->queue
;
867 while(BufferListItem
!= NULL
)
869 BufferListItem
->bufferstate
= PROCESSED
;
870 BufferListItem
= BufferListItem
->next
;
877 ALSource
->state
= AL_PLAYING
;
878 ALSource
->inuse
= AL_TRUE
;
879 ALSource
->play
= AL_TRUE
;
880 ALSource
->BuffersPlayed
= 0;
881 ALSource
->BufferPosition
= 0;
882 ALSource
->lBytesPlayed
= 0;
883 ALSource
->BuffersProcessed
= 0;
884 BufferListItem
= ALSource
->queue
;
885 while(BufferListItem
!= NULL
)
887 BufferListItem
->bufferstate
= PENDING
;
888 BufferListItem
= BufferListItem
->next
;
890 ALSource
->ulBufferID
= ALSource
->queue
->buffer
;
892 ALSource
->position
= DataPosInt
-DataSize
;
893 ALSource
->position_fraction
= DataPosFrac
;
900 State
= ALSource
->state
;
903 ALSource
= ALSource
->next
;
906 // effect slot processing
909 if(ALEffectSlot
->effect
.type
== AL_EFFECT_REVERB
)
911 ALfloat
*DelayBuffer
= ALEffectSlot
->ReverbBuffer
;
912 ALuint Pos
= ALEffectSlot
->ReverbPos
;
913 ALuint LatePos
= ALEffectSlot
->ReverbLatePos
;
914 ALuint ReflectPos
= ALEffectSlot
->ReverbReflectPos
;
915 ALuint Length
= ALEffectSlot
->ReverbLength
;
916 ALfloat DecayGain
= ALEffectSlot
->ReverbDecayGain
;
917 ALfloat DecayHFRatio
= ALEffectSlot
->effect
.Reverb
.DecayHFRatio
;
918 ALfloat Gain
= ALEffectSlot
->effect
.Reverb
.Gain
;
919 ALfloat ReflectGain
= ALEffectSlot
->effect
.Reverb
.ReflectionsGain
;
920 ALfloat LateReverbGain
= ALEffectSlot
->effect
.Reverb
.LateReverbGain
;
921 ALfloat LastDecaySample
= ALEffectSlot
->LastDecaySample
;
924 for(i
= 0;i
< SamplesToDo
;i
++)
926 DelayBuffer
[Pos
] = ReverbBuffer
[i
] * Gain
;
928 sample
= DelayBuffer
[ReflectPos
] * ReflectGain
;
930 DelayBuffer
[LatePos
] *= LateReverbGain
;
932 Pos
= (Pos
+1) % Length
;
933 DelayBuffer
[Pos
] *= DecayHFRatio
;
934 DelayBuffer
[Pos
] += LastDecaySample
* (1.0f
-DecayHFRatio
);
935 LastDecaySample
= DelayBuffer
[Pos
];
936 DelayBuffer
[Pos
] *= DecayGain
;
938 DelayBuffer
[LatePos
] += DelayBuffer
[Pos
];
940 sample
+= DelayBuffer
[LatePos
];
942 WetBuffer
[i
][FRONT_LEFT
] += sample
;
943 WetBuffer
[i
][FRONT_RIGHT
] += sample
;
944 WetBuffer
[i
][SIDE_LEFT
] += sample
;
945 WetBuffer
[i
][SIDE_RIGHT
] += sample
;
946 WetBuffer
[i
][BACK_LEFT
] += sample
;
947 WetBuffer
[i
][BACK_RIGHT
] += sample
;
949 LatePos
= (LatePos
+1) % Length
;
950 ReflectPos
= (ReflectPos
+1) % Length
;
953 ALEffectSlot
->ReverbPos
= Pos
;
954 ALEffectSlot
->ReverbLatePos
= LatePos
;
955 ALEffectSlot
->ReverbReflectPos
= ReflectPos
;
956 ALEffectSlot
->LastDecaySample
= LastDecaySample
;
959 ALEffectSlot
= ALEffectSlot
->next
;
962 //Post processing loop
965 case AL_FORMAT_MONO8
:
966 for(i
= 0;i
< SamplesToDo
;i
++)
968 ((ALubyte
*)buffer
)[0] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_LEFT
]+DryBuffer
[i
][FRONT_RIGHT
]+
969 WetBuffer
[i
][FRONT_LEFT
]+WetBuffer
[i
][FRONT_RIGHT
])>>8)+128);
970 buffer
= ((ALubyte
*)buffer
) + 1;
973 case AL_FORMAT_STEREO8
:
974 if(ALContext
&& ALContext
->bs2b
)
976 for(i
= 0;i
< SamplesToDo
;i
++)
979 samples
[0] = DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
];
980 samples
[1] = DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
];
981 bs2b_cross_feed(ALContext
->bs2b
, samples
);
982 ((ALubyte
*)buffer
)[0] = (ALubyte
)((aluF2S(samples
[0])>>8)+128);
983 ((ALubyte
*)buffer
)[1] = (ALubyte
)((aluF2S(samples
[1])>>8)+128);
984 buffer
= ((ALubyte
*)buffer
) + 2;
989 for(i
= 0;i
< SamplesToDo
;i
++)
991 ((ALubyte
*)buffer
)[0] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
])>>8)+128);
992 ((ALubyte
*)buffer
)[1] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
])>>8)+128);
993 buffer
= ((ALubyte
*)buffer
) + 2;
997 case AL_FORMAT_QUAD8
:
998 for(i
= 0;i
< SamplesToDo
;i
++)
1000 ((ALubyte
*)buffer
)[0] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
])>>8)+128);
1001 ((ALubyte
*)buffer
)[1] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
])>>8)+128);
1002 ((ALubyte
*)buffer
)[2] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
])>>8)+128);
1003 ((ALubyte
*)buffer
)[3] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
])>>8)+128);
1004 buffer
= ((ALubyte
*)buffer
) + 4;
1007 case AL_FORMAT_51CHN8
:
1008 for(i
= 0;i
< SamplesToDo
;i
++)
1010 ((ALubyte
*)buffer
)[0] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
])>>8)+128);
1011 ((ALubyte
*)buffer
)[1] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
])>>8)+128);
1012 #ifdef _WIN32 /* Of course, Windows can't use the same ordering... */
1013 ((ALubyte
*)buffer
)[2] = (ALubyte
)((aluF2S(DryBuffer
[i
][CENTER
] +WetBuffer
[i
][CENTER
])>>8)+128);
1014 ((ALubyte
*)buffer
)[3] = (ALubyte
)((aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
])>>8)+128);
1015 ((ALubyte
*)buffer
)[4] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
])>>8)+128);
1016 ((ALubyte
*)buffer
)[5] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
])>>8)+128);
1018 ((ALubyte
*)buffer
)[2] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
])>>8)+128);
1019 ((ALubyte
*)buffer
)[3] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
])>>8)+128);
1020 ((ALubyte
*)buffer
)[4] = (ALubyte
)((aluF2S(DryBuffer
[i
][CENTER
] +WetBuffer
[i
][CENTER
])>>8)+128);
1021 ((ALubyte
*)buffer
)[5] = (ALubyte
)((aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
])>>8)+128);
1023 buffer
= ((ALubyte
*)buffer
) + 6;
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);
1032 ((ALubyte
*)buffer
)[2] = (ALubyte
)((aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
])>>8)+128);
1033 ((ALubyte
*)buffer
)[3] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
])>>8)+128);
1034 ((ALubyte
*)buffer
)[4] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
])>>8)+128);
1036 ((ALubyte
*)buffer
)[2] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
])>>8)+128);
1037 ((ALubyte
*)buffer
)[3] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
])>>8)+128);
1038 ((ALubyte
*)buffer
)[4] = (ALubyte
)((aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
])>>8)+128);
1040 ((ALubyte
*)buffer
)[5] = (ALubyte
)((aluF2S(DryBuffer
[i
][SIDE_LEFT
] +WetBuffer
[i
][SIDE_LEFT
])>>8)+128);
1041 ((ALubyte
*)buffer
)[6] = (ALubyte
)((aluF2S(DryBuffer
[i
][SIDE_RIGHT
] +WetBuffer
[i
][SIDE_RIGHT
])>>8)+128);
1042 buffer
= ((ALubyte
*)buffer
) + 7;
1045 case AL_FORMAT_71CHN8
:
1046 for(i
= 0;i
< SamplesToDo
;i
++)
1048 ((ALubyte
*)buffer
)[0] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
])>>8)+128);
1049 ((ALubyte
*)buffer
)[1] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
])>>8)+128);
1051 ((ALubyte
*)buffer
)[2] = (ALubyte
)((aluF2S(DryBuffer
[i
][CENTER
] +WetBuffer
[i
][CENTER
])>>8)+128);
1052 ((ALubyte
*)buffer
)[3] = (ALubyte
)((aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
])>>8)+128);
1053 ((ALubyte
*)buffer
)[4] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
])>>8)+128);
1054 ((ALubyte
*)buffer
)[5] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
])>>8)+128);
1056 ((ALubyte
*)buffer
)[2] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
])>>8)+128);
1057 ((ALubyte
*)buffer
)[3] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
])>>8)+128);
1058 ((ALubyte
*)buffer
)[4] = (ALubyte
)((aluF2S(DryBuffer
[i
][CENTER
] +WetBuffer
[i
][CENTER
])>>8)+128);
1059 ((ALubyte
*)buffer
)[5] = (ALubyte
)((aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
])>>8)+128);
1061 ((ALubyte
*)buffer
)[6] = (ALubyte
)((aluF2S(DryBuffer
[i
][SIDE_LEFT
] +WetBuffer
[i
][SIDE_LEFT
])>>8)+128);
1062 ((ALubyte
*)buffer
)[7] = (ALubyte
)((aluF2S(DryBuffer
[i
][SIDE_RIGHT
] +WetBuffer
[i
][SIDE_RIGHT
])>>8)+128);
1063 buffer
= ((ALubyte
*)buffer
) + 8;
1067 case AL_FORMAT_MONO16
:
1068 for(i
= 0;i
< SamplesToDo
;i
++)
1070 ((ALshort
*)buffer
)[0] = aluF2S(DryBuffer
[i
][FRONT_LEFT
]+DryBuffer
[i
][FRONT_RIGHT
]+
1071 WetBuffer
[i
][FRONT_LEFT
]+WetBuffer
[i
][FRONT_RIGHT
]);
1072 buffer
= ((ALshort
*)buffer
) + 1;
1075 case AL_FORMAT_STEREO16
:
1076 if(ALContext
&& ALContext
->bs2b
)
1078 for(i
= 0;i
< SamplesToDo
;i
++)
1081 samples
[0] = DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
];
1082 samples
[1] = DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
];
1083 bs2b_cross_feed(ALContext
->bs2b
, samples
);
1084 ((ALshort
*)buffer
)[0] = aluF2S(samples
[0]);
1085 ((ALshort
*)buffer
)[1] = aluF2S(samples
[1]);
1086 buffer
= ((ALshort
*)buffer
) + 2;
1091 for(i
= 0;i
< SamplesToDo
;i
++)
1093 ((ALshort
*)buffer
)[0] = aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
]);
1094 ((ALshort
*)buffer
)[1] = aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
]);
1095 buffer
= ((ALshort
*)buffer
) + 2;
1099 case AL_FORMAT_QUAD16
:
1100 for(i
= 0;i
< SamplesToDo
;i
++)
1102 ((ALshort
*)buffer
)[0] = aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
]);
1103 ((ALshort
*)buffer
)[1] = aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
]);
1104 ((ALshort
*)buffer
)[2] = aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
]);
1105 ((ALshort
*)buffer
)[3] = aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
]);
1106 buffer
= ((ALshort
*)buffer
) + 4;
1109 case AL_FORMAT_51CHN16
:
1110 for(i
= 0;i
< SamplesToDo
;i
++)
1112 ((ALshort
*)buffer
)[0] = aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
]);
1113 ((ALshort
*)buffer
)[1] = aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
]);
1115 ((ALshort
*)buffer
)[2] = aluF2S(DryBuffer
[i
][CENTER
] +WetBuffer
[i
][CENTER
]);
1116 ((ALshort
*)buffer
)[3] = aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
]);
1117 ((ALshort
*)buffer
)[4] = aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
]);
1118 ((ALshort
*)buffer
)[5] = aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
]);
1120 ((ALshort
*)buffer
)[2] = aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
]);
1121 ((ALshort
*)buffer
)[3] = aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
]);
1122 ((ALshort
*)buffer
)[4] = aluF2S(DryBuffer
[i
][CENTER
] +WetBuffer
[i
][CENTER
]);
1123 ((ALshort
*)buffer
)[5] = aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
]);
1125 buffer
= ((ALshort
*)buffer
) + 6;
1128 case AL_FORMAT_61CHN16
:
1129 for(i
= 0;i
< SamplesToDo
;i
++)
1131 ((ALshort
*)buffer
)[0] = aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
]);
1132 ((ALshort
*)buffer
)[1] = aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
]);
1134 ((ALshort
*)buffer
)[2] = aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
]);
1135 ((ALshort
*)buffer
)[3] = aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
]);
1136 ((ALshort
*)buffer
)[4] = aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
]);
1138 ((ALshort
*)buffer
)[2] = aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
]);
1139 ((ALshort
*)buffer
)[3] = aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
]);
1140 ((ALshort
*)buffer
)[4] = aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
]);
1142 ((ALshort
*)buffer
)[5] = aluF2S(DryBuffer
[i
][SIDE_LEFT
] +WetBuffer
[i
][SIDE_LEFT
]);
1143 ((ALshort
*)buffer
)[6] = aluF2S(DryBuffer
[i
][SIDE_RIGHT
] +WetBuffer
[i
][SIDE_RIGHT
]);
1144 buffer
= ((ALshort
*)buffer
) + 7;
1147 case AL_FORMAT_71CHN16
:
1148 for(i
= 0;i
< SamplesToDo
;i
++)
1150 ((ALshort
*)buffer
)[0] = aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
]);
1151 ((ALshort
*)buffer
)[1] = aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
]);
1153 ((ALshort
*)buffer
)[2] = aluF2S(DryBuffer
[i
][CENTER
] +WetBuffer
[i
][CENTER
]);
1154 ((ALshort
*)buffer
)[3] = aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
]);
1155 ((ALshort
*)buffer
)[4] = aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
]);
1156 ((ALshort
*)buffer
)[5] = aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
]);
1158 ((ALshort
*)buffer
)[2] = aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
]);
1159 ((ALshort
*)buffer
)[3] = aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
]);
1160 ((ALshort
*)buffer
)[4] = aluF2S(DryBuffer
[i
][CENTER
] +WetBuffer
[i
][CENTER
]);
1161 ((ALshort
*)buffer
)[5] = aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
]);
1163 ((ALshort
*)buffer
)[6] = aluF2S(DryBuffer
[i
][SIDE_LEFT
] +WetBuffer
[i
][SIDE_LEFT
]);
1164 ((ALshort
*)buffer
)[7] = aluF2S(DryBuffer
[i
][SIDE_RIGHT
] +WetBuffer
[i
][SIDE_RIGHT
]);
1165 buffer
= ((ALshort
*)buffer
) + 8;
1173 size
-= SamplesToDo
;
1176 ProcessContext(ALContext
);