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 24000
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
:
166 static __inline ALfloat
lpFilter(FILTER
*iir
, ALfloat input
)
169 float *hist1_ptr
,*hist2_ptr
,*coef_ptr
;
170 ALfloat output
,new_hist
,history1
,history2
;
172 coef_ptr
= iir
->coef
; /* coefficient pointer */
174 hist1_ptr
= iir
->history
; /* first history */
175 hist2_ptr
= hist1_ptr
+ 1; /* next history */
177 /* 1st number of coefficients array is overall input scale factor,
179 output
= input
* (*coef_ptr
++);
181 for(i
= 0;i
< FILTER_SECTIONS
;i
++)
183 history1
= *hist1_ptr
; /* history values */
184 history2
= *hist2_ptr
;
186 output
= output
- history1
* (*coef_ptr
++);
187 new_hist
= output
- history2
* (*coef_ptr
++); /* poles */
189 output
= new_hist
+ history1
* (*coef_ptr
++);
190 output
= output
+ history2
* (*coef_ptr
++); /* zeros */
192 *hist2_ptr
++ = *hist1_ptr
;
193 *hist1_ptr
++ = new_hist
;
202 static __inline ALshort
aluF2S(ALfloat Value
)
207 i
= __min( 32767, i
);
208 i
= __max(-32768, i
);
212 static __inline ALvoid
aluCrossproduct(ALfloat
*inVector1
,ALfloat
*inVector2
,ALfloat
*outVector
)
214 outVector
[0] = inVector1
[1]*inVector2
[2] - inVector1
[2]*inVector2
[1];
215 outVector
[1] = inVector1
[2]*inVector2
[0] - inVector1
[0]*inVector2
[2];
216 outVector
[2] = inVector1
[0]*inVector2
[1] - inVector1
[1]*inVector2
[0];
219 static __inline ALfloat
aluDotproduct(ALfloat
*inVector1
,ALfloat
*inVector2
)
221 return inVector1
[0]*inVector2
[0] + inVector1
[1]*inVector2
[1] +
222 inVector1
[2]*inVector2
[2];
225 static __inline ALvoid
aluNormalize(ALfloat
*inVector
)
227 ALfloat length
, inverse_length
;
229 length
= aluSqrt(aluDotproduct(inVector
, inVector
));
232 inverse_length
= 1.0f
/length
;
233 inVector
[0] *= inverse_length
;
234 inVector
[1] *= inverse_length
;
235 inVector
[2] *= inverse_length
;
239 static __inline ALvoid
aluMatrixVector(ALfloat
*vector
,ALfloat matrix
[3][3])
243 result
[0] = vector
[0]*matrix
[0][0] + vector
[1]*matrix
[1][0] + vector
[2]*matrix
[2][0];
244 result
[1] = vector
[0]*matrix
[0][1] + vector
[1]*matrix
[1][1] + vector
[2]*matrix
[2][1];
245 result
[2] = vector
[0]*matrix
[0][2] + vector
[1]*matrix
[1][2] + vector
[2]*matrix
[2][2];
246 memcpy(vector
, result
, sizeof(result
));
249 static __inline ALfloat
aluComputeSample(ALfloat GainHF
, ALfloat sample
, ALfloat LowSample
)
251 return LowSample
+ ((sample
- LowSample
) * GainHF
);
254 static ALvoid
CalcSourceParams(ALCcontext
*ALContext
, ALsource
*ALSource
,
255 ALenum isMono
, ALenum OutputFormat
,
256 ALfloat
*drysend
, ALfloat
*wetsend
,
257 ALfloat
*pitch
, ALfloat
*drygainhf
,
260 ALfloat InnerAngle
,OuterAngle
,Angle
,Distance
,DryMix
,WetMix
=0.0f
;
261 ALfloat Direction
[3],Position
[3],SourceToListener
[3];
262 ALfloat MinVolume
,MaxVolume
,MinDist
,MaxDist
,Rolloff
,OuterGainHF
;
263 ALfloat ConeVolume
,SourceVolume
,PanningFB
,PanningLR
,ListenerGain
;
264 ALfloat U
[3],V
[3],N
[3];
265 ALfloat DopplerFactor
, DopplerVelocity
, flSpeedOfSound
, flMaxVelocity
;
266 ALfloat Matrix
[3][3];
267 ALfloat flAttenuation
;
268 ALfloat RoomAttenuation
;
269 ALfloat MetersPerUnit
;
271 ALfloat DryGainHF
= 1.0f
;
272 ALfloat WetGainHF
= 1.0f
;
274 //Get context properties
275 DopplerFactor
= ALContext
->DopplerFactor
* ALSource
->DopplerFactor
;
276 DopplerVelocity
= ALContext
->DopplerVelocity
;
277 flSpeedOfSound
= ALContext
->flSpeedOfSound
;
279 //Get listener properties
280 ListenerGain
= ALContext
->Listener
.Gain
;
281 MetersPerUnit
= ALContext
->Listener
.MetersPerUnit
;
283 //Get source properties
284 SourceVolume
= ALSource
->flGain
;
285 memcpy(Position
, ALSource
->vPosition
, sizeof(ALSource
->vPosition
));
286 memcpy(Direction
, ALSource
->vOrientation
, sizeof(ALSource
->vOrientation
));
287 MinVolume
= ALSource
->flMinGain
;
288 MaxVolume
= ALSource
->flMaxGain
;
289 MinDist
= ALSource
->flRefDistance
;
290 MaxDist
= ALSource
->flMaxDistance
;
291 Rolloff
= ALSource
->flRollOffFactor
;
292 InnerAngle
= ALSource
->flInnerAngle
;
293 OuterAngle
= ALSource
->flOuterAngle
;
294 OuterGainHF
= ALSource
->OuterGainHF
;
295 RoomRolloff
= ALSource
->RoomRolloffFactor
;
297 //Only apply 3D calculations for mono buffers
298 if(isMono
!= AL_FALSE
)
300 //1. Translate Listener to origin (convert to head relative)
301 // Note that Direction and SourceToListener are *not* transformed.
302 // SourceToListener is used with the source and listener velocities,
303 // which are untransformed, and Direction is used with SourceToListener
304 // for the sound cone
305 if(ALSource
->bHeadRelative
==AL_FALSE
)
307 // Build transform matrix
308 aluCrossproduct(ALContext
->Listener
.Forward
, ALContext
->Listener
.Up
, U
); // Right-vector
309 aluNormalize(U
); // Normalized Right-vector
310 memcpy(V
, ALContext
->Listener
.Up
, sizeof(V
)); // Up-vector
311 aluNormalize(V
); // Normalized Up-vector
312 memcpy(N
, ALContext
->Listener
.Forward
, sizeof(N
)); // At-vector
313 aluNormalize(N
); // Normalized At-vector
314 Matrix
[0][0] = U
[0]; Matrix
[0][1] = V
[0]; Matrix
[0][2] = -N
[0];
315 Matrix
[1][0] = U
[1]; Matrix
[1][1] = V
[1]; Matrix
[1][2] = -N
[1];
316 Matrix
[2][0] = U
[2]; Matrix
[2][1] = V
[2]; Matrix
[2][2] = -N
[2];
318 // Translate source position into listener space
319 Position
[0] -= ALContext
->Listener
.Position
[0];
320 Position
[1] -= ALContext
->Listener
.Position
[1];
321 Position
[2] -= ALContext
->Listener
.Position
[2];
323 SourceToListener
[0] = -Position
[0];
324 SourceToListener
[1] = -Position
[1];
325 SourceToListener
[2] = -Position
[2];
327 // Transform source position and direction into listener space
328 aluMatrixVector(Position
, Matrix
);
332 SourceToListener
[0] = -Position
[0];
333 SourceToListener
[1] = -Position
[1];
334 SourceToListener
[2] = -Position
[2];
336 aluNormalize(SourceToListener
);
337 aluNormalize(Direction
);
339 //2. Calculate distance attenuation
340 Distance
= aluSqrt(aluDotproduct(Position
, Position
));
342 if(ALSource
->Send
[0].Slot
&& !ALSource
->Send
[0].Slot
->AuxSendAuto
)
344 if(ALSource
->Send
[0].Slot
->effect
.type
== AL_EFFECT_REVERB
)
345 RoomRolloff
+= ALSource
->Send
[0].Slot
->effect
.Reverb
.RoomRolloffFactor
;
348 flAttenuation
= 1.0f
;
349 RoomAttenuation
= 1.0f
;
350 switch (ALContext
->DistanceModel
)
352 case AL_INVERSE_DISTANCE_CLAMPED
:
353 Distance
=__max(Distance
,MinDist
);
354 Distance
=__min(Distance
,MaxDist
);
355 if (MaxDist
< MinDist
)
358 case AL_INVERSE_DISTANCE
:
361 if ((MinDist
+ (Rolloff
* (Distance
- MinDist
))) > 0.0f
)
362 flAttenuation
= MinDist
/ (MinDist
+ (Rolloff
* (Distance
- MinDist
)));
363 if ((MinDist
+ (RoomRolloff
* (Distance
- MinDist
))) > 0.0f
)
364 RoomAttenuation
= MinDist
/ (MinDist
+ (RoomRolloff
* (Distance
- MinDist
)));
368 case AL_LINEAR_DISTANCE_CLAMPED
:
369 Distance
=__max(Distance
,MinDist
);
370 Distance
=__min(Distance
,MaxDist
);
371 if (MaxDist
< MinDist
)
374 case AL_LINEAR_DISTANCE
:
375 Distance
=__min(Distance
,MaxDist
);
376 if (MaxDist
!= MinDist
)
378 flAttenuation
= 1.0f
- (Rolloff
*(Distance
-MinDist
)/(MaxDist
- MinDist
));
379 RoomAttenuation
= 1.0f
- (RoomRolloff
*(Distance
-MinDist
)/(MaxDist
- MinDist
));
383 case AL_EXPONENT_DISTANCE_CLAMPED
:
384 Distance
=__max(Distance
,MinDist
);
385 Distance
=__min(Distance
,MaxDist
);
386 if (MaxDist
< MinDist
)
389 case AL_EXPONENT_DISTANCE
:
390 if ((Distance
> 0.0f
) && (MinDist
> 0.0f
))
392 flAttenuation
= (ALfloat
)pow(Distance
/MinDist
, -Rolloff
);
393 RoomAttenuation
= (ALfloat
)pow(Distance
/MinDist
, -RoomRolloff
);
399 flAttenuation
= 1.0f
;
400 RoomAttenuation
= 1.0f
;
404 // Source Gain + Attenuation and clamp to Min/Max Gain
405 DryMix
= SourceVolume
* flAttenuation
;
406 DryMix
= __min(DryMix
,MaxVolume
);
407 DryMix
= __max(DryMix
,MinVolume
);
409 WetMix
= SourceVolume
* (ALSource
->WetGainAuto
?
410 RoomAttenuation
: 1.0f
);
411 WetMix
= __min(WetMix
,MaxVolume
);
412 WetMix
= __max(WetMix
,MinVolume
);
414 //3. Apply directional soundcones
415 Angle
= aluAcos(aluDotproduct(Direction
,SourceToListener
)) * 180.0f
/
417 if(Angle
>= InnerAngle
&& Angle
<= OuterAngle
)
419 ALfloat scale
= (Angle
-InnerAngle
) / (OuterAngle
-InnerAngle
);
420 ConeVolume
= (1.0f
+(ALSource
->flOuterGain
-1.0f
)*scale
);
421 if(ALSource
->WetGainAuto
)
422 WetMix
*= ConeVolume
;
423 if(ALSource
->DryGainHFAuto
)
424 DryGainHF
*= (1.0f
+(OuterGainHF
-1.0f
)*scale
);
425 if(ALSource
->WetGainHFAuto
)
426 WetGainHF
*= (1.0f
+(OuterGainHF
-1.0f
)*scale
);
428 else if(Angle
> OuterAngle
)
430 ConeVolume
= (1.0f
+(ALSource
->flOuterGain
-1.0f
));
431 if(ALSource
->WetGainAuto
)
432 WetMix
*= ConeVolume
;
433 if(ALSource
->DryGainHFAuto
)
434 DryGainHF
*= (1.0f
+(OuterGainHF
-1.0f
));
435 if(ALSource
->WetGainHFAuto
)
436 WetGainHF
*= (1.0f
+(OuterGainHF
-1.0f
));
441 //4. Calculate Velocity
442 if(DopplerFactor
!= 0.0f
)
444 ALfloat flVSS
, flVLS
= 0.0f
;
446 if(ALSource
->bHeadRelative
==AL_FALSE
)
447 flVLS
= aluDotproduct(ALContext
->Listener
.Velocity
, SourceToListener
);
448 flVSS
= aluDotproduct(ALSource
->vVelocity
, SourceToListener
);
450 flMaxVelocity
= (DopplerVelocity
* flSpeedOfSound
) / DopplerFactor
;
452 if (flVSS
>= flMaxVelocity
)
453 flVSS
= (flMaxVelocity
- 1.0f
);
454 else if (flVSS
<= -flMaxVelocity
)
455 flVSS
= -flMaxVelocity
+ 1.0f
;
457 if (flVLS
>= flMaxVelocity
)
458 flVLS
= (flMaxVelocity
- 1.0f
);
459 else if (flVLS
<= -flMaxVelocity
)
460 flVLS
= -flMaxVelocity
+ 1.0f
;
462 pitch
[0] = ALSource
->flPitch
*
463 ((flSpeedOfSound
* DopplerVelocity
) - (DopplerFactor
* flVLS
)) /
464 ((flSpeedOfSound
* DopplerVelocity
) - (DopplerFactor
* flVSS
));
467 pitch
[0] = ALSource
->flPitch
;
469 //5. Apply filter gains and filters
470 switch(ALSource
->DirectFilter
.type
)
472 case AL_FILTER_LOWPASS
:
473 DryMix
*= ALSource
->DirectFilter
.Gain
;
474 DryGainHF
*= ALSource
->DirectFilter
.GainHF
;
478 switch(ALSource
->Send
[0].WetFilter
.type
)
480 case AL_FILTER_LOWPASS
:
481 WetMix
*= ALSource
->Send
[0].WetFilter
.Gain
;
482 WetGainHF
*= ALSource
->Send
[0].WetFilter
.GainHF
;
486 if(ALSource
->AirAbsorptionFactor
> 0.0f
)
487 DryGainHF
*= pow(ALSource
->AirAbsorptionFactor
* AIRABSORBGAINHF
,
488 Distance
* MetersPerUnit
);
490 if(ALSource
->Send
[0].Slot
)
492 WetMix
*= ALSource
->Send
[0].Slot
->Gain
;
494 if(ALSource
->Send
[0].Slot
->effect
.type
== AL_EFFECT_REVERB
)
496 WetMix
*= ALSource
->Send
[0].Slot
->effect
.Reverb
.Gain
;
497 WetGainHF
*= ALSource
->Send
[0].Slot
->effect
.Reverb
.GainHF
;
498 WetGainHF
*= pow(ALSource
->Send
[0].Slot
->effect
.Reverb
.AirAbsorptionGainHF
,
499 Distance
* MetersPerUnit
);
508 DryMix
*= ListenerGain
* ConeVolume
;
509 WetMix
*= ListenerGain
;
511 //6. Convert normalized position into pannings, then into channel volumes
512 aluNormalize(Position
);
513 switch(aluChannelsFromFormat(OutputFormat
))
517 PanningLR
= 0.5f
+ 0.5f
*Position
[0];
518 drysend
[FRONT_LEFT
] = DryMix
* aluSqrt(1.0f
-PanningLR
); //L Direct
519 drysend
[FRONT_RIGHT
] = DryMix
* aluSqrt( PanningLR
); //R Direct
520 drysend
[BACK_LEFT
] = drysend
[FRONT_LEFT
];
521 drysend
[BACK_RIGHT
] = drysend
[FRONT_RIGHT
];
522 drysend
[SIDE_LEFT
] = drysend
[FRONT_LEFT
];
523 drysend
[SIDE_RIGHT
] = drysend
[FRONT_RIGHT
];
524 wetsend
[FRONT_LEFT
] = WetMix
* aluSqrt(1.0f
-PanningLR
); //L Room
525 wetsend
[FRONT_RIGHT
] = WetMix
* aluSqrt( PanningLR
); //R Room
526 wetsend
[BACK_LEFT
] = wetsend
[FRONT_LEFT
];
527 wetsend
[BACK_RIGHT
] = wetsend
[FRONT_RIGHT
];
528 wetsend
[SIDE_LEFT
] = wetsend
[FRONT_LEFT
];
529 wetsend
[SIDE_RIGHT
] = wetsend
[FRONT_RIGHT
];
532 /* TODO: Add center/lfe channel in spatial calculations? */
534 // Apply a scalar so each individual speaker has more weight
535 PanningLR
= 0.5f
+ (0.5f
*Position
[0]*1.41421356f
);
536 PanningLR
= __min(1.0f
, PanningLR
);
537 PanningLR
= __max(0.0f
, PanningLR
);
538 PanningFB
= 0.5f
+ (0.5f
*Position
[2]*1.41421356f
);
539 PanningFB
= __min(1.0f
, PanningFB
);
540 PanningFB
= __max(0.0f
, PanningFB
);
541 drysend
[FRONT_LEFT
] = DryMix
* aluSqrt((1.0f
-PanningLR
)*(1.0f
-PanningFB
));
542 drysend
[FRONT_RIGHT
] = DryMix
* aluSqrt(( PanningLR
)*(1.0f
-PanningFB
));
543 drysend
[BACK_LEFT
] = DryMix
* aluSqrt((1.0f
-PanningLR
)*( PanningFB
));
544 drysend
[BACK_RIGHT
] = DryMix
* aluSqrt(( PanningLR
)*( PanningFB
));
545 drysend
[SIDE_LEFT
] = (drysend
[FRONT_LEFT
] +drysend
[BACK_LEFT
]) * 0.5f
;
546 drysend
[SIDE_RIGHT
] = (drysend
[FRONT_RIGHT
]+drysend
[BACK_RIGHT
]) * 0.5f
;
547 wetsend
[FRONT_LEFT
] = WetMix
* aluSqrt((1.0f
-PanningLR
)*(1.0f
-PanningFB
));
548 wetsend
[FRONT_RIGHT
] = WetMix
* aluSqrt(( PanningLR
)*(1.0f
-PanningFB
));
549 wetsend
[BACK_LEFT
] = WetMix
* aluSqrt((1.0f
-PanningLR
)*( PanningFB
));
550 wetsend
[BACK_RIGHT
] = WetMix
* aluSqrt(( PanningLR
)*( PanningFB
));
551 wetsend
[SIDE_LEFT
] = (wetsend
[FRONT_LEFT
] +wetsend
[BACK_LEFT
]) * 0.5f
;
552 wetsend
[SIDE_RIGHT
] = (wetsend
[FRONT_RIGHT
]+wetsend
[BACK_RIGHT
]) * 0.5f
;
556 PanningFB
= 1.0f
- fabs(Position
[2]*1.15470054f
);
557 PanningFB
= __min(1.0f
, PanningFB
);
558 PanningFB
= __max(0.0f
, PanningFB
);
559 PanningLR
= 0.5f
+ (0.5*Position
[0]*((1.0f
-PanningFB
)*2.0f
));
560 PanningLR
= __min(1.0f
, PanningLR
);
561 PanningLR
= __max(0.0f
, PanningLR
);
562 if(Position
[2] > 0.0f
)
564 drysend
[BACK_LEFT
] = DryMix
* aluSqrt((1.0f
-PanningLR
)*(1.0f
-PanningFB
));
565 drysend
[BACK_RIGHT
] = DryMix
* aluSqrt(( PanningLR
)*(1.0f
-PanningFB
));
566 drysend
[SIDE_LEFT
] = DryMix
* aluSqrt((1.0f
-PanningLR
)*( PanningFB
));
567 drysend
[SIDE_RIGHT
] = DryMix
* aluSqrt(( PanningLR
)*( PanningFB
));
568 drysend
[FRONT_LEFT
] = 0.0f
;
569 drysend
[FRONT_RIGHT
] = 0.0f
;
570 wetsend
[BACK_LEFT
] = WetMix
* aluSqrt((1.0f
-PanningLR
)*(1.0f
-PanningFB
));
571 wetsend
[BACK_RIGHT
] = WetMix
* aluSqrt(( PanningLR
)*(1.0f
-PanningFB
));
572 wetsend
[SIDE_LEFT
] = WetMix
* aluSqrt((1.0f
-PanningLR
)*( PanningFB
));
573 wetsend
[SIDE_RIGHT
] = WetMix
* aluSqrt(( PanningLR
)*( PanningFB
));
574 wetsend
[FRONT_LEFT
] = 0.0f
;
575 wetsend
[FRONT_RIGHT
] = 0.0f
;
579 drysend
[FRONT_LEFT
] = DryMix
* aluSqrt((1.0f
-PanningLR
)*(1.0f
-PanningFB
));
580 drysend
[FRONT_RIGHT
] = DryMix
* aluSqrt(( PanningLR
)*(1.0f
-PanningFB
));
581 drysend
[SIDE_LEFT
] = DryMix
* aluSqrt((1.0f
-PanningLR
)*( PanningFB
));
582 drysend
[SIDE_RIGHT
] = DryMix
* aluSqrt(( PanningLR
)*( PanningFB
));
583 drysend
[BACK_LEFT
] = 0.0f
;
584 drysend
[BACK_RIGHT
] = 0.0f
;
585 wetsend
[FRONT_LEFT
] = WetMix
* aluSqrt((1.0f
-PanningLR
)*(1.0f
-PanningFB
));
586 wetsend
[FRONT_RIGHT
] = WetMix
* aluSqrt(( PanningLR
)*(1.0f
-PanningFB
));
587 wetsend
[SIDE_LEFT
] = WetMix
* aluSqrt((1.0f
-PanningLR
)*( PanningFB
));
588 wetsend
[SIDE_RIGHT
] = WetMix
* aluSqrt(( PanningLR
)*( PanningFB
));
589 wetsend
[BACK_LEFT
] = 0.0f
;
590 wetsend
[BACK_RIGHT
] = 0.0f
;
596 *drygainhf
= DryGainHF
;
597 *wetgainhf
= WetGainHF
;
601 //1. Multi-channel buffers always play "normal"
602 pitch
[0] = ALSource
->flPitch
;
604 drysend
[FRONT_LEFT
] = SourceVolume
* ListenerGain
;
605 drysend
[FRONT_RIGHT
] = SourceVolume
* ListenerGain
;
606 drysend
[SIDE_LEFT
] = SourceVolume
* ListenerGain
;
607 drysend
[SIDE_RIGHT
] = SourceVolume
* ListenerGain
;
608 drysend
[BACK_LEFT
] = SourceVolume
* ListenerGain
;
609 drysend
[BACK_RIGHT
] = SourceVolume
* ListenerGain
;
610 drysend
[CENTER
] = SourceVolume
* ListenerGain
;
611 drysend
[LFE
] = SourceVolume
* ListenerGain
;
612 wetsend
[FRONT_LEFT
] = 0.0f
;
613 wetsend
[FRONT_RIGHT
] = 0.0f
;
614 wetsend
[SIDE_LEFT
] = 0.0f
;
615 wetsend
[SIDE_RIGHT
] = 0.0f
;
616 wetsend
[BACK_LEFT
] = 0.0f
;
617 wetsend
[BACK_RIGHT
] = 0.0f
;
618 wetsend
[CENTER
] = 0.0f
;
622 *drygainhf
= DryGainHF
;
623 *wetgainhf
= WetGainHF
;
627 ALvoid
aluMixData(ALCcontext
*ALContext
,ALvoid
*buffer
,ALsizei size
,ALenum format
)
629 static float DryBuffer
[BUFFERSIZE
][OUTPUTCHANNELS
];
630 static float WetBuffer
[BUFFERSIZE
][OUTPUTCHANNELS
];
631 ALfloat DrySend
[OUTPUTCHANNELS
] = { 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
};
632 ALfloat WetSend
[OUTPUTCHANNELS
] = { 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0.0f
};
633 ALfloat DryGainHF
= 0.0f
;
634 ALfloat WetGainHF
= 0.0f
;
635 ALuint BlockAlign
,BufferSize
;
636 ALuint DataSize
=0,DataPosInt
=0,DataPosFrac
=0;
637 ALuint Channels
,Frequency
,ulExtraSamples
;
640 ALint fraction
,increment
;
645 ALeffectslot
*ALEffectSlot
;
649 ALbufferlistitem
*BufferListItem
;
651 ALint64 DataSize64
,DataPos64
;
654 SuspendContext(ALContext
);
656 //Figure output format variables
657 BlockAlign
= aluChannelsFromFormat(format
);
658 BlockAlign
*= aluBytesFromFormat(format
);
664 ALEffectSlot
= (ALContext
? ALContext
->AuxiliaryEffectSlot
: NULL
);
665 ALSource
= (ALContext
? ALContext
->Source
: NULL
);
666 SamplesToDo
= min(size
, BUFFERSIZE
);
668 //Clear mixing buffer
669 memset(DryBuffer
, 0, SamplesToDo
*OUTPUTCHANNELS
*sizeof(ALfloat
));
670 memset(WetBuffer
, 0, SamplesToDo
*OUTPUTCHANNELS
*sizeof(ALfloat
));
676 State
= ALSource
->state
;
678 while(State
== AL_PLAYING
&& j
< SamplesToDo
)
685 if((Buffer
= ALSource
->ulBufferID
))
687 ALBuffer
= (ALbuffer
*)ALTHUNK_LOOKUPENTRY(Buffer
);
689 Data
= ALBuffer
->data
;
690 Channels
= aluChannelsFromFormat(ALBuffer
->format
);
691 DataSize
= ALBuffer
->size
;
692 Frequency
= ALBuffer
->frequency
;
694 CalcSourceParams(ALContext
, ALSource
,
695 (Channels
==1) ? AL_TRUE
: AL_FALSE
,
696 format
, DrySend
, WetSend
, &Pitch
,
697 &DryGainHF
, &WetGainHF
);
700 Pitch
= (Pitch
*Frequency
) / ALContext
->Frequency
;
701 DataSize
/= Channels
* aluBytesFromFormat(ALBuffer
->format
);
704 DataPosInt
= ALSource
->position
;
705 DataPosFrac
= ALSource
->position_fraction
;
706 Filter
= &ALSource
->iirFilter
;
708 //Compute 18.14 fixed point step
709 increment
= (ALint
)(Pitch
*(ALfloat
)(1L<<FRACTIONBITS
));
710 if(increment
> (MAX_PITCH
<<FRACTIONBITS
))
711 increment
= (MAX_PITCH
<<FRACTIONBITS
);
713 //Figure out how many samples we can mix.
714 DataSize64
= DataSize
;
715 DataSize64
<<= FRACTIONBITS
;
716 DataPos64
= DataPosInt
;
717 DataPos64
<<= FRACTIONBITS
;
718 DataPos64
+= DataPosFrac
;
719 BufferSize
= (ALuint
)((DataSize64
-DataPos64
+(increment
-1)) / increment
);
721 BufferListItem
= ALSource
->queue
;
722 for(loop
= 0; loop
< ALSource
->BuffersPlayed
; loop
++)
725 BufferListItem
= BufferListItem
->next
;
729 if (BufferListItem
->next
)
731 ALbuffer
*NextBuf
= (ALbuffer
*)ALTHUNK_LOOKUPENTRY(BufferListItem
->next
->buffer
);
732 if(NextBuf
&& NextBuf
->data
)
734 ulExtraSamples
= min(NextBuf
->size
, (ALint
)(ALBuffer
->padding
*Channels
*2));
735 memcpy(&Data
[DataSize
*Channels
], NextBuf
->data
, ulExtraSamples
);
738 else if (ALSource
->bLooping
)
740 ALbuffer
*NextBuf
= (ALbuffer
*)ALTHUNK_LOOKUPENTRY(ALSource
->queue
->buffer
);
741 if (NextBuf
&& NextBuf
->data
)
743 ulExtraSamples
= min(NextBuf
->size
, (ALint
)(ALBuffer
->padding
*Channels
*2));
744 memcpy(&Data
[DataSize
*Channels
], NextBuf
->data
, ulExtraSamples
);
748 BufferSize
= min(BufferSize
, (SamplesToDo
-j
));
750 //Actual sample mixing loop
751 Data
+= DataPosInt
*Channels
;
754 k
= DataPosFrac
>>FRACTIONBITS
;
755 fraction
= DataPosFrac
&FRACTIONMASK
;
759 ALfloat sample
, lowsamp
, outsamp
;
760 //First order interpolator
761 sample
= (Data
[k
]*((1<<FRACTIONBITS
)-fraction
) +
762 Data
[k
+1]*fraction
) >> FRACTIONBITS
;
763 lowsamp
= lpFilter(Filter
, sample
);
765 //Direct path final mix buffer and panning
766 outsamp
= aluComputeSample(DryGainHF
, sample
, lowsamp
);
767 DryBuffer
[j
][FRONT_LEFT
] += outsamp
*DrySend
[FRONT_LEFT
];
768 DryBuffer
[j
][FRONT_RIGHT
] += outsamp
*DrySend
[FRONT_RIGHT
];
769 DryBuffer
[j
][SIDE_LEFT
] += outsamp
*DrySend
[SIDE_LEFT
];
770 DryBuffer
[j
][SIDE_RIGHT
] += outsamp
*DrySend
[SIDE_RIGHT
];
771 DryBuffer
[j
][BACK_LEFT
] += outsamp
*DrySend
[BACK_LEFT
];
772 DryBuffer
[j
][BACK_RIGHT
] += outsamp
*DrySend
[BACK_RIGHT
];
773 //Room path final mix buffer and panning
774 outsamp
= aluComputeSample(WetGainHF
, sample
, lowsamp
);
775 WetBuffer
[j
][FRONT_LEFT
] += outsamp
*WetSend
[FRONT_LEFT
];
776 WetBuffer
[j
][FRONT_RIGHT
] += outsamp
*WetSend
[FRONT_RIGHT
];
777 WetBuffer
[j
][SIDE_LEFT
] += outsamp
*WetSend
[SIDE_LEFT
];
778 WetBuffer
[j
][SIDE_RIGHT
] += outsamp
*WetSend
[SIDE_RIGHT
];
779 WetBuffer
[j
][BACK_LEFT
] += outsamp
*WetSend
[BACK_LEFT
];
780 WetBuffer
[j
][BACK_RIGHT
] += outsamp
*WetSend
[BACK_RIGHT
];
784 ALfloat samp1
, samp2
;
785 //First order interpolator (front left)
786 samp1
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
]*(fraction
)))>>FRACTIONBITS
));
787 DryBuffer
[j
][FRONT_LEFT
] += samp1
*DrySend
[FRONT_LEFT
];
788 WetBuffer
[j
][FRONT_LEFT
] += samp1
*WetSend
[FRONT_LEFT
];
789 //First order interpolator (front right)
790 samp2
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+1]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+1]*(fraction
)))>>FRACTIONBITS
));
791 DryBuffer
[j
][FRONT_RIGHT
] += samp2
*DrySend
[FRONT_RIGHT
];
792 WetBuffer
[j
][FRONT_RIGHT
] += samp2
*WetSend
[FRONT_RIGHT
];
800 //First order interpolator (center)
801 value
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+i
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+i
]*(fraction
)))>>FRACTIONBITS
));
802 DryBuffer
[j
][CENTER
] += value
*DrySend
[CENTER
];
803 WetBuffer
[j
][CENTER
] += value
*WetSend
[CENTER
];
806 //First order interpolator (lfe)
807 value
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+i
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+i
]*(fraction
)))>>FRACTIONBITS
));
808 DryBuffer
[j
][LFE
] += value
*DrySend
[LFE
];
809 WetBuffer
[j
][LFE
] += value
*WetSend
[LFE
];
812 //First order interpolator (back left)
813 value
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+i
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+i
]*(fraction
)))>>FRACTIONBITS
));
814 DryBuffer
[j
][BACK_LEFT
] += value
*DrySend
[BACK_LEFT
];
815 WetBuffer
[j
][BACK_LEFT
] += value
*WetSend
[BACK_LEFT
];
817 //First order interpolator (back right)
818 value
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+i
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+i
]*(fraction
)))>>FRACTIONBITS
));
819 DryBuffer
[j
][BACK_RIGHT
] += value
*DrySend
[BACK_RIGHT
];
820 WetBuffer
[j
][BACK_RIGHT
] += value
*WetSend
[BACK_RIGHT
];
824 //First order interpolator (side left)
825 value
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+i
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+i
]*(fraction
)))>>FRACTIONBITS
));
826 DryBuffer
[j
][SIDE_LEFT
] += value
*DrySend
[SIDE_LEFT
];
827 WetBuffer
[j
][SIDE_LEFT
] += value
*WetSend
[SIDE_LEFT
];
829 //First order interpolator (side right)
830 value
= (ALfloat
)((ALshort
)(((Data
[k
*Channels
+i
]*((1L<<FRACTIONBITS
)-fraction
))+(Data
[(k
+1)*Channels
+i
]*(fraction
)))>>FRACTIONBITS
));
831 DryBuffer
[j
][SIDE_RIGHT
] += value
*DrySend
[SIDE_RIGHT
];
832 WetBuffer
[j
][SIDE_RIGHT
] += value
*WetSend
[SIDE_RIGHT
];
836 else if(DuplicateStereo
)
838 //Duplicate stereo channels on the back speakers
839 DryBuffer
[j
][BACK_LEFT
] += samp1
*DrySend
[BACK_LEFT
];
840 WetBuffer
[j
][BACK_LEFT
] += samp1
*WetSend
[BACK_LEFT
];
841 DryBuffer
[j
][BACK_RIGHT
] += samp2
*DrySend
[BACK_RIGHT
];
842 WetBuffer
[j
][BACK_RIGHT
] += samp2
*WetSend
[BACK_RIGHT
];
845 DataPosFrac
+= increment
;
848 DataPosInt
+= (DataPosFrac
>>FRACTIONBITS
);
849 DataPosFrac
= (DataPosFrac
&FRACTIONMASK
);
852 ALSource
->position
= DataPosInt
;
853 ALSource
->position_fraction
= DataPosFrac
;
856 //Handle looping sources
857 if(!Buffer
|| DataPosInt
>= DataSize
)
862 Looping
= ALSource
->bLooping
;
863 if(ALSource
->BuffersPlayed
< (ALSource
->BuffersInQueue
-1))
865 BufferListItem
= ALSource
->queue
;
866 for(loop
= 0; loop
<= ALSource
->BuffersPlayed
; loop
++)
871 BufferListItem
->bufferstate
= PROCESSED
;
872 BufferListItem
= BufferListItem
->next
;
876 ALSource
->BuffersProcessed
++;
878 ALSource
->ulBufferID
= BufferListItem
->buffer
;
879 ALSource
->position
= DataPosInt
-DataSize
;
880 ALSource
->position_fraction
= DataPosFrac
;
881 ALSource
->BuffersPlayed
++;
888 ALSource
->state
= AL_STOPPED
;
889 ALSource
->inuse
= AL_FALSE
;
890 ALSource
->BuffersPlayed
= ALSource
->BuffersProcessed
= ALSource
->BuffersInQueue
;
891 BufferListItem
= ALSource
->queue
;
892 while(BufferListItem
!= NULL
)
894 BufferListItem
->bufferstate
= PROCESSED
;
895 BufferListItem
= BufferListItem
->next
;
902 ALSource
->state
= AL_PLAYING
;
903 ALSource
->inuse
= AL_TRUE
;
904 ALSource
->play
= AL_TRUE
;
905 ALSource
->BuffersPlayed
= 0;
906 ALSource
->BufferPosition
= 0;
907 ALSource
->lBytesPlayed
= 0;
908 ALSource
->BuffersProcessed
= 0;
909 BufferListItem
= ALSource
->queue
;
910 while(BufferListItem
!= NULL
)
912 BufferListItem
->bufferstate
= PENDING
;
913 BufferListItem
= BufferListItem
->next
;
915 ALSource
->ulBufferID
= ALSource
->queue
->buffer
;
917 ALSource
->position
= DataPosInt
-DataSize
;
918 ALSource
->position_fraction
= DataPosFrac
;
925 State
= ALSource
->state
;
928 ALSource
= ALSource
->next
;
931 // effect slot processing
934 if(ALEffectSlot
->effect
.type
== AL_EFFECT_REVERB
)
936 ALfloat
*DelayBuffer
= ALEffectSlot
->ReverbBuffer
;
937 ALuint Pos
= ALEffectSlot
->ReverbPos
;
938 ALuint LatePos
= ALEffectSlot
->ReverbLatePos
;
939 ALuint ReflectPos
= ALEffectSlot
->ReverbReflectPos
;
940 ALuint Length
= ALEffectSlot
->ReverbLength
;
941 ALfloat DecayGain
= ALEffectSlot
->ReverbDecayGain
;
942 ALfloat DecayHFRatio
= ALEffectSlot
->effect
.Reverb
.DecayHFRatio
;
943 ALfloat ReflectGain
= ALEffectSlot
->effect
.Reverb
.ReflectionsGain
;
944 ALfloat LateReverbGain
= ALEffectSlot
->effect
.Reverb
.LateReverbGain
;
945 ALfloat sample
, lowsample
;
947 Filter
= &ALEffectSlot
->iirFilter
;
948 for(i
= 0;i
< SamplesToDo
;i
++)
950 sample
= WetBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][SIDE_LEFT
] +WetBuffer
[i
][BACK_LEFT
];
951 sample
+= WetBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][SIDE_RIGHT
]+WetBuffer
[i
][BACK_RIGHT
];
952 DelayBuffer
[Pos
] = sample
/ 6.0f
;
954 sample
= DelayBuffer
[ReflectPos
] * ReflectGain
;
956 DelayBuffer
[LatePos
] *= LateReverbGain
;
958 Pos
= (Pos
+1) % Length
;
959 lowsample
= lpFilter(Filter
, DelayBuffer
[Pos
]);
960 lowsample
+= (DelayBuffer
[Pos
]-lowsample
) * DecayHFRatio
;
962 DelayBuffer
[LatePos
] += lowsample
* DecayGain
;
964 sample
+= DelayBuffer
[LatePos
];
966 WetBuffer
[i
][FRONT_LEFT
] += sample
;
967 WetBuffer
[i
][FRONT_RIGHT
] += sample
;
968 WetBuffer
[i
][SIDE_LEFT
] += sample
;
969 WetBuffer
[i
][SIDE_RIGHT
] += sample
;
970 WetBuffer
[i
][BACK_LEFT
] += sample
;
971 WetBuffer
[i
][BACK_RIGHT
] += sample
;
973 LatePos
= (LatePos
+1) % Length
;
974 ReflectPos
= (ReflectPos
+1) % Length
;
977 ALEffectSlot
->ReverbPos
= Pos
;
978 ALEffectSlot
->ReverbLatePos
= LatePos
;
979 ALEffectSlot
->ReverbReflectPos
= ReflectPos
;
982 ALEffectSlot
= ALEffectSlot
->next
;
985 //Post processing loop
988 case AL_FORMAT_MONO8
:
989 for(i
= 0;i
< SamplesToDo
;i
++)
991 ((ALubyte
*)buffer
)[0] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_LEFT
]+DryBuffer
[i
][FRONT_RIGHT
]+
992 WetBuffer
[i
][FRONT_LEFT
]+WetBuffer
[i
][FRONT_RIGHT
])>>8)+128);
993 buffer
= ((ALubyte
*)buffer
) + 1;
996 case AL_FORMAT_STEREO8
:
997 if(ALContext
&& ALContext
->bs2b
)
999 for(i
= 0;i
< SamplesToDo
;i
++)
1002 samples
[0] = DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
];
1003 samples
[1] = DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
];
1004 bs2b_cross_feed(ALContext
->bs2b
, samples
);
1005 ((ALubyte
*)buffer
)[0] = (ALubyte
)((aluF2S(samples
[0])>>8)+128);
1006 ((ALubyte
*)buffer
)[1] = (ALubyte
)((aluF2S(samples
[1])>>8)+128);
1007 buffer
= ((ALubyte
*)buffer
) + 2;
1012 for(i
= 0;i
< SamplesToDo
;i
++)
1014 ((ALubyte
*)buffer
)[0] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
])>>8)+128);
1015 ((ALubyte
*)buffer
)[1] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
])>>8)+128);
1016 buffer
= ((ALubyte
*)buffer
) + 2;
1020 case AL_FORMAT_QUAD8
:
1021 for(i
= 0;i
< SamplesToDo
;i
++)
1023 ((ALubyte
*)buffer
)[0] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
])>>8)+128);
1024 ((ALubyte
*)buffer
)[1] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
])>>8)+128);
1025 ((ALubyte
*)buffer
)[2] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
])>>8)+128);
1026 ((ALubyte
*)buffer
)[3] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
])>>8)+128);
1027 buffer
= ((ALubyte
*)buffer
) + 4;
1030 case AL_FORMAT_51CHN8
:
1031 for(i
= 0;i
< SamplesToDo
;i
++)
1033 ((ALubyte
*)buffer
)[0] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
])>>8)+128);
1034 ((ALubyte
*)buffer
)[1] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
])>>8)+128);
1035 #ifdef _WIN32 /* Of course, Windows can't use the same ordering... */
1036 ((ALubyte
*)buffer
)[2] = (ALubyte
)((aluF2S(DryBuffer
[i
][CENTER
] +WetBuffer
[i
][CENTER
])>>8)+128);
1037 ((ALubyte
*)buffer
)[3] = (ALubyte
)((aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
])>>8)+128);
1038 ((ALubyte
*)buffer
)[4] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
])>>8)+128);
1039 ((ALubyte
*)buffer
)[5] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
])>>8)+128);
1041 ((ALubyte
*)buffer
)[2] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
])>>8)+128);
1042 ((ALubyte
*)buffer
)[3] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
])>>8)+128);
1043 ((ALubyte
*)buffer
)[4] = (ALubyte
)((aluF2S(DryBuffer
[i
][CENTER
] +WetBuffer
[i
][CENTER
])>>8)+128);
1044 ((ALubyte
*)buffer
)[5] = (ALubyte
)((aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
])>>8)+128);
1046 buffer
= ((ALubyte
*)buffer
) + 6;
1049 case AL_FORMAT_61CHN8
:
1050 for(i
= 0;i
< SamplesToDo
;i
++)
1052 ((ALubyte
*)buffer
)[0] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
])>>8)+128);
1053 ((ALubyte
*)buffer
)[1] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
])>>8)+128);
1055 ((ALubyte
*)buffer
)[2] = (ALubyte
)((aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
])>>8)+128);
1056 ((ALubyte
*)buffer
)[3] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
])>>8)+128);
1057 ((ALubyte
*)buffer
)[4] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
])>>8)+128);
1059 ((ALubyte
*)buffer
)[2] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
])>>8)+128);
1060 ((ALubyte
*)buffer
)[3] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
])>>8)+128);
1061 ((ALubyte
*)buffer
)[4] = (ALubyte
)((aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
])>>8)+128);
1063 ((ALubyte
*)buffer
)[5] = (ALubyte
)((aluF2S(DryBuffer
[i
][SIDE_LEFT
] +WetBuffer
[i
][SIDE_LEFT
])>>8)+128);
1064 ((ALubyte
*)buffer
)[6] = (ALubyte
)((aluF2S(DryBuffer
[i
][SIDE_RIGHT
] +WetBuffer
[i
][SIDE_RIGHT
])>>8)+128);
1065 buffer
= ((ALubyte
*)buffer
) + 7;
1068 case AL_FORMAT_71CHN8
:
1069 for(i
= 0;i
< SamplesToDo
;i
++)
1071 ((ALubyte
*)buffer
)[0] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
])>>8)+128);
1072 ((ALubyte
*)buffer
)[1] = (ALubyte
)((aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
])>>8)+128);
1074 ((ALubyte
*)buffer
)[2] = (ALubyte
)((aluF2S(DryBuffer
[i
][CENTER
] +WetBuffer
[i
][CENTER
])>>8)+128);
1075 ((ALubyte
*)buffer
)[3] = (ALubyte
)((aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
])>>8)+128);
1076 ((ALubyte
*)buffer
)[4] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
])>>8)+128);
1077 ((ALubyte
*)buffer
)[5] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
])>>8)+128);
1079 ((ALubyte
*)buffer
)[2] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
])>>8)+128);
1080 ((ALubyte
*)buffer
)[3] = (ALubyte
)((aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
])>>8)+128);
1081 ((ALubyte
*)buffer
)[4] = (ALubyte
)((aluF2S(DryBuffer
[i
][CENTER
] +WetBuffer
[i
][CENTER
])>>8)+128);
1082 ((ALubyte
*)buffer
)[5] = (ALubyte
)((aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
])>>8)+128);
1084 ((ALubyte
*)buffer
)[6] = (ALubyte
)((aluF2S(DryBuffer
[i
][SIDE_LEFT
] +WetBuffer
[i
][SIDE_LEFT
])>>8)+128);
1085 ((ALubyte
*)buffer
)[7] = (ALubyte
)((aluF2S(DryBuffer
[i
][SIDE_RIGHT
] +WetBuffer
[i
][SIDE_RIGHT
])>>8)+128);
1086 buffer
= ((ALubyte
*)buffer
) + 8;
1090 case AL_FORMAT_MONO16
:
1091 for(i
= 0;i
< SamplesToDo
;i
++)
1093 ((ALshort
*)buffer
)[0] = aluF2S(DryBuffer
[i
][FRONT_LEFT
]+DryBuffer
[i
][FRONT_RIGHT
]+
1094 WetBuffer
[i
][FRONT_LEFT
]+WetBuffer
[i
][FRONT_RIGHT
]);
1095 buffer
= ((ALshort
*)buffer
) + 1;
1098 case AL_FORMAT_STEREO16
:
1099 if(ALContext
&& ALContext
->bs2b
)
1101 for(i
= 0;i
< SamplesToDo
;i
++)
1104 samples
[0] = DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
];
1105 samples
[1] = DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
];
1106 bs2b_cross_feed(ALContext
->bs2b
, samples
);
1107 ((ALshort
*)buffer
)[0] = aluF2S(samples
[0]);
1108 ((ALshort
*)buffer
)[1] = aluF2S(samples
[1]);
1109 buffer
= ((ALshort
*)buffer
) + 2;
1114 for(i
= 0;i
< SamplesToDo
;i
++)
1116 ((ALshort
*)buffer
)[0] = aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
]);
1117 ((ALshort
*)buffer
)[1] = aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
]);
1118 buffer
= ((ALshort
*)buffer
) + 2;
1122 case AL_FORMAT_QUAD16
:
1123 for(i
= 0;i
< SamplesToDo
;i
++)
1125 ((ALshort
*)buffer
)[0] = aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
]);
1126 ((ALshort
*)buffer
)[1] = aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
]);
1127 ((ALshort
*)buffer
)[2] = aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
]);
1128 ((ALshort
*)buffer
)[3] = aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
]);
1129 buffer
= ((ALshort
*)buffer
) + 4;
1132 case AL_FORMAT_51CHN16
:
1133 for(i
= 0;i
< SamplesToDo
;i
++)
1135 ((ALshort
*)buffer
)[0] = aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
]);
1136 ((ALshort
*)buffer
)[1] = aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
]);
1138 ((ALshort
*)buffer
)[2] = aluF2S(DryBuffer
[i
][CENTER
] +WetBuffer
[i
][CENTER
]);
1139 ((ALshort
*)buffer
)[3] = aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
]);
1140 ((ALshort
*)buffer
)[4] = aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
]);
1141 ((ALshort
*)buffer
)[5] = aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
]);
1143 ((ALshort
*)buffer
)[2] = aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
]);
1144 ((ALshort
*)buffer
)[3] = aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
]);
1145 ((ALshort
*)buffer
)[4] = aluF2S(DryBuffer
[i
][CENTER
] +WetBuffer
[i
][CENTER
]);
1146 ((ALshort
*)buffer
)[5] = aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
]);
1148 buffer
= ((ALshort
*)buffer
) + 6;
1151 case AL_FORMAT_61CHN16
:
1152 for(i
= 0;i
< SamplesToDo
;i
++)
1154 ((ALshort
*)buffer
)[0] = aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
]);
1155 ((ALshort
*)buffer
)[1] = aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
]);
1157 ((ALshort
*)buffer
)[2] = aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
]);
1158 ((ALshort
*)buffer
)[3] = aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
]);
1159 ((ALshort
*)buffer
)[4] = aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
]);
1161 ((ALshort
*)buffer
)[2] = aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
]);
1162 ((ALshort
*)buffer
)[3] = aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
]);
1163 ((ALshort
*)buffer
)[4] = aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
]);
1165 ((ALshort
*)buffer
)[5] = aluF2S(DryBuffer
[i
][SIDE_LEFT
] +WetBuffer
[i
][SIDE_LEFT
]);
1166 ((ALshort
*)buffer
)[6] = aluF2S(DryBuffer
[i
][SIDE_RIGHT
] +WetBuffer
[i
][SIDE_RIGHT
]);
1167 buffer
= ((ALshort
*)buffer
) + 7;
1170 case AL_FORMAT_71CHN16
:
1171 for(i
= 0;i
< SamplesToDo
;i
++)
1173 ((ALshort
*)buffer
)[0] = aluF2S(DryBuffer
[i
][FRONT_LEFT
] +WetBuffer
[i
][FRONT_LEFT
]);
1174 ((ALshort
*)buffer
)[1] = aluF2S(DryBuffer
[i
][FRONT_RIGHT
]+WetBuffer
[i
][FRONT_RIGHT
]);
1176 ((ALshort
*)buffer
)[2] = aluF2S(DryBuffer
[i
][CENTER
] +WetBuffer
[i
][CENTER
]);
1177 ((ALshort
*)buffer
)[3] = aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
]);
1178 ((ALshort
*)buffer
)[4] = aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
]);
1179 ((ALshort
*)buffer
)[5] = aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
]);
1181 ((ALshort
*)buffer
)[2] = aluF2S(DryBuffer
[i
][BACK_LEFT
] +WetBuffer
[i
][BACK_LEFT
]);
1182 ((ALshort
*)buffer
)[3] = aluF2S(DryBuffer
[i
][BACK_RIGHT
] +WetBuffer
[i
][BACK_RIGHT
]);
1183 ((ALshort
*)buffer
)[4] = aluF2S(DryBuffer
[i
][CENTER
] +WetBuffer
[i
][CENTER
]);
1184 ((ALshort
*)buffer
)[5] = aluF2S(DryBuffer
[i
][LFE
] +WetBuffer
[i
][LFE
]);
1186 ((ALshort
*)buffer
)[6] = aluF2S(DryBuffer
[i
][SIDE_LEFT
] +WetBuffer
[i
][SIDE_LEFT
]);
1187 ((ALshort
*)buffer
)[7] = aluF2S(DryBuffer
[i
][SIDE_RIGHT
] +WetBuffer
[i
][SIDE_RIGHT
]);
1188 buffer
= ((ALshort
*)buffer
) + 8;
1196 size
-= SamplesToDo
;
1199 ProcessContext(ALContext
);