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 /* 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
)
92 case AL_FORMAT_STEREO8
:
93 case AL_FORMAT_QUAD8_LOKI
:
95 case AL_FORMAT_51CHN8
:
96 case AL_FORMAT_61CHN8
:
97 case AL_FORMAT_71CHN8
:
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
:
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
:
122 __inline ALuint
aluChannelsFromFormat(ALenum format
)
126 case AL_FORMAT_MONO8
:
127 case AL_FORMAT_MONO16
:
128 case AL_FORMAT_MONO_FLOAT32
:
131 case AL_FORMAT_STEREO8
:
132 case AL_FORMAT_STEREO16
:
133 case AL_FORMAT_STEREO_FLOAT32
:
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
:
143 case AL_FORMAT_51CHN8
:
144 case AL_FORMAT_51CHN16
:
145 case AL_FORMAT_51CHN32
:
148 case AL_FORMAT_61CHN8
:
149 case AL_FORMAT_61CHN16
:
150 case AL_FORMAT_61CHN32
:
153 case AL_FORMAT_71CHN8
:
154 case AL_FORMAT_71CHN16
:
155 case AL_FORMAT_71CHN32
:
163 static __inline ALint
aluF2L(ALfloat Value
)
166 if(sizeof(ALint
) == 4 && sizeof(double) == 8)
169 temp
= Value
+ (((65536.0*65536.0*16.0)+(65536.0*65536.0*8.0))*65536.0);
170 return *((ALint
*)&temp
);
176 static __inline ALshort
aluF2S(ALfloat Value
)
181 i
= __min( 32767, i
);
182 i
= __max(-32768, 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
));
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])
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(ALsource
*source
, ALfloat DryGainHF
, ALfloat sample
)
230 sample
+= source
->LastDrySample
* (1.0f
-DryGainHF
);
236 source
->LastDrySample
= sample
;
240 static __inline ALfloat
aluComputeWetSample(ALsource
*source
, ALfloat WetGainHF
, ALfloat sample
)
247 sample
+= source
->LastWetSample
* (1.0f
-WetGainHF
);
253 source
->LastWetSample
= sample
;
257 static ALvoid
CalcSourceParams(ALCcontext
*ALContext
, ALsource
*ALSource
,
258 ALenum isMono
, ALenum OutputFormat
,
259 ALfloat
*drysend
, ALfloat
*wetsend
,
260 ALfloat
*pitch
, ALfloat
*drygainhf
,
263 ALfloat InnerAngle
,OuterAngle
,Angle
,Distance
,DryMix
,WetMix
=0.0f
;
264 ALfloat Direction
[3],Position
[3],SourceToListener
[3];
265 ALfloat MinVolume
,MaxVolume
,MinDist
,MaxDist
,Rolloff
,OuterGainHF
;
266 ALfloat ConeVolume
,SourceVolume
,PanningFB
,PanningLR
,ListenerGain
;
267 ALfloat U
[3],V
[3],N
[3];
268 ALfloat DopplerFactor
, DopplerVelocity
, flSpeedOfSound
, flMaxVelocity
;
269 ALfloat Matrix
[3][3];
270 ALfloat flAttenuation
;
271 ALfloat RoomAttenuation
;
272 ALfloat MetersPerUnit
;
274 ALfloat DryGainHF
= 1.0f
;
275 ALfloat WetGainHF
= 1.0f
;
277 //Get context properties
278 DopplerFactor
= ALContext
->DopplerFactor
;
279 DopplerVelocity
= ALContext
->DopplerVelocity
;
280 flSpeedOfSound
= ALContext
->flSpeedOfSound
;
282 //Get listener properties
283 ListenerGain
= ALContext
->Listener
.Gain
;
284 MetersPerUnit
= ALContext
->Listener
.MetersPerUnit
;
286 //Get source properties
287 SourceVolume
= ALSource
->flGain
;
288 memcpy(Position
, ALSource
->vPosition
, sizeof(ALSource
->vPosition
));
289 memcpy(Direction
, ALSource
->vOrientation
, sizeof(ALSource
->vOrientation
));
290 MinVolume
= ALSource
->flMinGain
;
291 MaxVolume
= ALSource
->flMaxGain
;
292 MinDist
= ALSource
->flRefDistance
;
293 MaxDist
= ALSource
->flMaxDistance
;
294 Rolloff
= ALSource
->flRollOffFactor
;
295 InnerAngle
= ALSource
->flInnerAngle
;
296 OuterAngle
= ALSource
->flOuterAngle
;
297 OuterGainHF
= ALSource
->OuterGainHF
;
298 RoomRolloff
= ALSource
->RoomRolloffFactor
;
300 //Only apply 3D calculations for mono buffers
301 if(isMono
!= AL_FALSE
)
303 //1. Translate Listener to origin (convert to head relative)
304 if(ALSource
->bHeadRelative
==AL_FALSE
)
306 Position
[0] -= ALContext
->Listener
.Position
[0];
307 Position
[1] -= ALContext
->Listener
.Position
[1];
308 Position
[2] -= ALContext
->Listener
.Position
[2];
311 //2. Calculate distance attenuation
312 Distance
= aluSqrt(aluDotproduct(Position
, Position
));
314 if(ALSource
->Send
[0].Slot
&& !ALSource
->Send
[0].Slot
->AuxSendAuto
)
316 if(ALSource
->Send
[0].Slot
->effect
.type
== AL_EFFECT_REVERB
)
317 RoomRolloff
= ALSource
->Send
[0].Slot
->effect
.Reverb
.RoomRolloffFactor
;
320 flAttenuation
= 1.0f
;
321 RoomAttenuation
= 1.0f
;
322 switch (ALContext
->DistanceModel
)
324 case AL_INVERSE_DISTANCE_CLAMPED
:
325 Distance
=__max(Distance
,MinDist
);
326 Distance
=__min(Distance
,MaxDist
);
327 if (MaxDist
< MinDist
)
330 case AL_INVERSE_DISTANCE
:
333 if ((MinDist
+ (Rolloff
* (Distance
- MinDist
))) > 0.0f
)
334 flAttenuation
= MinDist
/ (MinDist
+ (Rolloff
* (Distance
- MinDist
)));
335 if ((MinDist
+ (RoomRolloff
* (Distance
- MinDist
))) > 0.0f
)
336 RoomAttenuation
= MinDist
/ (MinDist
+ (RoomRolloff
* (Distance
- MinDist
)));
340 case AL_LINEAR_DISTANCE_CLAMPED
:
341 Distance
=__max(Distance
,MinDist
);
342 Distance
=__min(Distance
,MaxDist
);
343 if (MaxDist
< MinDist
)
346 case AL_LINEAR_DISTANCE
:
347 Distance
=__min(Distance
,MaxDist
);
348 if (MaxDist
!= MinDist
)
350 flAttenuation
= 1.0f
- (Rolloff
*(Distance
-MinDist
)/(MaxDist
- MinDist
));
351 RoomAttenuation
= 1.0f
- (RoomRolloff
*(Distance
-MinDist
)/(MaxDist
- MinDist
));
355 case AL_EXPONENT_DISTANCE_CLAMPED
:
356 Distance
=__max(Distance
,MinDist
);
357 Distance
=__min(Distance
,MaxDist
);
358 if (MaxDist
< MinDist
)
361 case AL_EXPONENT_DISTANCE
:
362 if ((Distance
> 0.0f
) && (MinDist
> 0.0f
))
364 flAttenuation
= (ALfloat
)pow(Distance
/MinDist
, -Rolloff
);
365 RoomAttenuation
= (ALfloat
)pow(Distance
/MinDist
, -RoomRolloff
);
371 flAttenuation
= 1.0f
;
372 RoomAttenuation
= 1.0f
;
376 // Source Gain + Attenuation and clamp to Min/Max Gain
377 DryMix
= SourceVolume
* flAttenuation
;
378 DryMix
= __min(DryMix
,MaxVolume
);
379 DryMix
= __max(DryMix
,MinVolume
);
381 WetMix
= SourceVolume
* (ALSource
->WetGainAuto
?
382 RoomAttenuation
: 1.0f
);
383 WetMix
= __min(WetMix
,MaxVolume
);
384 WetMix
= __max(WetMix
,MinVolume
);
386 //3. Apply directional soundcones
387 SourceToListener
[0] = -Position
[0];
388 SourceToListener
[1] = -Position
[1];
389 SourceToListener
[2] = -Position
[2];
390 aluNormalize(Direction
);
391 aluNormalize(SourceToListener
);
392 Angle
= aluAcos(aluDotproduct(Direction
,SourceToListener
)) * 180.0f
/
394 if(Angle
>= InnerAngle
&& Angle
<= OuterAngle
)
396 ALfloat scale
= (Angle
-InnerAngle
) / (OuterAngle
-InnerAngle
);
397 ConeVolume
= (1.0f
+(ALSource
->flOuterGain
-1.0f
)*scale
);
398 if(ALSource
->WetGainAuto
)
399 WetMix
*= ConeVolume
;
400 if(ALSource
->DryGainHFAuto
)
401 DryGainHF
*= (1.0f
+(OuterGainHF
-1.0f
)*scale
);
402 if(ALSource
->WetGainHFAuto
)
403 WetGainHF
*= (1.0f
+(OuterGainHF
-1.0f
)*scale
);
405 else if(Angle
> OuterAngle
)
407 ConeVolume
= (1.0f
+(ALSource
->flOuterGain
-1.0f
));
408 if(ALSource
->WetGainAuto
)
409 WetMix
*= ConeVolume
;
410 if(ALSource
->DryGainHFAuto
)
411 DryGainHF
*= (1.0f
+(OuterGainHF
-1.0f
));
412 if(ALSource
->WetGainHFAuto
)
413 WetGainHF
*= (1.0f
+(OuterGainHF
-1.0f
));
418 //4. Calculate Velocity
419 if(DopplerFactor
!= 0.0f
)
421 ALfloat flVSS
, flVLS
;
423 flVLS
= aluDotproduct(ALContext
->Listener
.Velocity
,
425 flVSS
= aluDotproduct(ALSource
->vVelocity
, SourceToListener
);
427 flMaxVelocity
= (DopplerVelocity
* flSpeedOfSound
) / DopplerFactor
;
429 if (flVSS
>= flMaxVelocity
)
430 flVSS
= (flMaxVelocity
- 1.0f
);
431 else if (flVSS
<= -flMaxVelocity
)
432 flVSS
= -flMaxVelocity
+ 1.0f
;
434 if (flVLS
>= flMaxVelocity
)
435 flVLS
= (flMaxVelocity
- 1.0f
);
436 else if (flVLS
<= -flMaxVelocity
)
437 flVLS
= -flMaxVelocity
+ 1.0f
;
439 pitch
[0] = ALSource
->flPitch
*
440 ((flSpeedOfSound
* DopplerVelocity
) - (DopplerFactor
* flVLS
)) /
441 ((flSpeedOfSound
* DopplerVelocity
) - (DopplerFactor
* flVSS
));
444 pitch
[0] = ALSource
->flPitch
;
446 //5. Align coordinate system axes
447 aluCrossproduct(ALContext
->Listener
.Forward
, ALContext
->Listener
.Up
, U
); // Right-vector
448 aluNormalize(U
); // Normalized Right-vector
449 memcpy(V
, ALContext
->Listener
.Up
, sizeof(V
)); // Up-vector
450 aluNormalize(V
); // Normalized Up-vector
451 memcpy(N
, ALContext
->Listener
.Forward
, sizeof(N
)); // At-vector
452 aluNormalize(N
); // Normalized At-vector
453 Matrix
[0][0] = U
[0]; Matrix
[0][1] = V
[0]; Matrix
[0][2] = -N
[0];
454 Matrix
[1][0] = U
[1]; Matrix
[1][1] = V
[1]; Matrix
[1][2] = -N
[1];
455 Matrix
[2][0] = U
[2]; Matrix
[2][1] = V
[2]; Matrix
[2][2] = -N
[2];
456 aluMatrixVector(Position
, Matrix
);
458 //6. Apply filter gains and filters
459 switch(ALSource
->DirectFilter
.filter
)
461 case AL_FILTER_LOWPASS
:
462 DryMix
*= ALSource
->DirectFilter
.Gain
;
463 DryGainHF
*= ALSource
->DirectFilter
.GainHF
;
467 switch(ALSource
->Send
[0].WetFilter
.filter
)
469 case AL_FILTER_LOWPASS
:
470 WetMix
*= ALSource
->Send
[0].WetFilter
.Gain
;
471 WetGainHF
*= ALSource
->Send
[0].WetFilter
.GainHF
;
475 if(ALSource
->AirAbsorptionFactor
> 0.0f
)
476 DryGainHF
*= pow(ALSource
->AirAbsorptionFactor
* AIRABSORBGAINHF
,
477 Distance
* MetersPerUnit
);
479 if(ALSource
->Send
[0].Slot
)
481 WetMix
*= ALSource
->Send
[0].Slot
->Gain
;
483 if(ALSource
->Send
[0].Slot
->effect
.type
== AL_EFFECT_REVERB
)
485 WetGainHF
*= ALSource
->Send
[0].Slot
->effect
.Reverb
.GainHF
;
486 WetGainHF
*= pow(ALSource
->Send
[0].Slot
->effect
.Reverb
.AirAbsorptionGainHF
,
487 Distance
* MetersPerUnit
);
491 //7. Convert normalized position into pannings, then into channel volumes
492 aluNormalize(Position
);
493 switch(aluChannelsFromFormat(OutputFormat
))
496 drysend
[FRONT_LEFT
] = ConeVolume
* ListenerGain
* DryMix
* aluSqrt(1.0f
); //Direct
497 drysend
[FRONT_RIGHT
] = ConeVolume
* ListenerGain
* DryMix
* aluSqrt(1.0f
); //Direct
498 if(ALSource
->Send
[0].Slot
)
500 wetsend
[FRONT_LEFT
] = ListenerGain
* WetMix
* aluSqrt(1.0f
); //Room
501 wetsend
[FRONT_RIGHT
] = ListenerGain
* WetMix
* aluSqrt(1.0f
); //Room
505 wetsend
[FRONT_LEFT
] = 0.0f
;
506 wetsend
[FRONT_RIGHT
] = 0.0f
;
511 PanningLR
= 0.5f
+ 0.5f
*Position
[0];
512 drysend
[FRONT_LEFT
] = ConeVolume
* ListenerGain
* DryMix
* aluSqrt(1.0f
-PanningLR
); //L Direct
513 drysend
[FRONT_RIGHT
] = ConeVolume
* ListenerGain
* DryMix
* aluSqrt( PanningLR
); //R Direct
514 if(ALSource
->Send
[0].Slot
)
516 wetsend
[FRONT_LEFT
] = ListenerGain
* WetMix
* aluSqrt(1.0f
-PanningLR
); //L Room
517 wetsend
[FRONT_RIGHT
] = ListenerGain
* WetMix
* aluSqrt( PanningLR
); //R Room
521 wetsend
[FRONT_LEFT
] = 0.0f
;
522 wetsend
[FRONT_RIGHT
] = 0.0f
;
527 /* TODO: Add center/lfe channel in spatial calculations? */
529 // Apply a scalar so each individual speaker has more weight
530 PanningLR
= 0.5f
+ (0.5f
*Position
[0]*1.41421356f
);
531 PanningLR
= __min(1.0f
, PanningLR
);
532 PanningLR
= __max(0.0f
, PanningLR
);
533 PanningFB
= 0.5f
+ (0.5f
*Position
[2]*1.41421356f
);
534 PanningFB
= __min(1.0f
, PanningFB
);
535 PanningFB
= __max(0.0f
, PanningFB
);
536 drysend
[FRONT_LEFT
] = ConeVolume
* ListenerGain
* DryMix
* aluSqrt((1.0f
-PanningLR
)*(1.0f
-PanningFB
));
537 drysend
[FRONT_RIGHT
] = ConeVolume
* ListenerGain
* DryMix
* aluSqrt(( PanningLR
)*(1.0f
-PanningFB
));
538 drysend
[BACK_LEFT
] = ConeVolume
* ListenerGain
* DryMix
* aluSqrt((1.0f
-PanningLR
)*( PanningFB
));
539 drysend
[BACK_RIGHT
] = ConeVolume
* ListenerGain
* DryMix
* aluSqrt(( PanningLR
)*( PanningFB
));
540 if(ALSource
->Send
[0].Slot
)
542 wetsend
[FRONT_LEFT
] = ListenerGain
* WetMix
* aluSqrt((1.0f
-PanningLR
)*(1.0f
-PanningFB
));
543 wetsend
[FRONT_RIGHT
] = ListenerGain
* WetMix
* aluSqrt(( PanningLR
)*(1.0f
-PanningFB
));
544 wetsend
[BACK_LEFT
] = ListenerGain
* WetMix
* aluSqrt((1.0f
-PanningLR
)*( PanningFB
));
545 wetsend
[BACK_RIGHT
] = ListenerGain
* WetMix
* aluSqrt(( PanningLR
)*( PanningFB
));
549 wetsend
[FRONT_LEFT
] = 0.0f
;
550 wetsend
[FRONT_RIGHT
] = 0.0f
;
551 wetsend
[BACK_LEFT
] = 0.0f
;
552 wetsend
[BACK_RIGHT
] = 0.0f
;
558 PanningFB
= 1.0f
- fabs(Position
[2]*1.15470054f
);
559 PanningFB
= __min(1.0f
, PanningFB
);
560 PanningFB
= __max(0.0f
, PanningFB
);
561 PanningLR
= 0.5f
+ (0.5*Position
[0]*((1.0f
-PanningFB
)*2.0f
));
562 PanningLR
= __min(1.0f
, PanningLR
);
563 PanningLR
= __max(0.0f
, PanningLR
);
564 if(Position
[2] > 0.0f
)
566 drysend
[BACK_LEFT
] = ConeVolume
* ListenerGain
* DryMix
* aluSqrt((1.0f
-PanningLR
)*(1.0f
-PanningFB
));
567 drysend
[BACK_RIGHT
] = ConeVolume
* ListenerGain
* DryMix
* aluSqrt(( PanningLR
)*(1.0f
-PanningFB
));
568 drysend
[SIDE_LEFT
] = ConeVolume
* ListenerGain
* DryMix
* aluSqrt((1.0f
-PanningLR
)*( PanningFB
));
569 drysend
[SIDE_RIGHT
] = ConeVolume
* ListenerGain
* DryMix
* aluSqrt(( PanningLR
)*( PanningFB
));
570 drysend
[FRONT_LEFT
] = 0.0f
;
571 drysend
[FRONT_RIGHT
] = 0.0f
;
572 if(ALSource
->Send
[0].Slot
)
574 wetsend
[BACK_LEFT
] = ListenerGain
* WetMix
* aluSqrt((1.0f
-PanningLR
)*(1.0f
-PanningFB
));
575 wetsend
[BACK_RIGHT
] = ListenerGain
* WetMix
* aluSqrt(( PanningLR
)*(1.0f
-PanningFB
));
576 wetsend
[SIDE_LEFT
] = ListenerGain
* WetMix
* aluSqrt((1.0f
-PanningLR
)*( PanningFB
));
577 wetsend
[SIDE_RIGHT
] = ListenerGain
* WetMix
* aluSqrt(( PanningLR
)*( PanningFB
));
578 wetsend
[FRONT_LEFT
] = 0.0f
;
579 wetsend
[FRONT_RIGHT
] = 0.0f
;
583 wetsend
[FRONT_LEFT
] = 0.0f
;
584 wetsend
[FRONT_RIGHT
] = 0.0f
;
585 wetsend
[SIDE_LEFT
] = 0.0f
;
586 wetsend
[SIDE_RIGHT
] = 0.0f
;
587 wetsend
[BACK_LEFT
] = 0.0f
;
588 wetsend
[BACK_RIGHT
] = 0.0f
;
594 drysend
[FRONT_LEFT
] = ConeVolume
* ListenerGain
* DryMix
* aluSqrt((1.0f
-PanningLR
)*(1.0f
-PanningFB
));
595 drysend
[FRONT_RIGHT
] = ConeVolume
* ListenerGain
* DryMix
* aluSqrt(( PanningLR
)*(1.0f
-PanningFB
));
596 drysend
[SIDE_LEFT
] = ConeVolume
* ListenerGain
* DryMix
* aluSqrt((1.0f
-PanningLR
)*( PanningFB
));
597 drysend
[SIDE_RIGHT
] = ConeVolume
* ListenerGain
* DryMix
* aluSqrt(( PanningLR
)*( PanningFB
));
598 drysend
[BACK_LEFT
] = 0.0f
;
599 drysend
[BACK_RIGHT
] = 0.0f
;
600 if(ALSource
->Send
[0].Slot
)
602 wetsend
[FRONT_LEFT
] = ListenerGain
* WetMix
* aluSqrt((1.0f
-PanningLR
)*(1.0f
-PanningFB
));
603 wetsend
[FRONT_RIGHT
] = ListenerGain
* WetMix
* aluSqrt(( PanningLR
)*(1.0f
-PanningFB
));
604 wetsend
[SIDE_LEFT
] = ListenerGain
* WetMix
* aluSqrt((1.0f
-PanningLR
)*( PanningFB
));
605 wetsend
[SIDE_RIGHT
] = ListenerGain
* WetMix
* aluSqrt(( PanningLR
)*( PanningFB
));
606 wetsend
[BACK_LEFT
] = 0.0f
;
607 wetsend
[BACK_RIGHT
] = 0.0f
;
611 wetsend
[FRONT_LEFT
] = 0.0f
;
612 wetsend
[FRONT_RIGHT
] = 0.0f
;
613 wetsend
[SIDE_LEFT
] = 0.0f
;
614 wetsend
[SIDE_RIGHT
] = 0.0f
;
615 wetsend
[BACK_LEFT
] = 0.0f
;
616 wetsend
[BACK_RIGHT
] = 0.0f
;
624 *drygainhf
= DryGainHF
;
625 *wetgainhf
= WetGainHF
;
629 *drygainhf
= DryGainHF
;
630 *wetgainhf
= WetGainHF
;
632 //1. Multi-channel buffers always play "normal"
633 drysend
[FRONT_LEFT
] = SourceVolume
* 1.0f
* ListenerGain
;
634 drysend
[FRONT_RIGHT
] = SourceVolume
* 1.0f
* ListenerGain
;
635 drysend
[SIDE_LEFT
] = SourceVolume
* 1.0f
* ListenerGain
;
636 drysend
[SIDE_RIGHT
] = SourceVolume
* 1.0f
* ListenerGain
;
637 drysend
[BACK_LEFT
] = SourceVolume
* 1.0f
* ListenerGain
;
638 drysend
[BACK_RIGHT
] = SourceVolume
* 1.0f
* ListenerGain
;
639 drysend
[CENTER
] = SourceVolume
* 1.0f
* ListenerGain
;
640 drysend
[LFE
] = SourceVolume
* 1.0f
* ListenerGain
;
641 if(ALSource
->Send
[0].Slot
)
643 wetsend
[FRONT_LEFT
] = SourceVolume
* 0.0f
* ListenerGain
;
644 wetsend
[FRONT_RIGHT
] = SourceVolume
* 0.0f
* ListenerGain
;
645 wetsend
[SIDE_LEFT
] = SourceVolume
* 0.0f
* ListenerGain
;
646 wetsend
[SIDE_RIGHT
] = SourceVolume
* 0.0f
* ListenerGain
;
647 wetsend
[BACK_LEFT
] = SourceVolume
* 0.0f
* ListenerGain
;
648 wetsend
[BACK_RIGHT
] = SourceVolume
* 0.0f
* ListenerGain
;
649 wetsend
[CENTER
] = SourceVolume
* 0.0f
* ListenerGain
;
650 wetsend
[LFE
] = SourceVolume
* 0.0f
* ListenerGain
;
654 wetsend
[FRONT_LEFT
] = 0.0f
;
655 wetsend
[FRONT_RIGHT
] = 0.0f
;
656 wetsend
[SIDE_LEFT
] = 0.0f
;
657 wetsend
[SIDE_RIGHT
] = 0.0f
;
658 wetsend
[BACK_LEFT
] = 0.0f
;
659 wetsend
[BACK_RIGHT
] = 0.0f
;
660 wetsend
[CENTER
] = 0.0f
;
665 pitch
[0] = ALSource
->flPitch
;
669 ALvoid
aluMixData(ALCcontext
*ALContext
,ALvoid
*buffer
,ALsizei size
,ALenum format
)
671 static float DryBuffer
[BUFFERSIZE
][OUTPUTCHANNELS
];
672 static float WetBuffer
[BUFFERSIZE
][OUTPUTCHANNELS
];
673 static float ReverbBuffer
[BUFFERSIZE
];
674 ALfloat DrySend
[OUTPUTCHANNELS
] = { 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
};
675 ALfloat WetSend
[OUTPUTCHANNELS
] = { 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
};
676 ALfloat DryGainHF
= 0.0f
;
677 ALfloat WetGainHF
= 0.0f
;
678 ALuint BlockAlign
,BufferSize
;
679 ALuint DataSize
=0,DataPosInt
=0,DataPosFrac
=0;
680 ALuint Channels
,Frequency
,ulExtraSamples
;
683 ALint Looping
,increment
,State
;
684 ALuint Buffer
,fraction
;
688 ALeffectslot
*ALEffectSlot
;
692 ALbufferlistitem
*BufferListItem
;
694 ALint64 DataSize64
,DataPos64
;
696 SuspendContext(ALContext
);
700 //Figure output format variables
701 BlockAlign
= aluChannelsFromFormat(format
);
702 BlockAlign
*= aluBytesFromFormat(format
);
708 ALSource
= (ALContext
? ALContext
->Source
: NULL
);
709 SamplesToDo
= min(size
, BUFFERSIZE
);
711 //Clear mixing buffer
712 memset(DryBuffer
, 0, SamplesToDo
*OUTPUTCHANNELS
*sizeof(ALfloat
));
713 memset(WetBuffer
, 0, SamplesToDo
*OUTPUTCHANNELS
*sizeof(ALfloat
));
714 memset(ReverbBuffer
, 0, SamplesToDo
*sizeof(ALfloat
));
720 State
= ALSource
->state
;
722 doReverb
= ((ALSource
->Send
[0].Slot
&&
723 ALSource
->Send
[0].Slot
->effect
.type
== AL_EFFECT_REVERB
) ?
726 while(State
== AL_PLAYING
&& j
< SamplesToDo
)
733 if((Buffer
= ALSource
->ulBufferID
))
735 ALBuffer
= (ALbuffer
*)ALTHUNK_LOOKUPENTRY(Buffer
);
737 Data
= ALBuffer
->data
;
738 Channels
= aluChannelsFromFormat(ALBuffer
->format
);
739 DataSize
= ALBuffer
->size
;
740 Frequency
= ALBuffer
->frequency
;
742 CalcSourceParams(ALContext
, ALSource
,
743 (Channels
==1) ? AL_TRUE
: AL_FALSE
,
744 format
, DrySend
, WetSend
, &Pitch
,
745 &DryGainHF
, &WetGainHF
);
748 Pitch
= (Pitch
*Frequency
) / ALContext
->Frequency
;
749 DataSize
/= Channels
* aluBytesFromFormat(ALBuffer
->format
);
752 DataPosInt
= ALSource
->position
;
753 DataPosFrac
= ALSource
->position_fraction
;
755 //Compute 18.14 fixed point step
756 increment
= aluF2L(Pitch
*(1L<<FRACTIONBITS
));
757 if(increment
> (MAX_PITCH
<<FRACTIONBITS
))
758 increment
= (MAX_PITCH
<<FRACTIONBITS
);
760 //Figure out how many samples we can mix.
761 //Pitch must be <= 4 (the number below !)
762 DataSize64
= DataSize
+MAX_PITCH
;
763 DataSize64
<<= FRACTIONBITS
;
764 DataPos64
= DataPosInt
;
765 DataPos64
<<= FRACTIONBITS
;
766 DataPos64
+= DataPosFrac
;
767 BufferSize
= (ALuint
)((DataSize64
-DataPos64
) / increment
);
768 BufferListItem
= ALSource
->queue
;
769 for(loop
= 0; loop
< ALSource
->BuffersPlayed
; loop
++)
772 BufferListItem
= BufferListItem
->next
;
776 if (BufferListItem
->next
)
778 if(BufferListItem
->next
->buffer
&&
779 ((ALbuffer
*)ALTHUNK_LOOKUPENTRY(BufferListItem
->next
->buffer
))->data
)
781 ulExtraSamples
= min(((ALbuffer
*)ALTHUNK_LOOKUPENTRY(BufferListItem
->next
->buffer
))->size
, (ALint
)(16*Channels
));
782 memcpy(&Data
[DataSize
*Channels
], ((ALbuffer
*)ALTHUNK_LOOKUPENTRY(BufferListItem
->next
->buffer
))->data
, ulExtraSamples
);
785 else if (ALSource
->bLooping
)
787 if (ALSource
->queue
->buffer
)
789 if(((ALbuffer
*)ALTHUNK_LOOKUPENTRY(ALSource
->queue
->buffer
))->data
)
791 ulExtraSamples
= min(((ALbuffer
*)ALTHUNK_LOOKUPENTRY(ALSource
->queue
->buffer
))->size
, (ALint
)(16*Channels
));
792 memcpy(&Data
[DataSize
*Channels
], ((ALbuffer
*)ALTHUNK_LOOKUPENTRY(ALSource
->queue
->buffer
))->data
, ulExtraSamples
);
797 BufferSize
= min(BufferSize
, (SamplesToDo
-j
));
799 //Actual sample mixing loop
800 Data
+= DataPosInt
*Channels
;
803 k
= DataPosFrac
>>FRACTIONBITS
;
804 fraction
= DataPosFrac
&FRACTIONMASK
;
807 //First order interpolator
808 ALfloat sample
= (ALfloat
)((ALshort
)(((Data
[k
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[k
+1]*(fraction
)))>>FRACTIONBITS
));
810 //Direct path final mix buffer and panning
811 value
= aluComputeDrySample(ALSource
, DryGainHF
, sample
);
812 DryBuffer
[j
][FRONT_LEFT
] += value
*DrySend
[FRONT_LEFT
];
813 DryBuffer
[j
][FRONT_RIGHT
] += value
*DrySend
[FRONT_RIGHT
];
814 DryBuffer
[j
][SIDE_LEFT
] += value
*DrySend
[SIDE_LEFT
];
815 DryBuffer
[j
][SIDE_RIGHT
] += value
*DrySend
[SIDE_RIGHT
];
816 DryBuffer
[j
][BACK_LEFT
] += value
*DrySend
[BACK_LEFT
];
817 DryBuffer
[j
][BACK_RIGHT
] += value
*DrySend
[BACK_RIGHT
];
818 //Room path final mix buffer and panning
819 value
= aluComputeWetSample(ALSource
, WetGainHF
, sample
);
821 ReverbBuffer
[j
] += value
;
824 WetBuffer
[j
][FRONT_LEFT
] += value
*WetSend
[FRONT_LEFT
];
825 WetBuffer
[j
][FRONT_RIGHT
] += value
*WetSend
[FRONT_RIGHT
];
826 WetBuffer
[j
][SIDE_LEFT
] += value
*WetSend
[SIDE_LEFT
];
827 WetBuffer
[j
][SIDE_RIGHT
] += value
*WetSend
[SIDE_RIGHT
];
828 WetBuffer
[j
][BACK_LEFT
] += value
*WetSend
[BACK_LEFT
];
829 WetBuffer
[j
][BACK_RIGHT
] += value
*WetSend
[BACK_RIGHT
];
834 //First order interpolator (front left)
835 value
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
]*(fraction
)))>>FRACTIONBITS
));
836 DryBuffer
[j
][FRONT_LEFT
] += value
*DrySend
[FRONT_LEFT
];
837 WetBuffer
[j
][FRONT_LEFT
] += value
*WetSend
[FRONT_LEFT
];
838 //First order interpolator (front right)
839 value
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+1]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+1]*(fraction
)))>>FRACTIONBITS
));
840 DryBuffer
[j
][FRONT_RIGHT
] += value
*DrySend
[FRONT_RIGHT
];
841 WetBuffer
[j
][FRONT_RIGHT
] += value
*WetSend
[FRONT_RIGHT
];
849 //First order interpolator (center)
850 value
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+i
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+i
]*(fraction
)))>>FRACTIONBITS
));
851 DryBuffer
[j
][CENTER
] += value
*DrySend
[CENTER
];
852 WetBuffer
[j
][CENTER
] += value
*WetSend
[CENTER
];
855 //First order interpolator (lfe)
856 value
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+i
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+i
]*(fraction
)))>>FRACTIONBITS
));
857 DryBuffer
[j
][LFE
] += value
*DrySend
[LFE
];
858 WetBuffer
[j
][LFE
] += value
*WetSend
[LFE
];
861 //First order interpolator (back left)
862 value
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+i
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+i
]*(fraction
)))>>FRACTIONBITS
));
863 DryBuffer
[j
][BACK_LEFT
] += value
*DrySend
[BACK_LEFT
];
864 WetBuffer
[j
][BACK_LEFT
] += value
*WetSend
[BACK_LEFT
];
866 //First order interpolator (back right)
867 value
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+i
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+i
]*(fraction
)))>>FRACTIONBITS
));
868 DryBuffer
[j
][BACK_RIGHT
] += value
*DrySend
[BACK_RIGHT
];
869 WetBuffer
[j
][BACK_RIGHT
] += value
*WetSend
[BACK_RIGHT
];
873 //First order interpolator (side left)
874 value
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+i
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+i
]*(fraction
)))>>FRACTIONBITS
));
875 DryBuffer
[j
][SIDE_LEFT
] += value
*DrySend
[SIDE_LEFT
];
876 WetBuffer
[j
][SIDE_LEFT
] += value
*WetSend
[SIDE_LEFT
];
878 //First order interpolator (side right)
879 value
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+i
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+i
]*(fraction
)))>>FRACTIONBITS
));
880 DryBuffer
[j
][SIDE_RIGHT
] += value
*DrySend
[SIDE_RIGHT
];
881 WetBuffer
[j
][SIDE_RIGHT
] += value
*WetSend
[SIDE_RIGHT
];
886 DataPosFrac
+= increment
;
889 DataPosInt
+= (DataPosFrac
>>FRACTIONBITS
);
890 DataPosFrac
= (DataPosFrac
&FRACTIONMASK
);
893 ALSource
->position
= DataPosInt
;
894 ALSource
->position_fraction
= DataPosFrac
;
897 //Handle looping sources
898 if(!Buffer
|| DataPosInt
>= DataSize
)
903 Looping
= ALSource
->bLooping
;
904 if(ALSource
->BuffersPlayed
< (ALSource
->BuffersInQueue
-1))
906 BufferListItem
= ALSource
->queue
;
907 for(loop
= 0; loop
<= ALSource
->BuffersPlayed
; loop
++)
912 BufferListItem
->bufferstate
= PROCESSED
;
913 BufferListItem
= BufferListItem
->next
;
917 ALSource
->BuffersProcessed
++;
919 ALSource
->ulBufferID
= BufferListItem
->buffer
;
920 ALSource
->position
= DataPosInt
-DataSize
;
921 ALSource
->position_fraction
= DataPosFrac
;
922 ALSource
->BuffersPlayed
++;
929 ALSource
->state
= AL_STOPPED
;
930 ALSource
->inuse
= AL_FALSE
;
931 ALSource
->BuffersPlayed
= ALSource
->BuffersProcessed
= ALSource
->BuffersInQueue
;
932 BufferListItem
= ALSource
->queue
;
933 while(BufferListItem
!= NULL
)
935 BufferListItem
->bufferstate
= PROCESSED
;
936 BufferListItem
= BufferListItem
->next
;
943 ALSource
->state
= AL_PLAYING
;
944 ALSource
->inuse
= AL_TRUE
;
945 ALSource
->play
= AL_TRUE
;
946 ALSource
->BuffersPlayed
= 0;
947 ALSource
->BufferPosition
= 0;
948 ALSource
->lBytesPlayed
= 0;
949 ALSource
->BuffersProcessed
= 0;
950 BufferListItem
= ALSource
->queue
;
951 while(BufferListItem
!= NULL
)
953 BufferListItem
->bufferstate
= PENDING
;
954 BufferListItem
= BufferListItem
->next
;
956 ALSource
->ulBufferID
= ALSource
->queue
->buffer
;
958 ALSource
->position
= DataPosInt
-DataSize
;
959 ALSource
->position_fraction
= DataPosFrac
;
966 State
= ALSource
->state
;
969 ALSource
= ALSource
->next
;
972 ALEffectSlot
= (ALContext
? ALContext
->AuxiliaryEffectSlot
: NULL
);
975 if(ALEffectSlot
->effect
.type
== AL_EFFECT_REVERB
)
977 ALfloat
*DelayBuffer
= ALEffectSlot
->ReverbBuffer
;
978 ALuint Pos
= ALEffectSlot
->ReverbPos
;
979 ALuint LatePos
= ALEffectSlot
->ReverbLatePos
;
980 ALuint ReflectPos
= ALEffectSlot
->ReverbReflectPos
;
981 ALuint Length
= ALEffectSlot
->ReverbLength
;
982 ALfloat DecayGain
= ALEffectSlot
->ReverbDecayGain
;
983 ALfloat DecayHFRatio
= ALEffectSlot
->effect
.Reverb
.DecayHFRatio
;
984 ALfloat Gain
= ALEffectSlot
->effect
.Reverb
.Gain
;
985 ALfloat ReflectGain
= ALEffectSlot
->effect
.Reverb
.ReflectionsGain
;
986 ALfloat LateReverbGain
= ALEffectSlot
->effect
.Reverb
.LateReverbGain
;
987 ALfloat LastDecaySample
= ALEffectSlot
->LastDecaySample
;
990 for(i
= 0;i
< SamplesToDo
;i
++)
992 DelayBuffer
[Pos
] = ReverbBuffer
[i
] * Gain
;
994 sample
= DelayBuffer
[ReflectPos
] * ReflectGain
;
996 DelayBuffer
[LatePos
] *= LateReverbGain
;
998 Pos
= (Pos
+1) % Length
;
999 DelayBuffer
[Pos
] *= DecayHFRatio
;
1000 DelayBuffer
[Pos
] += LastDecaySample
* (1.0f
-DecayHFRatio
);
1001 LastDecaySample
= DelayBuffer
[Pos
];
1002 DelayBuffer
[Pos
] *= DecayGain
;
1004 DelayBuffer
[LatePos
] += DelayBuffer
[Pos
];
1006 sample
+= DelayBuffer
[LatePos
];
1008 WetBuffer
[i
][FRONT_LEFT
] += sample
;
1009 WetBuffer
[i
][FRONT_RIGHT
] += sample
;
1010 WetBuffer
[i
][SIDE_LEFT
] += sample
;
1011 WetBuffer
[i
][SIDE_RIGHT
] += sample
;
1012 WetBuffer
[i
][BACK_LEFT
] += sample
;
1013 WetBuffer
[i
][BACK_RIGHT
] += sample
;
1015 LatePos
= (LatePos
+1) % Length
;
1016 ReflectPos
= (ReflectPos
+1) % Length
;
1019 ALEffectSlot
->ReverbPos
= Pos
;
1020 ALEffectSlot
->ReverbLatePos
= LatePos
;
1021 ALEffectSlot
->ReverbReflectPos
= ReflectPos
;
1022 ALEffectSlot
->LastDecaySample
= LastDecaySample
;
1024 ALEffectSlot
= ALEffectSlot
->next
;
1027 //Post processing loop
1030 case AL_FORMAT_MONO8
:
1031 for(i
= 0;i
< SamplesToDo
;i
++)
1033 ((ALubyte
*)buffer
)[0] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_LEFT
]+DryBuffer
[i
][FRONT_RIGHT
]+
1034 WetBuffer
[i
][FRONT_LEFT
]+WetBuffer
[i
][FRONT_RIGHT
])>>8)+128);
1035 buffer
= ((ALubyte
*)buffer
) + 1;
1038 case AL_FORMAT_STEREO8
:
1039 if(ALContext
&& ALContext
->bs2b
)
1041 for(i
= 0;i
< SamplesToDo
;i
++)
1044 samples
[0] = DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
];
1045 samples
[1] = DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
];
1046 bs2b_cross_feed(ALContext
->bs2b
, samples
);
1047 ((ALubyte
*)buffer
)[0] = (ALubyte
)((aluF2S(samples
[0])>>8)+128);
1048 ((ALubyte
*)buffer
)[1] = (ALubyte
)((aluF2S(samples
[1])>>8)+128);
1049 buffer
= ((ALubyte
*)buffer
) + 2;
1054 for(i
= 0;i
< SamplesToDo
;i
++)
1056 ((ALubyte
*)buffer
)[0] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
])>>8)+128);
1057 ((ALubyte
*)buffer
)[1] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
])>>8)+128);
1058 buffer
= ((ALubyte
*)buffer
) + 2;
1062 case AL_FORMAT_QUAD8
:
1063 for(i
= 0;i
< SamplesToDo
;i
++)
1065 ((ALubyte
*)buffer
)[0] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
])>>8)+128);
1066 ((ALubyte
*)buffer
)[1] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
])>>8)+128);
1067 ((ALubyte
*)buffer
)[2] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
])>>8)+128);
1068 ((ALubyte
*)buffer
)[3] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
])>>8)+128);
1069 buffer
= ((ALubyte
*)buffer
) + 4;
1072 case AL_FORMAT_51CHN8
:
1073 for(i
= 0;i
< SamplesToDo
;i
++)
1075 ((ALubyte
*)buffer
)[0] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
])>>8)+128);
1076 ((ALubyte
*)buffer
)[1] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
])>>8)+128);
1077 ((ALubyte
*)buffer
)[2] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
])>>8)+128);
1078 ((ALubyte
*)buffer
)[3] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
])>>8)+128);
1079 ((ALubyte
*)buffer
)[4] = (ALubyte
)((aluF2S(DryBuffer
[i
][CENTER
] +WetBuffer
[i
][CENTER
])>>8)+128);
1080 ((ALubyte
*)buffer
)[5] = (ALubyte
)((aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
])>>8)+128);
1081 buffer
= ((ALubyte
*)buffer
) + 6;
1084 case AL_FORMAT_61CHN8
:
1085 for(i
= 0;i
< SamplesToDo
;i
++)
1087 ((ALubyte
*)buffer
)[0] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
])>>8)+128);
1088 ((ALubyte
*)buffer
)[1] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
])>>8)+128);
1089 ((ALubyte
*)buffer
)[2] = (ALubyte
)((aluF2S(DryBuffer
[i
][SIDE_LEFT
] +WetBuffer
[i
][SIDE_LEFT
])>>8)+128);
1090 ((ALubyte
*)buffer
)[3] = (ALubyte
)((aluF2S(DryBuffer
[i
][SIDE_RIGHT
] +WetBuffer
[i
][SIDE_RIGHT
])>>8)+128);
1091 ((ALubyte
*)buffer
)[4] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
])>>8)+128);
1092 ((ALubyte
*)buffer
)[5] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
])>>8)+128);
1093 ((ALubyte
*)buffer
)[6] = (ALubyte
)((aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
])>>8)+128);
1094 buffer
= ((ALubyte
*)buffer
) + 7;
1097 case AL_FORMAT_71CHN8
:
1098 for(i
= 0;i
< SamplesToDo
;i
++)
1100 ((ALubyte
*)buffer
)[0] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
])>>8)+128);
1101 ((ALubyte
*)buffer
)[1] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
])>>8)+128);
1102 ((ALubyte
*)buffer
)[2] = (ALubyte
)((aluF2S(DryBuffer
[i
][SIDE_LEFT
] +WetBuffer
[i
][SIDE_LEFT
])>>8)+128);
1103 ((ALubyte
*)buffer
)[3] = (ALubyte
)((aluF2S(DryBuffer
[i
][SIDE_RIGHT
] +WetBuffer
[i
][SIDE_RIGHT
])>>8)+128);
1104 ((ALubyte
*)buffer
)[4] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
])>>8)+128);
1105 ((ALubyte
*)buffer
)[5] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
])>>8)+128);
1106 ((ALubyte
*)buffer
)[6] = (ALubyte
)((aluF2S(DryBuffer
[i
][CENTER
] +WetBuffer
[i
][CENTER
])>>8)+128);
1107 ((ALubyte
*)buffer
)[7] = (ALubyte
)((aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
])>>8)+128);
1108 buffer
= ((ALubyte
*)buffer
) + 8;
1112 case AL_FORMAT_MONO16
:
1113 for(i
= 0;i
< SamplesToDo
;i
++)
1115 ((ALshort
*)buffer
)[0] = aluF2S(DryBuffer
[i
][FRONT_LEFT
]+DryBuffer
[i
][FRONT_RIGHT
]+
1116 WetBuffer
[i
][FRONT_LEFT
]+WetBuffer
[i
][FRONT_RIGHT
]);
1117 buffer
= ((ALshort
*)buffer
) + 1;
1120 case AL_FORMAT_STEREO16
:
1121 if(ALContext
&& ALContext
->bs2b
)
1123 for(i
= 0;i
< SamplesToDo
;i
++)
1126 samples
[0] = DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
];
1127 samples
[1] = DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
];
1128 bs2b_cross_feed(ALContext
->bs2b
, samples
);
1129 ((ALshort
*)buffer
)[0] = aluF2S(samples
[0]);
1130 ((ALshort
*)buffer
)[1] = aluF2S(samples
[1]);
1131 buffer
= ((ALshort
*)buffer
) + 2;
1136 for(i
= 0;i
< SamplesToDo
;i
++)
1138 ((ALshort
*)buffer
)[0] = aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
]);
1139 ((ALshort
*)buffer
)[1] = aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
]);
1140 buffer
= ((ALshort
*)buffer
) + 2;
1144 case AL_FORMAT_QUAD16
:
1145 for(i
= 0;i
< SamplesToDo
;i
++)
1147 ((ALshort
*)buffer
)[0] = aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
]);
1148 ((ALshort
*)buffer
)[1] = aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
]);
1149 ((ALshort
*)buffer
)[2] = aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
]);
1150 ((ALshort
*)buffer
)[3] = aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
]);
1151 buffer
= ((ALshort
*)buffer
) + 4;
1154 case AL_FORMAT_51CHN16
:
1155 for(i
= 0;i
< SamplesToDo
;i
++)
1157 ((ALshort
*)buffer
)[0] = aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
]);
1158 ((ALshort
*)buffer
)[1] = aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
]);
1159 ((ALshort
*)buffer
)[2] = aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
]);
1160 ((ALshort
*)buffer
)[3] = aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
]);
1161 ((ALshort
*)buffer
)[4] = aluF2S(DryBuffer
[i
][CENTER
] +WetBuffer
[i
][CENTER
]);
1162 ((ALshort
*)buffer
)[5] = aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
]);
1163 buffer
= ((ALshort
*)buffer
) + 6;
1166 case AL_FORMAT_61CHN16
:
1167 for(i
= 0;i
< SamplesToDo
;i
++)
1169 ((ALshort
*)buffer
)[0] = aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
]);
1170 ((ALshort
*)buffer
)[1] = aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
]);
1171 ((ALshort
*)buffer
)[2] = aluF2S(DryBuffer
[i
][SIDE_LEFT
] +WetBuffer
[i
][SIDE_LEFT
]);
1172 ((ALshort
*)buffer
)[3] = aluF2S(DryBuffer
[i
][SIDE_RIGHT
] +WetBuffer
[i
][SIDE_RIGHT
]);
1173 ((ALshort
*)buffer
)[4] = aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
]);
1174 ((ALshort
*)buffer
)[5] = aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
]);
1175 ((ALshort
*)buffer
)[6] = aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
]);
1176 buffer
= ((ALshort
*)buffer
) + 7;
1179 case AL_FORMAT_71CHN16
:
1180 for(i
= 0;i
< SamplesToDo
;i
++)
1182 ((ALshort
*)buffer
)[0] = aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
]);
1183 ((ALshort
*)buffer
)[1] = aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
]);
1184 ((ALshort
*)buffer
)[2] = aluF2S(DryBuffer
[i
][SIDE_LEFT
] +WetBuffer
[i
][SIDE_LEFT
]);
1185 ((ALshort
*)buffer
)[3] = aluF2S(DryBuffer
[i
][SIDE_RIGHT
] +WetBuffer
[i
][SIDE_RIGHT
]);
1186 ((ALshort
*)buffer
)[4] = aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
]);
1187 ((ALshort
*)buffer
)[5] = aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
]);
1188 ((ALshort
*)buffer
)[6] = aluF2S(DryBuffer
[i
][CENTER
] +WetBuffer
[i
][CENTER
]);
1189 ((ALshort
*)buffer
)[7] = aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
]);
1190 buffer
= ((ALshort
*)buffer
) + 8;
1198 size
-= SamplesToDo
;
1202 ProcessContext(ALContext
);