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];
117 return inVector1[0]*inVector2[0] + inVector1[1]*inVector2[1] +
118 inVector1[2]*inVector2[2];
126 ALfloat inv_length = 1.0f/sqrtf(lengthsqr);
127 inVector[0] *= inv_length;
128 inVector[1] *= inv_length;
129 inVector[2] *= inv_length;
136 vector[0], vector[1], vector[2], w
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];
147 ALfloat N[3], V[3], U[3], P[3];
154 V[0] = Listener->
Up[0];
155 V[1] = Listener->
Up[1];
156 V[2] = Listener->
Up[2];
195 static const struct ChanMap MonoMap[1] = { {
FrontCenter, 0.0f } };
196 static const struct ChanMap StereoMap[2] = {
200 static const struct ChanMap StereoWideMap[2] = {
204 static const struct ChanMap RearMap[2] = {
208 static const struct ChanMap QuadMap[4] = {
214 static const struct ChanMap X51Map[6] = {
222 static const struct ChanMap X61Map[7] = {
231 static const struct ChanMap X71Map[8] = {
243 ALfloat SourceVolume,ListenerGain,MinVolume,MaxVolume;
250 ALint NumSends, Frequency;
251 const struct ChanMap *chans =
NULL;
253 ALint num_channels = 0;
268 SourceVolume = ALSource->
Gain;
271 Pitch = ALSource->
Pitch;
277 BufferListItem = ALSource->
queue;
278 while(BufferListItem !=
NULL)
288 Pitch = Pitch * ALBuffer->
Frequency / Frequency;
302 BufferListItem = BufferListItem->
next;
304 if(!DirectChannels && Device->
Hrtf)
311 DryGain =
clampf(SourceVolume, MinVolume, MaxVolume);
312 DryGain *= ALSource->
DirectGain * ListenerGain;
314 for(i = 0;i < NumSends;i++)
316 WetGain[
i] =
clampf(SourceVolume, MinVolume, MaxVolume);
317 WetGain[
i] *= ALSource->
Send[
i].
Gain * ListenerGain;
325 SrcMatrix[i][c] = 0.0
f;
341 chans = StereoWideMap;
347 chans = StereoWideMap;
348 hwidth = 60.0f *
F_PI/180.0f;
381 for(c = 0;c < num_channels;c++)
386 if(chan == chans[c].channel)
388 SrcMatrix[
c][chan] = DryGain;
394 else if(Device->
Hrtf)
396 for(c = 0;c < num_channels;c++)
398 if(chans[c].channel ==
LFE)
414 0.0f, chans[c].angle, DryGain,
427 for(c = 0;c < num_channels;c++)
430 if(chans[c].channel ==
LFE)
432 SrcMatrix[
c][chans[
c].channel] = DryGain;
443 for(i = 0;i < NumSends;i++)
463 for(i = 0;i < NumSends;i++)
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;
516 SourceVolume = ALSource->
Gain;
519 Pitch = ALSource->
Pitch;
521 Position[0] = ALSource->
Position[0];
522 Position[1] = ALSource->
Position[1];
523 Position[2] = ALSource->
Position[2];
527 Velocity[0] = ALSource->
Velocity[0];
528 Velocity[1] = ALSource->
Velocity[1];
529 Velocity[2] = ALSource->
Velocity[2];
544 for(i = 0;i < NumSends;i++)
553 RoomRolloff[
i] = 0.0f;
554 DecayDistance[
i] = 0.0f;
555 RoomAirAbsorption[
i] = 1.0f;
559 RoomRolloff[
i] = RoomRolloffBase;
569 DecayDistance[
i] = 0.0f;
570 RoomAirAbsorption[
i] = 1.0f;
577 RoomRolloff[
i] = Rolloff;
578 DecayDistance[
i] = 0.0f;
598 Velocity[0] += ListenerVel[0];
599 Velocity[1] += ListenerVel[1];
600 Velocity[2] += ListenerVel[2];
603 SourceToListener[0] = -Position[0];
604 SourceToListener[1] = -Position[1];
605 SourceToListener[2] = -Position[2];
611 ClampedDist = Distance;
614 for(i = 0;i < NumSends;i++)
615 RoomAttenuation[i] = 1.0
f;
620 ClampedDist =
clampf(ClampedDist, MinDist, MaxDist);
621 if(MaxDist < MinDist)
627 if((MinDist + (Rolloff * (ClampedDist - MinDist))) > 0.0
f)
628 Attenuation = MinDist / (MinDist + (Rolloff * (ClampedDist - MinDist)));
629 for(i = 0;i < NumSends;i++)
631 if((MinDist + (RoomRolloff[i] * (ClampedDist - MinDist))) > 0.0f)
632 RoomAttenuation[i] = MinDist / (MinDist + (RoomRolloff[i] * (ClampedDist - MinDist)));
638 ClampedDist =
clampf(ClampedDist, MinDist, MaxDist);
639 if(MaxDist < MinDist)
643 if(MaxDist != MinDist)
645 Attenuation = 1.0f - (Rolloff*(ClampedDist-MinDist)/(MaxDist - MinDist));
646 Attenuation =
maxf(Attenuation, 0.0
f);
647 for(i = 0;i < NumSends;i++)
649 RoomAttenuation[
i] = 1.0f - (RoomRolloff[
i]*(ClampedDist-MinDist)/(MaxDist - MinDist));
650 RoomAttenuation[
i] =
maxf(RoomAttenuation[i], 0.0
f);
656 ClampedDist =
clampf(ClampedDist, MinDist, MaxDist);
657 if(MaxDist < MinDist)
661 if(ClampedDist > 0.0
f && MinDist > 0.0
f)
663 Attenuation = powf(ClampedDist/MinDist, -Rolloff);
664 for(i = 0;i < NumSends;i++)
665 RoomAttenuation[i] = powf(ClampedDist/MinDist, -RoomRolloff[i]);
670 ClampedDist = MinDist;
675 DryGain = SourceVolume * Attenuation;
676 for(i = 0;i < NumSends;i++)
677 WetGain[i] = SourceVolume * RoomAttenuation[i];
680 if(AirAbsorptionFactor > 0.0
f && ClampedDist > MinDist)
682 ALfloat meters =
maxf(ClampedDist-MinDist, 0.0
f) * MetersPerUnit;
684 for(i = 0;i < NumSends;i++)
685 WetGainHF[i] *= powf(RoomAirAbsorption[i], AirAbsorptionFactor*meters);
690 ALfloat ApparentDist = 1.0f/
maxf(Attenuation, 0.00001
f) - 1.0f;
699 for(i = 0;i < NumSends;i++)
701 if(DecayDistance[i] > 0.0
f)
702 WetGain[
i] *= powf(0.001
f, ApparentDist/DecayDistance[i]);
708 if(Angle > InnerAngle && Angle <= OuterAngle)
710 ALfloat scale = (Angle-InnerAngle) / (OuterAngle-InnerAngle);
714 else if(Angle > OuterAngle)
725 DryGain *= ConeVolume;
728 for(i = 0;i < NumSends;i++)
729 WetGain[i] *= ConeVolume;
735 for(i = 0;i < NumSends;i++)
736 WetGainHF[i] *= ConeHF;
740 DryGain =
clampf(DryGain, MinVolume, MaxVolume);
741 for(i = 0;i < NumSends;i++)
742 WetGain[i] =
clampf(WetGain[i], MinVolume, MaxVolume);
745 DryGain *= ALSource->
DirectGain * ListenerGain;
747 for(i = 0;i < NumSends;i++)
749 WetGain[
i] *= ALSource->
Send[
i].
Gain * ListenerGain;
754 if(DopplerFactor > 0.0
f)
759 if(SpeedOfSound < 1.0
f)
761 DopplerFactor *= 1.0f/SpeedOfSound;
765 VSS =
aluDotproduct(Velocity, SourceToListener) * DopplerFactor;
766 VLS =
aluDotproduct(ListenerVel, SourceToListener) * DopplerFactor;
768 Pitch *=
clampf(SpeedOfSound-VLS, 1.0
f, SpeedOfSound*2.0
f - 1.0
f) /
769 clampf(SpeedOfSound-VSS, 1.0
f, SpeedOfSound*2.0
f - 1.0
f);
772 BufferListItem = ALSource->
queue;
773 while(BufferListItem !=
NULL)
785 Pitch = Pitch * ALBuffer->
Frequency / Frequency;
798 BufferListItem = BufferListItem->
next;
809 ALfloat delta, ev = 0.0f, az = 0.0f;
813 ALfloat invlen = 1.0f/Distance;
814 Position[0] *= invlen;
815 Position[1] *= invlen;
816 Position[2] *= invlen;
822 ev = asinf(
clampf(Position[1], -1.0
f, 1.0
f));
823 az = atan2f(Position[0], -Position[2]*
ZScale);
837 ev, az, DryGain, delta,
881 ALfloat invlen = 1.0f/Distance;
882 Position[0] *= invlen;
883 Position[1] *= invlen;
884 Position[2] *= invlen;
886 DirGain = sqrtf(Position[0]*Position[0] + Position[2]*Position[2]);
888 DryGain*DirGain, Matrix[0]);
893 AmbientGain = DryGain * sqrtf(1.0
f/Device->
NumChan) * (1.0f-DirGain);
897 Matrix[0][chan] =
maxf(Matrix[0][chan], AmbientGain);
900 for(i = 0;i < NumSends;i++)
907 for(i = 0;i < NumSends;i++)
920 val = val+1.0f - fabsf(val-1.0
f);
921 val = (val-2.0f + fabsf(val+2.0
f)) * 0.25
f;
926 {
return aluF2I(val)+2147483648
u; }
928 {
return aluF2I(val)>>16; }
930 {
return aluF2S(val)+32768; }
932 {
return aluF2I(val)>>24; }
934 {
return aluF2B(val)+128; }
936 #define DECL_TEMPLATE(T, func) \
937 static int Write_##T(ALCdevice *device, T *RESTRICT buffer, \
938 ALuint SamplesToDo) \
940 ALfloat (*RESTRICT DryBuffer)[BUFFERSIZE] = device->DryBuffer; \
941 ALuint numchans = ChannelsFromDevFmt(device->FmtChans); \
942 const ALuint *offsets = device->ChannelOffsets; \
945 for(j = 0;j < MaxChannels;j++) \
949 if(offsets[j] == INVALID_OFFSET) \
952 out = buffer + offsets[j]; \
953 for(i = 0;i < SamplesToDo;i++) \
954 out[i*numchans] = func(DryBuffer[j][i]); \
956 return SamplesToDo*numchans*sizeof(T); \
985 memset(device->DryBuffer[c], 0, SamplesToDo*
sizeof(
ALfloat));
1003 while(src != src_end)
1008 *src = *(--src_end);
1012 if(!DeferUpdates && (ExchangeInt(&(*src)->NeedsUpdate,
AL_FALSE) ||
1023 while(slot != slot_end)
1026 if(offset < (1.0
f/32768.0
f))
1028 else for(i = 0;i < SamplesToDo;i++)
1030 (*slot)->WetBuffer[0][
i] +=
offset;
1031 offset -= offset * (1.0f/256.0f);
1033 (*slot)->ClickRemoval[0] = offset + (*slot)->PendingClicks[0];
1034 (*slot)->PendingClicks[0] = 0.0f;
1036 if(!DeferUpdates && ExchangeInt(&(*slot)->NeedsUpdate,
AL_FALSE))
1040 (*slot)->WetBuffer[0], device->DryBuffer);
1042 for(i = 0;i < SamplesToDo;i++)
1043 (*slot)->WetBuffer[0][i] = 0.0f;
1055 if(offset < (1.0
f/32768.0
f))
1057 else for(i = 0;i < SamplesToDo;i++)
1059 (*slot)->WetBuffer[0][
i] +=
offset;
1060 offset -= offset * (1.0f/256.0f);
1062 (*slot)->ClickRemoval[0] = offset + (*slot)->PendingClicks[0];
1063 (*slot)->PendingClicks[0] = 0.0f;
1065 if(ExchangeInt(&(*slot)->NeedsUpdate,
AL_FALSE))
1069 (*slot)->WetBuffer[0], device->DryBuffer);
1071 for(i = 0;i < SamplesToDo;i++)
1072 (*slot)->WetBuffer[0][i] = 0.0f;
1082 if(offset < (1.0
f/32768.0
f))
1084 else for(i = 0;i < SamplesToDo;i++)
1087 offset -= offset * (1.0f/256.0f);
1095 for(c = 0;c < 2;c++)
1098 if(offset < (1.0
f/32768.0
f))
1100 else for(i = 0;i < SamplesToDo;i++)
1103 offset -= offset * (1.0f/256.0f);
1105 device->ClickRemoval[
c] = offset + device->PendingClicks[
c];
1106 device->PendingClicks[
c] = 0.0f;
1111 for(i = 0;i < SamplesToDo;i++)
1113 samples[0] = device->DryBuffer[
FrontLeft][
i];
1116 device->DryBuffer[
FrontLeft][
i] = samples[0];
1126 if(offset < (1.0
f/32768.0
f))
1128 else for(i = 0;i < SamplesToDo;i++)
1131 offset -= offset * (1.0f/256.0f);
1133 device->ClickRemoval[
c] = offset + device->PendingClicks[
c];
1134 device->PendingClicks[
c] = 0.0f;
1144 bytes = Write_ALbyte(device, buffer, SamplesToDo);
1147 bytes = Write_ALubyte(device, buffer, SamplesToDo);
1150 bytes = Write_ALshort(device, buffer, SamplesToDo);
1153 bytes = Write_ALushort(device, buffer, SamplesToDo);
1156 bytes = Write_ALint(device, buffer, SamplesToDo);
1159 bytes = Write_ALuint(device, buffer, SamplesToDo);
1162 bytes = Write_ALfloat(device, buffer, SamplesToDo);
1166 buffer = (ALubyte*)buffer + bytes;
1169 size -= SamplesToDo;
1189 while(src != src_end)
1194 (*src)->BuffersPlayed = (*src)->BuffersInQueue;
1195 (*src)->position = 0;
1196 (*src)->position_fraction = 0;
1202 Context = Context->
next;
static WetMixerFunc SelectSendMixer(void)
ALfloat(* OutBuffer)[BUFFERSIZE]
enum DistanceModel DistanceModel
struct ALeffectslot * Slot
volatile ALenum UpdateSources
ALvoid(* WetMixerFunc)(const struct SendParams *params, const ALfloat *RESTRICT data, ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
volatile ALfloat DopplerFactor
volatile ALboolean WetGainHFAuto
struct ALlistener * Listener
void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat(*coeffs)[2], ALuint *delays)
GLuint const GLfloat * val
static __inline void aluCrossproduct(const ALfloat *inVector1, const ALfloat *inVector2, ALfloat *outVector)
struct ALeffect::@52 Reverb
#define ALeffectState_Process(a, b, c, d)
void MixDirect_SSE(const struct DirectParams *, const ALfloat *RESTRICT, ALuint, ALuint, ALuint, ALuint)
#define ALeffectState_Update(a, b, c)
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)
enum FmtChannels FmtChannels
struct ALeffectslot * DefaultSlot
volatile ALfloat DopplerFactor
#define SPEEDOFSOUNDMETRESPERSEC
ALsizei ActiveEffectSlotCount
static __inline ALboolean IsReverbEffect(ALenum type)
struct ALsource ** ActiveSources
volatile ALfloat MetersPerUnit
#define ALsource_Update(s, a)
static __inline ALfloat lerp(ALfloat val1, ALfloat val2, ALfloat mu)
ALfloat lpCoeffCalc(ALfloat g, ALfloat cw)
volatile ALfloat SpeedOfSound
const ALsizei ResamplerPadding[ResamplerMax]
static __inline ALfloat aluDotproduct(const ALfloat *inVector1, const ALfloat *inVector2)
static __inline ALubyte aluF2UB(ALfloat val)
ALvoid(* DryMixerFunc)(const struct DirectParams *params, const ALfloat *RESTRICT data, ALuint srcchan, ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
ALuint GetHrtfIrSize(const struct Hrtf *Hrtf)
GLboolean GLboolean GLboolean GLboolean a
static DryMixerFunc SelectHrtfMixer(void)
void MixDirect_Hrtf_Neon(const struct DirectParams *, const ALfloat *RESTRICT, ALuint, ALuint, ALuint, ALuint)
volatile ALfloat Position[3]
void MixSend_SSE(const struct SendParams *, const ALfloat *RESTRICT, ALuint, ALuint, ALuint)
volatile ALfloat OuterGainHF
ALfloat CalcHrtfDelta(ALfloat oldGain, ALfloat newGain, const ALfloat olddir[3], const ALfloat newdir[3])
void RestoreFPUMode(const FPUCtl *ctl)
static __inline ALfloat clampf(ALfloat val, ALfloat min, ALfloat max)
ALuint Delay[MaxChannels][2]
void SetMixerFPUMode(FPUCtl *ctl)
ALsizei ActiveSourceCount
static __inline ALfloat maxf(ALfloat a, ALfloat b)
static __inline ALushort aluF2US(ALfloat val)
ALvoid aluHandleDisconnect(ALCdevice *device)
volatile ALfloat Position[3]
static __inline ALvoid aluMatrixVector(ALfloat *vector, ALfloat w, ALfloat(*RESTRICT matrix)[4])
#define ALCdevice_Unlock(a)
ALfloat AirAbsorptionGainHF
volatile ALfloat RoomRolloffFactor
static __inline ALshort aluF2S(ALfloat val)
void Resample_point32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *RESTRICT dst, ALuint dstlen)
EGLContext EGLenum EGLClientBuffer buffer
static __inline ALfloat aluF2F(ALfloat val)
volatile ALfloat AirAbsorptionFactor
volatile ALfloat Velocity[3]
ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
enum Channel Speaker2Chan[MaxChannels]
volatile ALfloat RefDistance
struct ALlistener::@56 Params
volatile ALboolean HeadRelative
volatile ALfloat OuterAngle
volatile ALfloat MaxDistance
static __inline ALuint aluF2UI(ALfloat val)
ALfloat RoomRolloffFactor
ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
const ALsizei ResamplerPrePadding[ResamplerMax]
volatile ALboolean DryGainHFAuto
static ALvoid CalcListenerParams(ALlistener *Listener)
void MixDirect_Hrtf_SSE(const struct DirectParams *, const ALfloat *RESTRICT, ALuint, ALuint, ALuint, ALuint)
volatile ALboolean SourceDistanceModel
ALvoid ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat hwidth, ALfloat ingain, ALfloat *gains)
volatile ALenum DeferUpdates
void Resample_cubic32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *RESTRICT dst, ALuint dstlen)
void MixSend_C(const SendParams *params, const ALfloat *RESTRICT data, ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
ALfloat Gains[MaxChannels][MaxChannels]
static __inline ALbyte aluF2B(ALfloat val)
volatile ALfloat OuterGain
void MixDirect_C(const DirectParams *params, const ALfloat *RESTRICT data, ALuint srcchan, ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
enum DevFmtChannels FmtChans
volatile ALfloat DopplerVelocity
static __inline ALuint minu(ALuint a, ALuint b)
GLenum GLenum GLenum GLenum GLenum scale
void Resample_lerp32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *RESTRICT dst, ALuint dstlen)
volatile ALboolean WetGainAuto
#define DECL_TEMPLATE(T, func)
volatile ALfloat Velocity[3]
volatile ALboolean DirectChannels
volatile ALfloat Forward[3]
static ResamplerFunc SelectResampler(enum Resampler Resampler, ALuint increment)
ALCcontext *volatile ContextList
static __inline void aluNormalize(ALfloat *inVector)
struct ALbufferlistitem * next
struct DirectParams::@60 Hrtf
struct ALsource::@62 Params
static DryMixerFunc SelectDirectMixer(void)
volatile ALboolean AuxSendAuto
ALCcontext *volatile next
ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
GLint GLint GLint GLint GLint w
volatile ALfloat RollOffFactor
static __inline ALint mini(ALint a, ALint b)
void bs2b_cross_feed(struct bs2b *bs2b, float *sample)
static __inline ALint fastf2i(ALfloat f)
void(* ResamplerFunc)(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *RESTRICT dst, ALuint dstlen)
struct ALsource::@61 Send[MAX_SENDS]
struct ALeffectslot ** ActiveEffectSlots
enum DistanceModel DistanceModel
volatile ALfloat InnerAngle
volatile ALfloat Orientation[3]
static __inline ALint aluF2I(ALfloat val)
#define ALCdevice_Lock(a)
void Resample_copy32_C(const ALfloat *data, ALuint frac, ALuint increment, ALfloat *RESTRICT OutBuffer, ALuint BufferSize)
void MixDirect_Hrtf_C(const struct DirectParams *, const ALfloat *RESTRICT, ALuint, ALuint, ALuint, ALuint)
#define DEVICE_WIDE_STEREO