zenilib: zenilib/jni/external/openal-soft/Alc/ALu.c Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ALu.c
Go to the documentation of this file.
1
21 #include "config.h"
22
23 #include <math.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <assert.h>
28
29 #include "alMain.h"
30 #include "alSource.h"
31 #include "alBuffer.h"
32 #include "alListener.h"
33 #include "alAuxEffectSlot.h"
34 #include "alu.h"
35 #include "bs2b.h"
36
37 #include "mixer_defs.h"
38
39
40 struct ChanMap {
41 enum Channel channel;
42 ALfloat angle;
43 };
44
45 /* Cone scalar */
46 ALfloat ConeScale = 1.0f;
47
48 /* Localized Z scalar for mono sources */
49 ALfloat ZScale = 1.0f;
50
51
52 static ResamplerFunc SelectResampler(enum Resampler Resampler, ALuint increment)
53 {
54 if(increment == FRACTIONONE)
55 return Resample_copy32_C;
56 switch(Resampler)
57 {
58 case PointResampler:
59 return Resample_point32_C;
60 case LinearResampler:
61 return Resample_lerp32_C;
62 case CubicResampler:
63 return Resample_cubic32_C;
64 case ResamplerMax:
65 /* Shouldn't happen */
66 break;
67 }
68
69 return Resample_point32_C;
70 }
71
72
73 static DryMixerFunc SelectHrtfMixer(void)
74 {
75 #ifdef HAVE_SSE
76 if((CPUCapFlags&CPU_CAP_SSE))
77 return MixDirect_Hrtf_SSE;
78 #endif
79 #ifdef HAVE_NEON
80 if((CPUCapFlags&CPU_CAP_NEON))
81 return MixDirect_Hrtf_Neon;
82 #endif
83
84 return MixDirect_Hrtf_C;
85 }
86
87 static DryMixerFunc SelectDirectMixer(void)
88 {
89 #ifdef HAVE_SSE
90 if((CPUCapFlags&CPU_CAP_SSE))
91 return MixDirect_SSE;
92 #endif
93
94 return MixDirect_C;
95 }
96
97 static WetMixerFunc SelectSendMixer(void)
98 {
99 #ifdef HAVE_SSE
100 if((CPUCapFlags&CPU_CAP_SSE))
101 return MixSend_SSE;
102 #endif
103
104 return MixSend_C;
105 }
106
107
108 static __inline void aluCrossproduct(const ALfloat *inVector1, const ALfloat *inVector2, ALfloat *outVector)
109 {
110 outVector[0] = inVector1[1]*inVector2[2] - inVector1[2]*inVector2[1];
111 outVector[1] = inVector1[2]*inVector2[0] - inVector1[0]*inVector2[2];
112 outVector[2] = inVector1[0]*inVector2[1] - inVector1[1]*inVector2[0];
113 }
114
115 static __inline ALfloat aluDotproduct(const ALfloat *inVector1, const ALfloat *inVector2)
116 {
117 return inVector1[0]*inVector2[0] + inVector1[1]*inVector2[1] +
118 inVector1[2]*inVector2[2];
119 }
120
121 static __inline void aluNormalize(ALfloat *inVector)
122 {
123 ALfloat lengthsqr = aluDotproduct(inVector, inVector);
124 if(lengthsqr > 0.0f)
125 {
126 ALfloat inv_length = 1.0f/sqrtf(lengthsqr);
127 inVector[0] *= inv_length;
128 inVector[1] *= inv_length;
129 inVector[2] *= inv_length;
130 }
131 }
132
133 static __inline ALvoid aluMatrixVector(ALfloat *vector, ALfloat w, ALfloat (*RESTRICT matrix)[4])
134 {
135 ALfloat temp[4] = {
136 vector[0], vector[1], vector[2], w
137 };
138
139 vector[0] = temp[0]*matrix[0][0] + temp[1]*matrix[1][0] + temp[2]*matrix[2][0] + temp[3]*matrix[3][0];
140 vector[1] = temp[0]*matrix[0][1] + temp[1]*matrix[1][1] + temp[2]*matrix[2][1] + temp[3]*matrix[3][1];
141 vector[2] = temp[0]*matrix[0][2] + temp[1]*matrix[1][2] + temp[2]*matrix[2][2] + temp[3]*matrix[3][2];
142 }
143
144
145 static ALvoid CalcListenerParams(ALlistener *Listener)
146 {
147 ALfloat N[3], V[3], U[3], P[3];
148
149 /* AT then UP */
150 N[0] = Listener->Forward[0];
151 N[1] = Listener->Forward[1];
152 N[2] = Listener->Forward[2];
153 aluNormalize(N);
154 V[0] = Listener->Up[0];
155 V[1] = Listener->Up[1];
156 V[2] = Listener->Up[2];
157 aluNormalize(V);
158 /* Build and normalize right-vector */
159 aluCrossproduct(N, V, U);
160 aluNormalize(U);
161
162 Listener->Params.Matrix[0][0] = U[0];
163 Listener->Params.Matrix[0][1] = V[0];
164 Listener->Params.Matrix[0][2] = -N[0];
165 Listener->Params.Matrix[0][3] = 0.0f;
166 Listener->Params.Matrix[1][0] = U[1];
167 Listener->Params.Matrix[1][1] = V[1];
168 Listener->Params.Matrix[1][2] = -N[1];
169 Listener->Params.Matrix[1][3] = 0.0f;
170 Listener->Params.Matrix[2][0] = U[2];
171 Listener->Params.Matrix[2][1] = V[2];
172 Listener->Params.Matrix[2][2] = -N[2];
173 Listener->Params.Matrix[2][3] = 0.0f;
174 Listener->Params.Matrix[3][0] = 0.0f;
175 Listener->Params.Matrix[3][1] = 0.0f;
176 Listener->Params.Matrix[3][2] = 0.0f;
177 Listener->Params.Matrix[3][3] = 1.0f;
178
179 P[0] = Listener->Position[0];
180 P[1] = Listener->Position[1];
181 P[2] = Listener->Position[2];
182 aluMatrixVector(P, 1.0f, Listener->Params.Matrix);
183 Listener->Params.Matrix[3][0] = -P[0];
184 Listener->Params.Matrix[3][1] = -P[1];
185 Listener->Params.Matrix[3][2] = -P[2];
186
187 Listener->Params.Velocity[0] = Listener->Velocity[0];
188 Listener->Params.Velocity[1] = Listener->Velocity[1];
189 Listener->Params.Velocity[2] = Listener->Velocity[2];
190 aluMatrixVector(Listener->Params.Velocity, 0.0f, Listener->Params.Matrix);
191 }
192
193 ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
194 {
195 static const struct ChanMap MonoMap[1] = { { FrontCenter, 0.0f } };
196 static const struct ChanMap StereoMap[2] = {
197 { FrontLeft, -30.0f * F_PI/180.0f },
198 { FrontRight, 30.0f * F_PI/180.0f }
199 };
200 static const struct ChanMap StereoWideMap[2] = {
201 { FrontLeft, -90.0f * F_PI/180.0f },
202 { FrontRight, 90.0f * F_PI/180.0f }
203 };
204 static const struct ChanMap RearMap[2] = {
205 { BackLeft, -150.0f * F_PI/180.0f },
206 { BackRight, 150.0f * F_PI/180.0f }
207 };
208 static const struct ChanMap QuadMap[4] = {
209 { FrontLeft, -45.0f * F_PI/180.0f },
210 { FrontRight, 45.0f * F_PI/180.0f },
211 { BackLeft, -135.0f * F_PI/180.0f },
212 { BackRight, 135.0f * F_PI/180.0f }
213 };
214 static const struct ChanMap X51Map[6] = {
215 { FrontLeft, -30.0f * F_PI/180.0f },
216 { FrontRight, 30.0f * F_PI/180.0f },
217 { FrontCenter, 0.0f * F_PI/180.0f },
218 { LFE, 0.0f },
219 { BackLeft, -110.0f * F_PI/180.0f },
220 { BackRight, 110.0f * F_PI/180.0f }
221 };
222 static const struct ChanMap X61Map[7] = {
223 { FrontLeft, -30.0f * F_PI/180.0f },
224 { FrontRight, 30.0f * F_PI/180.0f },
225 { FrontCenter, 0.0f * F_PI/180.0f },
226 { LFE, 0.0f },
227 { BackCenter, 180.0f * F_PI/180.0f },
228 { SideLeft, -90.0f * F_PI/180.0f },
229 { SideRight, 90.0f * F_PI/180.0f }
230 };
231 static const struct ChanMap X71Map[8] = {
232 { FrontLeft, -30.0f * F_PI/180.0f },
233 { FrontRight, 30.0f * F_PI/180.0f },
234 { FrontCenter, 0.0f * F_PI/180.0f },
235 { LFE, 0.0f },
236 { BackLeft, -150.0f * F_PI/180.0f },
237 { BackRight, 150.0f * F_PI/180.0f },
238 { SideLeft, -90.0f * F_PI/180.0f },
239 { SideRight, 90.0f * F_PI/180.0f }
240 };
241
242 ALCdevice *Device = ALContext->Device;
243 ALfloat SourceVolume,ListenerGain,MinVolume,MaxVolume;
244 ALbufferlistitem *BufferListItem;
245 enum FmtChannels Channels;
246 ALfloat (*SrcMatrix)[MaxChannels];
247 ALfloat DryGain, DryGainHF;
248 ALfloat WetGain[MAX_SENDS];
249 ALfloat WetGainHF[MAX_SENDS];
250 ALint NumSends, Frequency;
251 const struct ChanMap *chans = NULL;
252 enum Resampler Resampler;
253 ALint num_channels = 0;
254 ALboolean DirectChannels;
255 ALfloat hwidth = 0.0f;
256 ALfloat Pitch;
257 ALfloat cw;
258 ALint i, c;
259
260 /* Get device properties */
261 NumSends = Device->NumAuxSends;
262 Frequency = Device->Frequency;
263
264 /* Get listener properties */
265 ListenerGain = ALContext->Listener->Gain;
266
267 /* Get source properties */
268 SourceVolume = ALSource->Gain;
269 MinVolume = ALSource->MinGain;
270 MaxVolume = ALSource->MaxGain;
271 Pitch = ALSource->Pitch;
272 Resampler = ALSource->Resampler;
273 DirectChannels = ALSource->DirectChannels;
274
275 /* Calculate the stepping value */
276 Channels = FmtMono;
277 BufferListItem = ALSource->queue;
278 while(BufferListItem != NULL)
279 {
280 ALbuffer *ALBuffer;
281 if((ALBuffer=BufferListItem->buffer) != NULL)
282 {
283 ALsizei maxstep = BUFFERSIZE;
284 maxstep -= ResamplerPadding[Resampler] +
285 ResamplerPrePadding[Resampler] + 1;
286 maxstep = mini(maxstep, INT_MAX>>FRACTIONBITS);
287
288 Pitch = Pitch * ALBuffer->Frequency / Frequency;
289 if(Pitch > (ALfloat)maxstep)
290 ALSource->Params.Step = maxstep<<FRACTIONBITS;
291 else
292 {
293 ALSource->Params.Step = fastf2i(Pitch*FRACTIONONE);
294 if(ALSource->Params.Step == 0)
295 ALSource->Params.Step = 1;
296 }
297 ALSource->Params.Resample = SelectResampler(Resampler, ALSource->Params.Step);
298
299 Channels = ALBuffer->FmtChannels;
300 break;
301 }
302 BufferListItem = BufferListItem->next;
303 }
304 if(!DirectChannels && Device->Hrtf)
305 ALSource->Params.DryMix = SelectHrtfMixer();
306 else
307 ALSource->Params.DryMix = SelectDirectMixer();
308 ALSource->Params.WetMix = SelectSendMixer();
309
310 /* Calculate gains */
311 DryGain = clampf(SourceVolume, MinVolume, MaxVolume);
312 DryGain *= ALSource->DirectGain * ListenerGain;
313 DryGainHF = ALSource->DirectGainHF;
314 for(i = 0;i < NumSends;i++)
315 {
316 WetGain[i] = clampf(SourceVolume, MinVolume, MaxVolume);
317 WetGain[i] *= ALSource->Send[i].Gain * ListenerGain;
318 WetGainHF[i] = ALSource->Send[i].GainHF;
319 }
320
321 SrcMatrix = ALSource->Params.Direct.Gains;
322 for(i = 0;i < MaxChannels;i++)
323 {
324 for(c = 0;c < MaxChannels;c++)
325 SrcMatrix[i][c] = 0.0f;
326 }
327 switch(Channels)
328 {
329 case FmtMono:
330 chans = MonoMap;
331 num_channels = 1;
332 break;
333
334 case FmtStereo:
335 if(!(Device->Flags&DEVICE_WIDE_STEREO))
336 {
337 /* HACK: Place the stereo channels at +/-90 degrees when using non-
338 * HRTF stereo output. This helps reduce the "monoization" caused
339 * by them panning towards the center. */
340 if(Device->FmtChans == DevFmtStereo && !Device->Hrtf)
341 chans = StereoWideMap;
342 else
343 chans = StereoMap;
344 }
345 else
346 {
347 chans = StereoWideMap;
348 hwidth = 60.0f * F_PI/180.0f;
349 }
350 num_channels = 2;
351 break;
352
353 case FmtRear:
354 chans = RearMap;
355 num_channels = 2;
356 break;
357
358 case FmtQuad:
359 chans = QuadMap;
360 num_channels = 4;
361 break;
362
363 case FmtX51:
364 chans = X51Map;
365 num_channels = 6;
366 break;
367
368 case FmtX61:
369 chans = X61Map;
370 num_channels = 7;
371 break;
372
373 case FmtX71:
374 chans = X71Map;
375 num_channels = 8;
376 break;
377 }
378
379 if(DirectChannels != AL_FALSE)
380 {
381 for(c = 0;c < num_channels;c++)
382 {
383 for(i = 0;i < (ALint)Device->NumChan;i++)
384 {
385 enum Channel chan = Device->Speaker2Chan[i];
386 if(chan == chans[c].channel)
387 {
388 SrcMatrix[c][chan] = DryGain;
389 break;
390 }
391 }
392 }
393 }
394 else if(Device->Hrtf)
395 {
396 for(c = 0;c < num_channels;c++)
397 {
398 if(chans[c].channel == LFE)
399 {
400 /* Skip LFE */
401 ALSource->Params.Direct.Hrtf.Params.Delay[c][0] = 0;
402 ALSource->Params.Direct.Hrtf.Params.Delay[c][1] = 0;
403 for(i = 0;i < HRIR_LENGTH;i++)
404 {
405 ALSource->Params.Direct.Hrtf.Params.Coeffs[c][i][0] = 0.0f;
406 ALSource->Params.Direct.Hrtf.Params.Coeffs[c][i][1] = 0.0f;
407 }
408 }
409 else
410 {
411 /* Get the static HRIR coefficients and delays for this
412 * channel. */
413 GetLerpedHrtfCoeffs(Device->Hrtf,
414 0.0f, chans[c].angle, DryGain,
415 ALSource->Params.Direct.Hrtf.Params.Coeffs[c],
416 ALSource->Params.Direct.Hrtf.Params.Delay[c]);
417 }
418 }
419 ALSource->Hrtf.Counter = 0;
420 ALSource->Params.Direct.Hrtf.Params.IrSize = GetHrtfIrSize(Device->Hrtf);
421
422 ALSource->Params.Direct.Hrtf.State = &ALSource->Hrtf;
423 }
424 else
425 {
426 DryGain *= lerp(1.0f, 1.0f/sqrtf((float)Device->NumChan), hwidth/F_PI);
427 for(c = 0;c < num_channels;c++)
428 {
429 /* Special-case LFE */
430 if(chans[c].channel == LFE)
431 {
432 SrcMatrix[c][chans[c].channel] = DryGain;
433 continue;
434 }
435 ComputeAngleGains(Device, chans[c].angle, hwidth, DryGain,
436 SrcMatrix[c]);
437 }
438 }
439
440 ALSource->Params.Direct.OutBuffer = Device->DryBuffer;
441 ALSource->Params.Direct.ClickRemoval = Device->ClickRemoval;
442 ALSource->Params.Direct.PendingClicks = Device->PendingClicks;
443 for(i = 0;i < NumSends;i++)
444 {
445 ALeffectslot *Slot = ALSource->Send[i].Slot;
446
447 if(!Slot && i == 0)
448 Slot = Device->DefaultSlot;
449 if(Slot && Slot->effect.type == AL_EFFECT_NULL)
450 Slot = NULL;
451 ALSource->Params.Send[i].Slot = Slot;
452 ALSource->Params.Send[i].Gain = WetGain[i];
453 }
454
455 /* Update filter coefficients. Calculations based on the I3DL2
456 * spec. */
457 cw = cosf(F_PI*2.0f * LOWPASSFREQREF / Frequency);
458
459 /* We use two chained one-pole filters, so we need to take the
460 * square root of the squared gain, which is the same as the base
461 * gain. */
462 ALSource->Params.Direct.iirFilter.coeff = lpCoeffCalc(DryGainHF, cw);
463 for(i = 0;i < NumSends;i++)
464 {
465 ALfloat a = lpCoeffCalc(WetGainHF[i], cw);
466 ALSource->Params.Send[i].iirFilter.coeff = a;
467 }
468 }
469
470 ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
471 {
472 ALCdevice *Device = ALContext->Device;
473 ALfloat Velocity[3],Direction[3],Position[3],SourceToListener[3];
474 ALfloat InnerAngle,OuterAngle,Angle,Distance,ClampedDist;
475 ALfloat MinVolume,MaxVolume,MinDist,MaxDist,Rolloff;
476 ALfloat ConeVolume,ConeHF,SourceVolume,ListenerGain;
477 ALfloat DopplerFactor, SpeedOfSound;
478 ALfloat AirAbsorptionFactor;
479 ALfloat RoomAirAbsorption[MAX_SENDS];
480 ALbufferlistitem *BufferListItem;
481 ALfloat Attenuation;
482 ALfloat RoomAttenuation[MAX_SENDS];
483 ALfloat MetersPerUnit;
484 ALfloat RoomRolloffBase;
485 ALfloat RoomRolloff[MAX_SENDS];
486 ALfloat DecayDistance[MAX_SENDS];
487 ALfloat DryGain;
488 ALfloat DryGainHF;
489 ALboolean DryGainHFAuto;
490 ALfloat WetGain[MAX_SENDS];
491 ALfloat WetGainHF[MAX_SENDS];
492 ALboolean WetGainAuto;
493 ALboolean WetGainHFAuto;
494 enum Resampler Resampler;
495 ALfloat Pitch;
496 ALuint Frequency;
497 ALint NumSends;
498 ALfloat cw;
499 ALint i, j;
500
501 DryGainHF = 1.0f;
502 for(i = 0;i < MAX_SENDS;i++)
503 WetGainHF[i] = 1.0f;
504
505 /* Get context/device properties */
506 DopplerFactor = ALContext->DopplerFactor * ALSource->DopplerFactor;
507 SpeedOfSound = ALContext->SpeedOfSound * ALContext->DopplerVelocity;
508 NumSends = Device->NumAuxSends;
509 Frequency = Device->Frequency;
510
511 /* Get listener properties */
512 ListenerGain = ALContext->Listener->Gain;
513 MetersPerUnit = ALContext->Listener->MetersPerUnit;
514
515 /* Get source properties */
516 SourceVolume = ALSource->Gain;
517 MinVolume = ALSource->MinGain;
518 MaxVolume = ALSource->MaxGain;
519 Pitch = ALSource->Pitch;
520 Resampler = ALSource->Resampler;
521 Position[0] = ALSource->Position[0];
522 Position[1] = ALSource->Position[1];
523 Position[2] = ALSource->Position[2];
524 Direction[0] = ALSource->Orientation[0];
525 Direction[1] = ALSource->Orientation[1];
526 Direction[2] = ALSource->Orientation[2];
527 Velocity[0] = ALSource->Velocity[0];
528 Velocity[1] = ALSource->Velocity[1];
529 Velocity[2] = ALSource->Velocity[2];
530 MinDist = ALSource->RefDistance;
531 MaxDist = ALSource->MaxDistance;
532 Rolloff = ALSource->RollOffFactor;
533 InnerAngle = ALSource->InnerAngle;
534 OuterAngle = ALSource->OuterAngle;
535 AirAbsorptionFactor = ALSource->AirAbsorptionFactor;
536 DryGainHFAuto = ALSource->DryGainHFAuto;
537 WetGainAuto = ALSource->WetGainAuto;
538 WetGainHFAuto = ALSource->WetGainHFAuto;
539 RoomRolloffBase = ALSource->RoomRolloffFactor;
540
541 ALSource->Params.Direct.OutBuffer = Device->DryBuffer;
542 ALSource->Params.Direct.ClickRemoval = Device->ClickRemoval;
543 ALSource->Params.Direct.PendingClicks = Device->PendingClicks;
544 for(i = 0;i < NumSends;i++)
545 {
546 ALeffectslot *Slot = ALSource->Send[i].Slot;
547
548 if(!Slot && i == 0)
549 Slot = Device->DefaultSlot;
550 if(!Slot || Slot->effect.type == AL_EFFECT_NULL)
551 {
552 Slot = NULL;
553 RoomRolloff[i] = 0.0f;
554 DecayDistance[i] = 0.0f;
555 RoomAirAbsorption[i] = 1.0f;
556 }
557 else if(Slot->AuxSendAuto)
558 {
559 RoomRolloff[i] = RoomRolloffBase;
560 if(IsReverbEffect(Slot->effect.type))
561 {
562 RoomRolloff[i] += Slot->effect.Reverb.RoomRolloffFactor;
563 DecayDistance[i] = Slot->effect.Reverb.DecayTime *
564 SPEEDOFSOUNDMETRESPERSEC;
565 RoomAirAbsorption[i] = Slot->effect.Reverb.AirAbsorptionGainHF;
566 }
567 else
568 {
569 DecayDistance[i] = 0.0f;
570 RoomAirAbsorption[i] = 1.0f;
571 }
572 }
573 else
574 {
575 /* If the slot's auxiliary send auto is off, the data sent to the
576 * effect slot is the same as the dry path, sans filter effects */
577 RoomRolloff[i] = Rolloff;
578 DecayDistance[i] = 0.0f;
579 RoomAirAbsorption[i] = AIRABSORBGAINHF;
580 }
581
582 ALSource->Params.Send[i].Slot = Slot;
583 }
584
585 /* Transform source to listener space (convert to head relative) */
586 if(ALSource->HeadRelative == AL_FALSE)
587 {
588 ALfloat (*RESTRICT Matrix)[4] = ALContext->Listener->Params.Matrix;
589 /* Transform source vectors */
590 aluMatrixVector(Position, 1.0f, Matrix);
591 aluMatrixVector(Direction, 0.0f, Matrix);
592 aluMatrixVector(Velocity, 0.0f, Matrix);
593 }
594 else
595 {
596 const ALfloat *ListenerVel = ALContext->Listener->Params.Velocity;
597 /* Offset the source velocity to be relative of the listener velocity */
598 Velocity[0] += ListenerVel[0];
599 Velocity[1] += ListenerVel[1];
600 Velocity[2] += ListenerVel[2];
601 }
602
603 SourceToListener[0] = -Position[0];
604 SourceToListener[1] = -Position[1];
605 SourceToListener[2] = -Position[2];
606 aluNormalize(SourceToListener);
607 aluNormalize(Direction);
608
609 /* Calculate distance attenuation */
610 Distance = sqrtf(aluDotproduct(Position, Position));
611 ClampedDist = Distance;
612
613 Attenuation = 1.0f;
614 for(i = 0;i < NumSends;i++)
615 RoomAttenuation[i] = 1.0f;
616 switch(ALContext->SourceDistanceModel ? ALSource->DistanceModel :
617 ALContext->DistanceModel)
618 {
619 case InverseDistanceClamped:
620 ClampedDist = clampf(ClampedDist, MinDist, MaxDist);
621 if(MaxDist < MinDist)
622 break;
623 /*fall-through*/
624 case InverseDistance:
625 if(MinDist > 0.0f)
626 {
627 if((MinDist + (Rolloff * (ClampedDist - MinDist))) > 0.0f)
628 Attenuation = MinDist / (MinDist + (Rolloff * (ClampedDist - MinDist)));
629 for(i = 0;i < NumSends;i++)
630 {
631 if((MinDist + (RoomRolloff[i] * (ClampedDist - MinDist))) > 0.0f)
632 RoomAttenuation[i] = MinDist / (MinDist + (RoomRolloff[i] * (ClampedDist - MinDist)));
633 }
634 }
635 break;
636
637 case LinearDistanceClamped:
638 ClampedDist = clampf(ClampedDist, MinDist, MaxDist);
639 if(MaxDist < MinDist)
640 break;
641 /*fall-through*/
642 case LinearDistance:
643 if(MaxDist != MinDist)
644 {
645 Attenuation = 1.0f - (Rolloff*(ClampedDist-MinDist)/(MaxDist - MinDist));
646 Attenuation = maxf(Attenuation, 0.0f);
647 for(i = 0;i < NumSends;i++)
648 {
649 RoomAttenuation[i] = 1.0f - (RoomRolloff[i]*(ClampedDist-MinDist)/(MaxDist - MinDist));
650 RoomAttenuation[i] = maxf(RoomAttenuation[i], 0.0f);
651 }
652 }
653 break;
654
655 case ExponentDistanceClamped:
656 ClampedDist = clampf(ClampedDist, MinDist, MaxDist);
657 if(MaxDist < MinDist)
658 break;
659 /*fall-through*/
660 case ExponentDistance:
661 if(ClampedDist > 0.0f && MinDist > 0.0f)
662 {
663 Attenuation = powf(ClampedDist/MinDist, -Rolloff);
664 for(i = 0;i < NumSends;i++)
665 RoomAttenuation[i] = powf(ClampedDist/MinDist, -RoomRolloff[i]);
666 }
667 break;
668
669 case DisableDistance:
670 ClampedDist = MinDist;
671 break;
672 }
673
674 /* Source Gain + Attenuation */
675 DryGain = SourceVolume * Attenuation;
676 for(i = 0;i < NumSends;i++)
677 WetGain[i] = SourceVolume * RoomAttenuation[i];
678
679 /* Distance-based air absorption */
680 if(AirAbsorptionFactor > 0.0f && ClampedDist > MinDist)
681 {
682 ALfloat meters = maxf(ClampedDist-MinDist, 0.0f) * MetersPerUnit;
683 DryGainHF *= powf(AIRABSORBGAINHF, AirAbsorptionFactor*meters);
684 for(i = 0;i < NumSends;i++)
685 WetGainHF[i] *= powf(RoomAirAbsorption[i], AirAbsorptionFactor*meters);
686 }
687
688 if(WetGainAuto)
689 {
690 ALfloat ApparentDist = 1.0f/maxf(Attenuation, 0.00001f) - 1.0f;
691
692 /* Apply a decay-time transformation to the wet path, based on the
693 * attenuation of the dry path.
694 *
695 * Using the apparent distance, based on the distance attenuation, the
696 * initial decay of the reverb effect is calculated and applied to the
697 * wet path.
698 */
699 for(i = 0;i < NumSends;i++)
700 {
701 if(DecayDistance[i] > 0.0f)
702 WetGain[i] *= powf(0.001f/*-60dB*/, ApparentDist/DecayDistance[i]);
703 }
704 }
705
706 /* Calculate directional soundcones */
707 Angle = acosf(aluDotproduct(Direction,SourceToListener)) * ConeScale * (360.0f/F_PI);
708 if(Angle > InnerAngle && Angle <= OuterAngle)
709 {
710 ALfloat scale = (Angle-InnerAngle) / (OuterAngle-InnerAngle);
711 ConeVolume = lerp(1.0f, ALSource->OuterGain, scale);
712 ConeHF = lerp(1.0f, ALSource->OuterGainHF, scale);
713 }
714 else if(Angle > OuterAngle)
715 {
716 ConeVolume = ALSource->OuterGain;
717 ConeHF = ALSource->OuterGainHF;
718 }
719 else
720 {
721 ConeVolume = 1.0f;
722 ConeHF = 1.0f;
723 }
724
725 DryGain *= ConeVolume;
726 if(WetGainAuto)
727 {
728 for(i = 0;i < NumSends;i++)
729 WetGain[i] *= ConeVolume;
730 }
731 if(DryGainHFAuto)
732 DryGainHF *= ConeHF;
733 if(WetGainHFAuto)
734 {
735 for(i = 0;i < NumSends;i++)
736 WetGainHF[i] *= ConeHF;
737 }
738
739 /* Clamp to Min/Max Gain */
740 DryGain = clampf(DryGain, MinVolume, MaxVolume);
741 for(i = 0;i < NumSends;i++)
742 WetGain[i] = clampf(WetGain[i], MinVolume, MaxVolume);
743
744 /* Apply gain and frequency filters */
745 DryGain *= ALSource->DirectGain * ListenerGain;
746 DryGainHF *= ALSource->DirectGainHF;
747 for(i = 0;i < NumSends;i++)
748 {
749 WetGain[i] *= ALSource->Send[i].Gain * ListenerGain;
750 WetGainHF[i] *= ALSource->Send[i].GainHF;
751 }
752
753 /* Calculate velocity-based doppler effect */
754 if(DopplerFactor > 0.0f)
755 {
756 const ALfloat *ListenerVel = ALContext->Listener->Params.Velocity;
757 ALfloat VSS, VLS;
758
759 if(SpeedOfSound < 1.0f)
760 {
761 DopplerFactor *= 1.0f/SpeedOfSound;
762 SpeedOfSound = 1.0f;
763 }
764
765 VSS = aluDotproduct(Velocity, SourceToListener) * DopplerFactor;
766 VLS = aluDotproduct(ListenerVel, SourceToListener) * DopplerFactor;
767
768 Pitch *= clampf(SpeedOfSound-VLS, 1.0f, SpeedOfSound*2.0f - 1.0f) /
769 clampf(SpeedOfSound-VSS, 1.0f, SpeedOfSound*2.0f - 1.0f);
770 }
771
772 BufferListItem = ALSource->queue;
773 while(BufferListItem != NULL)
774 {
775 ALbuffer *ALBuffer;
776 if((ALBuffer=BufferListItem->buffer) != NULL)
777 {
778 /* Calculate fixed-point stepping value, based on the pitch, buffer
779 * frequency, and output frequency. */
780 ALsizei maxstep = BUFFERSIZE;
781 maxstep -= ResamplerPadding[Resampler] +
782 ResamplerPrePadding[Resampler] + 1;
783 maxstep = mini(maxstep, INT_MAX>>FRACTIONBITS);
784
785 Pitch = Pitch * ALBuffer->Frequency / Frequency;
786 if(Pitch > (ALfloat)maxstep)
787 ALSource->Params.Step = maxstep<<FRACTIONBITS;
788 else
789 {
790 ALSource->Params.Step = fastf2i(Pitch*FRACTIONONE);
791 if(ALSource->Params.Step == 0)
792 ALSource->Params.Step = 1;
793 }
794 ALSource->Params.Resample = SelectResampler(Resampler, ALSource->Params.Step);
795
796 break;
797 }
798 BufferListItem = BufferListItem->next;
799 }
800 if(Device->Hrtf)
801 ALSource->Params.DryMix = SelectHrtfMixer();
802 else
803 ALSource->Params.DryMix = SelectDirectMixer();
804 ALSource->Params.WetMix = SelectSendMixer();
805
806 if(Device->Hrtf)
807 {
808 /* Use a binaural HRTF algorithm for stereo headphone playback */
809 ALfloat delta, ev = 0.0f, az = 0.0f;
810
811 if(Distance > FLT_EPSILON)
812 {
813 ALfloat invlen = 1.0f/Distance;
814 Position[0] *= invlen;
815 Position[1] *= invlen;
816 Position[2] *= invlen;
817
818 /* Calculate elevation and azimuth only when the source is not at
819 * the listener. This prevents +0 and -0 Z from producing
820 * inconsistent panning. Also, clamp Y in case FP precision errors
821 * cause it to land outside of -1..+1. */
822 ev = asinf(clampf(Position[1], -1.0f, 1.0f));
823 az = atan2f(Position[0], -Position[2]*ZScale);
824 }
825
826 /* Check to see if the HRIR is already moving. */
827 if(ALSource->Hrtf.Moving)
828 {
829 /* Calculate the normalized HRTF transition factor (delta). */
830 delta = CalcHrtfDelta(ALSource->Params.Direct.Hrtf.Params.Gain, DryGain,
831 ALSource->Params.Direct.Hrtf.Params.Dir, Position);
832 /* If the delta is large enough, get the moving HRIR target
833 * coefficients, target delays, steppping values, and counter. */
834 if(delta > 0.001f)
835 {
836 ALSource->Hrtf.Counter = GetMovingHrtfCoeffs(Device->Hrtf,
837 ev, az, DryGain, delta,
838 ALSource->Hrtf.Counter,
839 ALSource->Params.Direct.Hrtf.Params.Coeffs[0],
840 ALSource->Params.Direct.Hrtf.Params.Delay[0],
841 ALSource->Params.Direct.Hrtf.Params.CoeffStep,
842 ALSource->Params.Direct.Hrtf.Params.DelayStep);
843 ALSource->Params.Direct.Hrtf.Params.Gain = DryGain;
844 ALSource->Params.Direct.Hrtf.Params.Dir[0] = Position[0];
845 ALSource->Params.Direct.Hrtf.Params.Dir[1] = Position[1];
846 ALSource->Params.Direct.Hrtf.Params.Dir[2] = Position[2];
847 }
848 }
849 else
850 {
851 /* Get the initial (static) HRIR coefficients and delays. */
852 GetLerpedHrtfCoeffs(Device->Hrtf, ev, az, DryGain,
853 ALSource->Params.Direct.Hrtf.Params.Coeffs[0],
854 ALSource->Params.Direct.Hrtf.Params.Delay[0]);
855 ALSource->Hrtf.Counter = 0;
856 ALSource->Hrtf.Moving = AL_TRUE;
857 ALSource->Params.Direct.Hrtf.Params.Gain = DryGain;
858 ALSource->Params.Direct.Hrtf.Params.Dir[0] = Position[0];
859 ALSource->Params.Direct.Hrtf.Params.Dir[1] = Position[1];
860 ALSource->Params.Direct.Hrtf.Params.Dir[2] = Position[2];
861 }
862 ALSource->Params.Direct.Hrtf.Params.IrSize = GetHrtfIrSize(Device->Hrtf);
863
864 ALSource->Params.Direct.Hrtf.State = &ALSource->Hrtf;
865 }
866 else
867 {
868 ALfloat (*Matrix)[MaxChannels] = ALSource->Params.Direct.Gains;
869 ALfloat DirGain = 0.0f;
870 ALfloat AmbientGain;
871
872 for(i = 0;i < MaxChannels;i++)
873 {
874 for(j = 0;j < MaxChannels;j++)
875 Matrix[i][j] = 0.0f;
876 }
877
878 /* Normalize the length, and compute panned gains. */
879 if(Distance > FLT_EPSILON)
880 {
881 ALfloat invlen = 1.0f/Distance;
882 Position[0] *= invlen;
883 Position[1] *= invlen;
884 Position[2] *= invlen;
885
886 DirGain = sqrtf(Position[0]*Position[0] + Position[2]*Position[2]);
887 ComputeAngleGains(Device, atan2f(Position[0], -Position[2]*ZScale), 0.0f,
888 DryGain*DirGain, Matrix[0]);
889 }
890
891 /* Adjustment for vertical offsets. Not the greatest, but simple
892 * enough. */
893 AmbientGain = DryGain * sqrtf(1.0f/Device->NumChan) * (1.0f-DirGain);
894 for(i = 0;i < (ALint)Device->NumChan;i++)
895 {
896 enum Channel chan = Device->Speaker2Chan[i];
897 Matrix[0][chan] = maxf(Matrix[0][chan], AmbientGain);
898 }
899 }
900 for(i = 0;i < NumSends;i++)
901 ALSource->Params.Send[i].Gain = WetGain[i];
902
903 /* Update filter coefficients. */
904 cw = cosf(F_PI*2.0f * LOWPASSFREQREF / Frequency);
905
906 ALSource->Params.Direct.iirFilter.coeff = lpCoeffCalc(DryGainHF, cw);
907 for(i = 0;i < NumSends;i++)
908 {
909 ALfloat a = lpCoeffCalc(WetGainHF[i], cw);
910 ALSource->Params.Send[i].iirFilter.coeff = a;
911 }
912 }
913
914
915 static __inline ALfloat aluF2F(ALfloat val)
916 { return val; }
917 static __inline ALint aluF2I(ALfloat val)
918 {
919 /* Clamp the value between -1 and +1. This handles that without branching. */
920 val = val+1.0f - fabsf(val-1.0f);
921 val = (val-2.0f + fabsf(val+2.0f)) * 0.25f;
922 /* Convert to a signed integer, between -2147483647 and +2147483647. */
923 return fastf2i((ALfloat)(val*2147483647.0));
924 }
925 static __inline ALuint aluF2UI(ALfloat val)
926 { return aluF2I(val)+2147483648u; }
927 static __inline ALshort aluF2S(ALfloat val)
928 { return aluF2I(val)>>16; }
929 static __inline ALushort aluF2US(ALfloat val)
930 { return aluF2S(val)+32768; }
931 static __inline ALbyte aluF2B(ALfloat val)
932 { return aluF2I(val)>>24; }
933 static __inline ALubyte aluF2UB(ALfloat val)
934 { return aluF2B(val)+128; }
935
936 #define DECL_TEMPLATE(T, func) \
937 static int Write_##T(ALCdevice *device, T *RESTRICT buffer, \
938 ALuint SamplesToDo) \
939 { \
940 ALfloat (*RESTRICT DryBuffer)[BUFFERSIZE] = device->DryBuffer; \
941 ALuint numchans = ChannelsFromDevFmt(device->FmtChans); \
942 const ALuint *offsets = device->ChannelOffsets; \
943 ALuint i, j; \
944 \
945 for(j = 0;j < MaxChannels;j++) \
946 { \
947 T *RESTRICT out; \
948 \
949 if(offsets[j] == INVALID_OFFSET) \
950 continue; \
951 \
952 out = buffer + offsets[j]; \
953 for(i = 0;i < SamplesToDo;i++) \
954 out[i*numchans] = func(DryBuffer[j][i]); \
955 } \
956 return SamplesToDo*numchans*sizeof(T); \
957 }
958
959 DECL_TEMPLATE(ALfloat, aluF2F)
960 DECL_TEMPLATE(ALuint, aluF2UI)
961 DECL_TEMPLATE(ALint, aluF2I)
962 DECL_TEMPLATE(ALushort, aluF2US)
963 DECL_TEMPLATE(ALshort, aluF2S)
964 DECL_TEMPLATE(ALubyte, aluF2UB)
965 DECL_TEMPLATE(ALbyte, aluF2B)
966
967 #undef DECL_TEMPLATE
968
969
970 ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
971 {
972 ALuint SamplesToDo;
973 ALeffectslot **slot, **slot_end;
974 ALsource **src, **src_end;
975 ALCcontext *ctx;
976 FPUCtl oldMode;
977 ALuint i, c;
978
979 SetMixerFPUMode(&oldMode);
980
981 while(size > 0)
982 {
983 SamplesToDo = minu(size, BUFFERSIZE);
984 for(c = 0;c < MaxChannels;c++)
985 memset(device->DryBuffer[c], 0, SamplesToDo*sizeof(ALfloat));
986
987 ALCdevice_Lock(device);
988 ctx = device->ContextList;
989 while(ctx)
990 {
991 ALenum DeferUpdates = ctx->DeferUpdates;
992 ALenum UpdateSources = AL_FALSE;
993
994 if(!DeferUpdates)
995 UpdateSources = ExchangeInt(&ctx->UpdateSources, AL_FALSE);
996
997 if(UpdateSources)
998 CalcListenerParams(ctx->Listener);
999
1000 /* source processing */
1001 src = ctx->ActiveSources;
1002 src_end = src + ctx->ActiveSourceCount;
1003 while(src != src_end)
1004 {
1005 if((*src)->state != AL_PLAYING)
1006 {
1007 --(ctx->ActiveSourceCount);
1008 *src = *(--src_end);
1009 continue;
1010 }
1011
1012 if(!DeferUpdates && (ExchangeInt(&(*src)->NeedsUpdate, AL_FALSE) ||
1013 UpdateSources))
1014 ALsource_Update(*src, ctx);
1015
1016 MixSource(*src, device, SamplesToDo);
1017 src++;
1018 }
1019
1020 /* effect slot processing */
1021 slot = ctx->ActiveEffectSlots;
1022 slot_end = slot + ctx->ActiveEffectSlotCount;
1023 while(slot != slot_end)
1024 {
1025 ALfloat offset = (*slot)->ClickRemoval[0];
1026 if(offset < (1.0f/32768.0f))
1027 offset = 0.0f;
1028 else for(i = 0;i < SamplesToDo;i++)
1029 {
1030 (*slot)->WetBuffer[0][i] += offset;
1031 offset -= offset * (1.0f/256.0f);
1032 }
1033 (*slot)->ClickRemoval[0] = offset + (*slot)->PendingClicks[0];
1034 (*slot)->PendingClicks[0] = 0.0f;
1035
1036 if(!DeferUpdates && ExchangeInt(&(*slot)->NeedsUpdate, AL_FALSE))
1037 ALeffectState_Update((*slot)->EffectState, device, *slot);
1038
1039 ALeffectState_Process((*slot)->EffectState, SamplesToDo,
1040 (*slot)->WetBuffer[0], device->DryBuffer);
1041
1042 for(i = 0;i < SamplesToDo;i++)
1043 (*slot)->WetBuffer[0][i] = 0.0f;
1044
1045 slot++;
1046 }
1047
1048 ctx = ctx->next;
1049 }
1050
1051 slot = &device->DefaultSlot;
1052 if(*slot != NULL)
1053 {
1054 ALfloat offset = (*slot)->ClickRemoval[0];
1055 if(offset < (1.0f/32768.0f))
1056 offset = 0.0f;
1057 else for(i = 0;i < SamplesToDo;i++)
1058 {
1059 (*slot)->WetBuffer[0][i] += offset;
1060 offset -= offset * (1.0f/256.0f);
1061 }
1062 (*slot)->ClickRemoval[0] = offset + (*slot)->PendingClicks[0];
1063 (*slot)->PendingClicks[0] = 0.0f;
1064
1065 if(ExchangeInt(&(*slot)->NeedsUpdate, AL_FALSE))
1066 ALeffectState_Update((*slot)->EffectState, device, *slot);
1067
1068 ALeffectState_Process((*slot)->EffectState, SamplesToDo,
1069 (*slot)->WetBuffer[0], device->DryBuffer);
1070
1071 for(i = 0;i < SamplesToDo;i++)
1072 (*slot)->WetBuffer[0][i] = 0.0f;
1073 }
1074 ALCdevice_Unlock(device);
1075
1076 /* Click-removal. Could do better; this only really handles immediate
1077 * changes between updates where a predictive sample could be
1078 * generated. Delays caused by effects and HRTF aren't caught. */
1079 if(device->FmtChans == DevFmtMono)
1080 {
1081 ALfloat offset = device->ClickRemoval[FrontCenter];
1082 if(offset < (1.0f/32768.0f))
1083 offset = 0.0f;
1084 else for(i = 0;i < SamplesToDo;i++)
1085 {
1086 device->DryBuffer[FrontCenter][i] += offset;
1087 offset -= offset * (1.0f/256.0f);
1088 }
1089 device->ClickRemoval[FrontCenter] = offset + device->PendingClicks[FrontCenter];
1090 device->PendingClicks[FrontCenter] = 0.0f;
1091 }
1092 else if(device->FmtChans == DevFmtStereo)
1093 {
1094 /* Assumes the first two channels are FrontLeft and FrontRight */
1095 for(c = 0;c < 2;c++)
1096 {
1097 ALfloat offset = device->ClickRemoval[c];
1098 if(offset < (1.0f/32768.0f))
1099 offset = 0.0f;
1100 else for(i = 0;i < SamplesToDo;i++)
1101 {
1102 device->DryBuffer[c][i] += offset;
1103 offset -= offset * (1.0f/256.0f);
1104 }
1105 device->ClickRemoval[c] = offset + device->PendingClicks[c];
1106 device->PendingClicks[c] = 0.0f;
1107 }
1108 if(device->Bs2b)
1109 {
1110 float samples[2];
1111 for(i = 0;i < SamplesToDo;i++)
1112 {
1113 samples[0] = device->DryBuffer[FrontLeft][i];
1114 samples[1] = device->DryBuffer[FrontRight][i];
1115 bs2b_cross_feed(device->Bs2b, samples);
1116 device->DryBuffer[FrontLeft][i] = samples[0];
1117 device->DryBuffer[FrontRight][i] = samples[1];
1118 }
1119 }
1120 }
1121 else
1122 {
1123 for(c = 0;c < MaxChannels;c++)
1124 {
1125 ALfloat offset = device->ClickRemoval[c];
1126 if(offset < (1.0f/32768.0f))
1127 offset = 0.0f;
1128 else for(i = 0;i < SamplesToDo;i++)
1129 {
1130 device->DryBuffer[c][i] += offset;
1131 offset -= offset * (1.0f/256.0f);
1132 }
1133 device->ClickRemoval[c] = offset + device->PendingClicks[c];
1134 device->PendingClicks[c] = 0.0f;
1135 }
1136 }
1137
1138 if(buffer)
1139 {
1140 int bytes = 0;
1141 switch(device->FmtType)
1142 {
1143 case DevFmtByte:
1144 bytes = Write_ALbyte(device, buffer, SamplesToDo);
1145 break;
1146 case DevFmtUByte:
1147 bytes = Write_ALubyte(device, buffer, SamplesToDo);
1148 break;
1149 case DevFmtShort:
1150 bytes = Write_ALshort(device, buffer, SamplesToDo);
1151 break;
1152 case DevFmtUShort:
1153 bytes = Write_ALushort(device, buffer, SamplesToDo);
1154 break;
1155 case DevFmtInt:
1156 bytes = Write_ALint(device, buffer, SamplesToDo);
1157 break;
1158 case DevFmtUInt:
1159 bytes = Write_ALuint(device, buffer, SamplesToDo);
1160 break;
1161 case DevFmtFloat:
1162 bytes = Write_ALfloat(device, buffer, SamplesToDo);
1163 break;
1164 }
1165
1166 buffer = (ALubyte*)buffer + bytes;
1167 }
1168
1169 size -= SamplesToDo;
1170 }
1171
1172 RestoreFPUMode(&oldMode);
1173 }
1174
1175
1176 ALvoid aluHandleDisconnect(ALCdevice *device)
1177 {
1178 ALCcontext *Context;
1179
1180 device->Connected = ALC_FALSE;
1181
1182 Context = device->ContextList;
1183 while(Context)
1184 {
1185 ALsource **src, **src_end;
1186
1187 src = Context->ActiveSources;
1188 src_end = src + Context->ActiveSourceCount;
1189 while(src != src_end)
1190 {
1191 if((*src)->state == AL_PLAYING)
1192 {
1193 (*src)->state = AL_STOPPED;
1194 (*src)->BuffersPlayed = (*src)->BuffersInQueue;
1195 (*src)->position = 0;
1196 (*src)->position_fraction = 0;
1197 }
1198 src++;
1199 }
1200 Context->ActiveSourceCount = 0;
1201
1202 Context = Context->next;
1203 }
1204 }
SelectSendMixer
static WetMixerFunc SelectSendMixer(void)
Definition: ALu.c:97
DirectParams::OutBuffer
ALfloat(* OutBuffer)[BUFFERSIZE]
Definition: alSource.h:50
BackCenter
Definition: alMain.h:487
ALCcontext_struct::DistanceModel
enum DistanceModel DistanceModel
Definition: alMain.h:688
ALsource::Slot
struct ALeffectslot * Slot
Definition: alSource.h:150
ALCcontext_struct::UpdateSources
volatile ALenum UpdateSources
Definition: alMain.h:686
WetMixerFunc
ALvoid(* WetMixerFunc)(const struct SendParams *params, const ALfloat *RESTRICT data, ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
Definition: alu.h:40
ALubyte
unsigned char ALubyte
Definition: al.h:47
ALCcontext_struct::DopplerFactor
volatile ALfloat DopplerFactor
Definition: alMain.h:691
ALsource::WetGainHFAuto
volatile ALboolean WetGainHFAuto
Definition: alSource.h:105
ALCcontext_struct::Listener
struct ALlistener * Listener
Definition: alMain.h:679
GetLerpedHrtfCoeffs
void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat(*coeffs)[2], ALuint *delays)
Definition: hrtf.c:140
FILTER::coeff
ALfloat coeff
Definition: alFilter.h:13
ALCdevice_struct::Connected
ALCboolean Connected
Definition: alMain.h:564
val
GLuint const GLfloat * val
Definition: glew.h:2715
F_PI
#define F_PI
Definition: alu.h:16
ALvoid
void ALvoid
Definition: al.h:74
FmtX71
Definition: alBuffer.h:58
HrtfParams::IrSize
ALuint IrSize
Definition: alSource.h:46
aluCrossproduct
static __inline void aluCrossproduct(const ALfloat *inVector1, const ALfloat *inVector2, ALfloat *outVector)
Definition: ALu.c:108
ALeffect::Reverb
struct ALeffect::@52 Reverb
AL_STOPPED
#define AL_STOPPED
Definition: al.h:241
ALeffectState_Process
#define ALeffectState_Process(a, b, c, d)
Definition: alAuxEffectSlot.h:53
MixDirect_SSE
void MixDirect_SSE(const struct DirectParams *, const ALfloat *RESTRICT, ALuint, ALuint, ALuint, ALuint)
ALeffectState_Update
#define ALeffectState_Update(a, b, c)
Definition: alAuxEffectSlot.h:52
LFE
Definition: alMain.h:484
ALCdevice_struct::Hrtf
struct Hrtf * Hrtf
Definition: alMain.h:598
GetMovingHrtfCoeffs
ALuint GetMovingHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat delta, ALint counter, ALfloat(*coeffs)[2], ALuint *delays, ALfloat(*coeffStep)[2], ALint *delayStep)
Definition: hrtf.c:232
AL_TRUE
#define AL_TRUE
Definition: al.h:86
ALbuffer::FmtChannels
enum FmtChannels FmtChannels
Definition: alBuffer.h:77
DevFmtUShort
Definition: alMain.h:500
ALCdevice_struct::DefaultSlot
struct ALeffectslot * DefaultSlot
Definition: alMain.h:624
BackRight
Definition: alMain.h:486
ALsource::DopplerFactor
volatile ALfloat DopplerFactor
Definition: alSource.h:110
SPEEDOFSOUNDMETRESPERSEC
#define SPEEDOFSOUNDMETRESPERSEC
Definition: alu.h:46
NULL
#define NULL
Definition: ftobjs.h:61
ALCcontext_struct::ActiveEffectSlotCount
ALsizei ActiveEffectSlotCount
Definition: alMain.h:701
IsReverbEffect
static __inline ALboolean IsReverbEffect(ALenum type)
Definition: alEffect.h:102
ALCcontext_struct::ActiveSources
struct ALsource ** ActiveSources
Definition: alMain.h:696
f
GLclampf f
Definition: glew.h:3390
ALlistener::MetersPerUnit
volatile ALfloat MetersPerUnit
Definition: alListener.h:16
ALsource_Update
#define ALsource_Update(s, a)
Definition: alSource.h:179
lerp
static __inline ALfloat lerp(ALfloat val1, ALfloat val2, ALfloat mu)
Definition: alu.h:90
angle
GLdouble angle
Definition: glew.h:8396
ConeScale
ALfloat ConeScale
Definition: ALu.c:46
ALsource::Pitch
volatile ALfloat Pitch
Definition: alSource.h:85
lpCoeffCalc
ALfloat lpCoeffCalc(ALfloat g, ALfloat cw)
Definition: alFilter.c:329
ALCcontext_struct::SpeedOfSound
volatile ALfloat SpeedOfSound
Definition: alMain.h:693
ResamplerPadding
const ALsizei ResamplerPadding[ResamplerMax]
Definition: alSource.c:38
ALCdevice_struct::NumAuxSends
ALuint NumAuxSends
Definition: alMain.h:586
ExponentDistanceClamped
Definition: alMain.h:463
aluDotproduct
static __inline ALfloat aluDotproduct(const ALfloat *inVector1, const ALfloat *inVector2)
Definition: ALu.c:115
aluF2UB
static __inline ALubyte aluF2UB(ALfloat val)
Definition: ALu.c:933
alu.h
ALsizei
int ALsizei
Definition: al.h:62
ALCdevice_struct::Frequency
ALuint Frequency
Definition: alMain.h:569
FLT_EPSILON
#define FLT_EPSILON
Definition: alu.h:20
DryMixerFunc
ALvoid(* DryMixerFunc)(const struct DirectParams *params, const ALfloat *RESTRICT data, ALuint srcchan, ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
Definition: alu.h:36
ALCdevice_struct
Definition: alMain.h:560
ALint
int ALint
Definition: al.h:56
j
int32_t j
Definition: e_log.c:102
aluMixData
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
Definition: ALu.c:970
memset
#define memset
Definition: SDL_malloc.c:633
AL_FALSE
#define AL_FALSE
Definition: al.h:83
GetHrtfIrSize
ALuint GetHrtfIrSize(const struct Hrtf *Hrtf)
Definition: hrtf.c:801
a
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:8736
FRACTIONONE
#define FRACTIONONE
Definition: alu.h:50
alBuffer.h
ALbuffer::Frequency
ALsizei Frequency
Definition: alBuffer.h:73
SelectHrtfMixer
static DryMixerFunc SelectHrtfMixer(void)
Definition: ALu.c:73
ALshort
short ALshort
Definition: al.h:50
MixDirect_Hrtf_Neon
void MixDirect_Hrtf_Neon(const struct DirectParams *, const ALfloat *RESTRICT, ALuint, ALuint, ALuint, ALuint)
ALsource::Position
volatile ALfloat Position[3]
Definition: alSource.h:95
HrtfParams::DelayStep
ALint DelayStep[2]
Definition: alSource.h:45
MixSend_SSE
void MixSend_SSE(const struct SendParams *, const ALfloat *RESTRICT, ALuint, ALuint, ALuint)
FmtX61
Definition: alBuffer.h:57
alSource.h
ALsource::OuterGainHF
volatile ALfloat OuterGainHF
Definition: alSource.h:106
CalcHrtfDelta
ALfloat CalcHrtfDelta(ALfloat oldGain, ALfloat newGain, const ALfloat olddir[3], const ALfloat newdir[3])
Definition: hrtf.c:106
ALCdevice_struct::Flags
ALuint Flags
Definition: alMain.h:605
RestoreFPUMode
void RestoreFPUMode(const FPUCtl *ctl)
Definition: helpers.c:235
ALCdevice_struct::Bs2b
struct bs2b * Bs2b
Definition: alMain.h:601
clampf
static __inline ALfloat clampf(ALfloat val, ALfloat min, ALfloat max)
Definition: alu.h:58
ResamplerMax
Definition: alMain.h:477
HrtfParams::Delay
ALuint Delay[MaxChannels][2]
Definition: alSource.h:44
SetMixerFPUMode
void SetMixerFPUMode(FPUCtl *ctl)
Definition: helpers.c:193
InverseDistance
Definition: alMain.h:464
CPU_CAP_NEON
Definition: alMain.h:828
FmtRear
Definition: alBuffer.h:54
ALCcontext_struct::ActiveSourceCount
ALsizei ActiveSourceCount
Definition: alMain.h:697
maxf
static __inline ALfloat maxf(ALfloat a, ALfloat b)
Definition: alu.h:56
HRIR_LENGTH
#define HRIR_LENGTH
Definition: alMain.h:776
ALfloat
float ALfloat
Definition: al.h:68
aluF2US
static __inline ALushort aluF2US(ALfloat val)
Definition: ALu.c:929
aluHandleDisconnect
ALvoid aluHandleDisconnect(ALCdevice *device)
Definition: ALu.c:1176
ALsource::DryMix
DryMixerFunc DryMix
Definition: alSource.h:161
ALbyte
signed char ALbyte
Definition: al.h:44
DevFmtByte
Definition: alMain.h:497
ALbufferlistitem
Definition: alSource.h:24
ALlistener::Position
volatile ALfloat Position[3]
Definition: alListener.h:11
SideLeft
Definition: alMain.h:488
ALsource::MinGain
volatile ALfloat MinGain
Definition: alSource.h:88
DirectParams::iirFilter
FILTER iirFilter
Definition: alSource.h:65
aluMatrixVector
static __inline ALvoid aluMatrixVector(ALfloat *vector, ALfloat w, ALfloat(*RESTRICT matrix)[4])
Definition: ALu.c:133
ALsource::Step
ALint Step
Definition: alSource.h:164
ALbuffer
Definition: alBuffer.h:69
FmtStereo
Definition: alBuffer.h:53
ALCdevice_Unlock
#define ALCdevice_Unlock(a)
Definition: alMain.h:647
ALeffect::AirAbsorptionGainHF
ALfloat AirAbsorptionGainHF
Definition: alEffect.h:41
ALsource::RoomRolloffFactor
volatile ALfloat RoomRolloffFactor
Definition: alSource.h:109
aluF2S
static __inline ALshort aluF2S(ALfloat val)
Definition: ALu.c:927
Resample_point32_C
void Resample_point32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *RESTRICT dst, ALuint dstlen)
buffer
EGLContext EGLenum EGLClientBuffer buffer
Definition: eglext.h:87
aluF2F
static __inline ALfloat aluF2F(ALfloat val)
Definition: ALu.c:915
ALsource::AirAbsorptionFactor
volatile ALfloat AirAbsorptionFactor
Definition: alSource.h:108
DevFmtStereo
Definition: alMain.h:509
ALC_FALSE
#define ALC_FALSE
Definition: alc.h:81
ALsource::Velocity
volatile ALfloat Velocity[3]
Definition: alSource.h:96
DevFmtFloat
Definition: alMain.h:503
FrontLeft
Definition: alMain.h:481
ALCdevice_struct::NumChan
ALuint NumChan
Definition: alMain.h:611
ALsource::Resampler
enum Resampler Resampler
Definition: alSource.h:112
DevFmtInt
Definition: alMain.h:501
CalcSourceParams
ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
Definition: ALu.c:470
u
ALuint u
Definition: alMain.h:58
ALsource::DirectGainHF
ALfloat DirectGainHF
Definition: alSource.h:147
ALCdevice_struct::Speaker2Chan
enum Channel Speaker2Chan[MaxChannels]
Definition: alMain.h:609
ALsource::RefDistance
volatile ALfloat RefDistance
Definition: alSource.h:92
alAuxEffectSlot.h
ALeffectslot::effect
ALeffect effect
Definition: alAuxEffectSlot.h:21
ALsource::DirectGain
ALfloat DirectGain
Definition: alSource.h:146
AL_PLAYING
#define AL_PLAYING
Definition: al.h:239
ALeffectslot
Definition: alAuxEffectSlot.h:19
ALlistener::Params
struct ALlistener::@56 Params
ALsource::GainHF
ALfloat GainHF
Definition: alSource.h:152
ALsource::HeadRelative
volatile ALboolean HeadRelative
Definition: alSource.h:98
ALsource::OuterAngle
volatile ALfloat OuterAngle
Definition: alSource.h:91
ALsource::MaxDistance
volatile ALfloat MaxDistance
Definition: alSource.h:93
FrontCenter
Definition: alMain.h:483
alMain.h
DevFmtShort
Definition: alMain.h:499
ALushort
unsigned short ALushort
Definition: al.h:53
aluF2UI
static __inline ALuint aluF2UI(ALfloat val)
Definition: ALu.c:925
ALeffect::RoomRolloffFactor
ALfloat RoomRolloffFactor
Definition: alEffect.h:42
MixSource
ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
Definition: mixer.c:97
BackLeft
Definition: alMain.h:485
ALsource::WetMix
WetMixerFunc WetMix
Definition: alSource.h:162
LinearDistance
Definition: alMain.h:465
MAX_SENDS
#define MAX_SENDS
Definition: alSource.h:4
ResamplerPrePadding
const ALsizei ResamplerPrePadding[ResamplerMax]
Definition: alSource.c:43
samples
GLsizei samples
Definition: gl2ext.h:970
c
const GLfloat * c
Definition: glew.h:14913
FmtMono
Definition: alBuffer.h:52
ALsource::DryGainHFAuto
volatile ALboolean DryGainHFAuto
Definition: alSource.h:103
mixer_defs.h
FmtX51
Definition: alBuffer.h:56
CalcListenerParams
static ALvoid CalcListenerParams(ALlistener *Listener)
Definition: ALu.c:145
MixDirect_Hrtf_SSE
void MixDirect_Hrtf_SSE(const struct DirectParams *, const ALfloat *RESTRICT, ALuint, ALuint, ALuint, ALuint)
DirectParams::Params
HrtfParams Params
Definition: alSource.h:55
ALCcontext_struct::SourceDistanceModel
volatile ALboolean SourceDistanceModel
Definition: alMain.h:689
ComputeAngleGains
ALvoid ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat hwidth, ALfloat ingain, ALfloat *gains)
Definition: panning.c:149
ALsource::Resample
ResamplerFunc Resample
Definition: alSource.h:160
ALenum
int ALenum
Definition: al.h:65
ALCcontext_struct::DeferUpdates
volatile ALenum DeferUpdates
Definition: alMain.h:694
AL_EFFECT_NULL
#define AL_EFFECT_NULL
Definition: efx.h:154
Resample_cubic32_C
void Resample_cubic32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *RESTRICT dst, ALuint dstlen)
ALlistener::Up
volatile ALfloat Up[3]
Definition: alListener.h:14
MixSend_C
void MixSend_C(const SendParams *params, const ALfloat *RESTRICT data, ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
Definition: mixer_c.c:112
DirectParams::Gains
ALfloat Gains[MaxChannels][MaxChannels]
Definition: alSource.h:62
aluF2B
static __inline ALbyte aluF2B(ALfloat val)
Definition: ALu.c:931
ALuint
unsigned int ALuint
Definition: al.h:59
ALsource::OuterGain
volatile ALfloat OuterGain
Definition: alSource.h:87
HrtfParams::Dir
ALfloat Dir[3]
Definition: alSource.h:41
MixDirect_C
void MixDirect_C(const DirectParams *params, const ALfloat *RESTRICT data, ALuint srcchan, ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
Definition: mixer_c.c:86
matrix
GLuint GLenum matrix
Definition: glew.h:13408
ALCdevice_struct::FmtChans
enum DevFmtChannels FmtChans
Definition: alMain.h:572
ALCcontext_struct::DopplerVelocity
volatile ALfloat DopplerVelocity
Definition: alMain.h:692
ALsource::Direct
DirectParams Direct
Definition: alSource.h:166
minu
static __inline ALuint minu(ALuint a, ALuint b)
Definition: alu.h:61
scale
GLenum GLenum GLenum GLenum GLenum scale
Definition: glew.h:12632
ExponentDistance
Definition: alMain.h:466
Resample_lerp32_C
void Resample_lerp32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *RESTRICT dst, ALuint dstlen)
CPU_CAP_SSE
Definition: alMain.h:827
ZScale
ALfloat ZScale
Definition: ALu.c:49
ALsource::MaxGain
volatile ALfloat MaxGain
Definition: alSource.h:89
DisableDistance
Definition: alMain.h:467
ALsource::WetGainAuto
volatile ALboolean WetGainAuto
Definition: alSource.h:104
ALbufferlistitem::buffer
struct ALbuffer * buffer
Definition: alSource.h:26
CubicResampler
Definition: alMain.h:475
ALlistener
Definition: alListener.h:10
DECL_TEMPLATE
#define DECL_TEMPLATE(T, func)
Definition: ALu.c:936
HrtfState::Moving
ALboolean Moving
Definition: alSource.h:32
ALlistener::Velocity
volatile ALfloat Velocity[3]
Definition: alListener.h:12
FPUCtl
Definition: alMain.h:738
DevFmtUInt
Definition: alMain.h:502
DevFmtMono
Definition: alMain.h:508
offset
GLintptr offset
Definition: glew.h:1668
ALsource::DirectChannels
volatile ALboolean DirectChannels
Definition: alSource.h:101
LinearResampler
Definition: alMain.h:474
FRACTIONBITS
#define FRACTIONBITS
Definition: alu.h:49
FmtChannels
FmtChannels
Definition: alBuffer.h:51
ALlistener::Forward
volatile ALfloat Forward[3]
Definition: alListener.h:13
ALeffectslot::ClickRemoval
ALfloat ClickRemoval[1]
Definition: alAuxEffectSlot.h:31
SelectResampler
static ResamplerFunc SelectResampler(enum Resampler Resampler, ALuint increment)
Definition: ALu.c:52
ALlistener::Gain
volatile ALfloat Gain
Definition: alListener.h:15
DirectParams::PendingClicks
ALfloat * PendingClicks
Definition: alSource.h:52
ALCdevice_struct::ContextList
ALCcontext *volatile ContextList
Definition: alMain.h:627
Resampler
Resampler
Definition: alMain.h:472
ALCcontext_struct
Definition: alMain.h:675
aluNormalize
static __inline void aluNormalize(ALfloat *inVector)
Definition: ALu.c:121
LOWPASSFREQREF
#define LOWPASSFREQREF
Definition: alFilter.h:10
ALbufferlistitem::next
struct ALbufferlistitem * next
Definition: alSource.h:27
DirectParams::Hrtf
struct DirectParams::@60 Hrtf
ALsource::Params
struct ALsource::@62 Params
ALsource::Gain
volatile ALfloat Gain
Definition: alSource.h:86
HrtfState::Counter
ALuint Counter
Definition: alSource.h:33
ALCdevice_struct::FmtType
enum DevFmtType FmtType
Definition: alMain.h:573
alListener.h
DirectParams::State
HrtfState * State
Definition: alSource.h:56
ALlistener::Matrix
ALfloat Matrix[4][4]
Definition: alListener.h:19
HrtfParams::Gain
ALfloat Gain
Definition: alSource.h:40
String.h
FrontRight
Definition: alMain.h:482
SelectDirectMixer
static DryMixerFunc SelectDirectMixer(void)
Definition: ALu.c:87
ALboolean
char ALboolean
Definition: al.h:38
ALeffectslot::AuxSendAuto
volatile ALboolean AuxSendAuto
Definition: alAuxEffectSlot.h:24
ALsource
Definition: alSource.h:82
FmtQuad
Definition: alBuffer.h:55
ALCcontext_struct::next
ALCcontext *volatile next
Definition: alMain.h:707
CalcNonAttnSourceParams
ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
Definition: ALu.c:193
w
GLint GLint GLint GLint GLint w
Definition: gl2ext.h:1215
ALsource::RollOffFactor
volatile ALfloat RollOffFactor
Definition: alSource.h:94
mini
static __inline ALint mini(ALint a, ALint b)
Definition: alu.h:68
ALCcontext_struct::Device
ALCdevice * Device
Definition: alMain.h:704
SideRight
Definition: alMain.h:489
PointResampler
Definition: alMain.h:473
src
GLenum src
Definition: glew.h:2396
bs2b_cross_feed
void bs2b_cross_feed(struct bs2b *bs2b, float *sample)
Definition: bs2b.c:154
ALeffect::DecayTime
ALfloat DecayTime
Definition: alEffect.h:35
i
int i
Definition: pngrutil.c:1377
fastf2i
static __inline ALint fastf2i(ALfloat f)
Definition: alMain.h:363
CPUCapFlags
ALuint CPUCapFlags
Definition: helpers.c:70
bs2b.h
ResamplerFunc
void(* ResamplerFunc)(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *RESTRICT dst, ALuint dstlen)
Definition: alu.h:33
ALsource::Send
struct ALsource::@61 Send[MAX_SENDS]
DevFmtUByte
Definition: alMain.h:498
BUFFERSIZE
#define BUFFERSIZE
Definition: alMain.h:556
ALCcontext_struct::ActiveEffectSlots
struct ALeffectslot ** ActiveEffectSlots
Definition: alMain.h:700
ALsource::DistanceModel
enum DistanceModel DistanceModel
Definition: alSource.h:100
LinearDistanceClamped
Definition: alMain.h:462
ALsource::InnerAngle
volatile ALfloat InnerAngle
Definition: alSource.h:90
InverseDistanceClamped
Definition: alMain.h:461
AIRABSORBGAINHF
#define AIRABSORBGAINHF
Definition: alu.h:47
Channel
Channel
Definition: alMain.h:480
ALeffect::type
ALenum type
Definition: alEffect.h:27
DirectParams::ClickRemoval
ALfloat * ClickRemoval
Definition: alSource.h:51
ALsource::Orientation
volatile ALfloat Orientation[3]
Definition: alSource.h:97
aluF2I
static __inline ALint aluF2I(ALfloat val)
Definition: ALu.c:917
ALsource::queue
ALbufferlistitem * queue
Definition: alSource.h:137
MaxChannels
Definition: alMain.h:491
ALCdevice_Lock
#define ALCdevice_Lock(a)
Definition: alMain.h:646
Resample_copy32_C
void Resample_copy32_C(const ALfloat *data, ALuint frac, ALuint increment, ALfloat *RESTRICT OutBuffer, ALuint BufferSize)
Definition: mixer_c.c:18
ALsource::Hrtf
HrtfState Hrtf
Definition: alSource.h:156
MixDirect_Hrtf_C
void MixDirect_Hrtf_C(const struct DirectParams *, const ALfloat *RESTRICT, ALuint, ALuint, ALuint, ALuint)
size
GLsizei size
Definition: gl2ext.h:1467
DEVICE_WIDE_STEREO
#define DEVICE_WIDE_STEREO
Definition: alMain.h:658
ctx
EGLContext ctx
Definition: eglext.h:87