diff options
author | Chris Robinson <[email protected]> | 2014-10-02 18:05:42 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2014-10-02 18:05:42 -0700 |
commit | 95ba18cf4e52c439b85ece2daf0b404fa69c7b70 (patch) | |
tree | 2367b5d69488633fb8d596cf3e3b328d81b2753f /Alc | |
parent | 9377d0f23730ff0d42a870627ea9a75059c481f4 (diff) |
Make ComputeAngleGains use ComputeDirectionalGains
Diffstat (limited to 'Alc')
-rw-r--r-- | Alc/ALu.c | 119 | ||||
-rw-r--r-- | Alc/effects/chorus.c | 6 | ||||
-rw-r--r-- | Alc/effects/dedicated.c | 30 | ||||
-rw-r--r-- | Alc/effects/echo.c | 14 | ||||
-rw-r--r-- | Alc/effects/flanger.c | 6 | ||||
-rw-r--r-- | Alc/effects/reverb.c | 62 | ||||
-rw-r--r-- | Alc/panning.c | 230 |
7 files changed, 176 insertions, 291 deletions
@@ -45,6 +45,7 @@ static_assert((INT_MAX>>FRACTIONBITS)/MAX_PITCH > BUFFERSIZE, struct ChanMap { enum Channel channel; ALfloat angle; + ALfloat elevation; }; /* Cone scalar */ @@ -231,51 +232,51 @@ static ALvoid CalcListenerParams(ALlistener *Listener) ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCcontext *ALContext) { - static const struct ChanMap MonoMap[1] = { { FrontCenter, 0.0f } }; + static const struct ChanMap MonoMap[1] = { { FrontCenter, 0.0f, 0.0f } }; static const struct ChanMap StereoMap[2] = { - { FrontLeft, DEG2RAD(-30.0f) }, - { FrontRight, DEG2RAD( 30.0f) } + { FrontLeft, DEG2RAD(-30.0f), DEG2RAD(0.0f) }, + { FrontRight, DEG2RAD( 30.0f), DEG2RAD(0.0f) } }; static const struct ChanMap StereoWideMap[2] = { - { FrontLeft, DEG2RAD(-90.0f) }, - { FrontRight, DEG2RAD( 90.0f) } + { FrontLeft, DEG2RAD(-90.0f), DEG2RAD(0.0f) }, + { FrontRight, DEG2RAD( 90.0f), DEG2RAD(0.0f) } }; static const struct ChanMap RearMap[2] = { - { BackLeft, DEG2RAD(-150.0f) }, - { BackRight, DEG2RAD( 150.0f) } + { BackLeft, DEG2RAD(-150.0f), DEG2RAD(0.0f) }, + { BackRight, DEG2RAD( 150.0f), DEG2RAD(0.0f) } }; static const struct ChanMap QuadMap[4] = { - { FrontLeft, DEG2RAD( -45.0f) }, - { FrontRight, DEG2RAD( 45.0f) }, - { BackLeft, DEG2RAD(-135.0f) }, - { BackRight, DEG2RAD( 135.0f) } + { FrontLeft, DEG2RAD( -45.0f), DEG2RAD(0.0f) }, + { FrontRight, DEG2RAD( 45.0f), DEG2RAD(0.0f) }, + { BackLeft, DEG2RAD(-135.0f), DEG2RAD(0.0f) }, + { BackRight, DEG2RAD( 135.0f), DEG2RAD(0.0f) } }; static const struct ChanMap X51Map[6] = { - { FrontLeft, DEG2RAD( -30.0f) }, - { FrontRight, DEG2RAD( 30.0f) }, - { FrontCenter, DEG2RAD( 0.0f) }, - { LFE, 0.0f }, - { BackLeft, DEG2RAD(-110.0f) }, - { BackRight, DEG2RAD( 110.0f) } + { FrontLeft, DEG2RAD( -30.0f), DEG2RAD(0.0f) }, + { FrontRight, DEG2RAD( 30.0f), DEG2RAD(0.0f) }, + { FrontCenter, DEG2RAD( 0.0f), DEG2RAD(0.0f) }, + { LFE, 0.0f, 0.0f }, + { BackLeft, DEG2RAD(-110.0f), DEG2RAD(0.0f) }, + { BackRight, DEG2RAD( 110.0f), DEG2RAD(0.0f) } }; static const struct ChanMap X61Map[7] = { - { FrontLeft, DEG2RAD(-30.0f) }, - { FrontRight, DEG2RAD( 30.0f) }, - { FrontCenter, DEG2RAD( 0.0f) }, - { LFE, 0.0f }, - { BackCenter, DEG2RAD(180.0f) }, - { SideLeft, DEG2RAD(-90.0f) }, - { SideRight, DEG2RAD( 90.0f) } + { FrontLeft, DEG2RAD(-30.0f), DEG2RAD(0.0f) }, + { FrontRight, DEG2RAD( 30.0f), DEG2RAD(0.0f) }, + { FrontCenter, DEG2RAD( 0.0f), DEG2RAD(0.0f) }, + { LFE, 0.0f, 0.0f }, + { BackCenter, DEG2RAD(180.0f), DEG2RAD(0.0f) }, + { SideLeft, DEG2RAD(-90.0f), DEG2RAD(0.0f) }, + { SideRight, DEG2RAD( 90.0f), DEG2RAD(0.0f) } }; static const struct ChanMap X71Map[8] = { - { FrontLeft, DEG2RAD( -30.0f) }, - { FrontRight, DEG2RAD( 30.0f) }, - { FrontCenter, DEG2RAD( 0.0f) }, - { LFE, 0.0f }, - { BackLeft, DEG2RAD(-150.0f) }, - { BackRight, DEG2RAD( 150.0f) }, - { SideLeft, DEG2RAD( -90.0f) }, - { SideRight, DEG2RAD( 90.0f) } + { FrontLeft, DEG2RAD( -30.0f), DEG2RAD(0.0f) }, + { FrontRight, DEG2RAD( 30.0f), DEG2RAD(0.0f) }, + { FrontCenter, DEG2RAD( 0.0f), DEG2RAD(0.0f) }, + { LFE, 0.0f, 0.0f }, + { BackLeft, DEG2RAD(-150.0f), DEG2RAD(0.0f) }, + { BackRight, DEG2RAD( 150.0f), DEG2RAD(0.0f) }, + { SideLeft, DEG2RAD( -90.0f), DEG2RAD(0.0f) }, + { SideRight, DEG2RAD( 90.0f), DEG2RAD(0.0f) } }; ALCdevice *Device = ALContext->Device; @@ -290,7 +291,6 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A const struct ChanMap *chans = NULL; ALint num_channels = 0; ALboolean DirectChannels; - ALfloat hwidth = 0.0f; ALfloat Pitch; ALint i, j, c; @@ -365,21 +365,13 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A break; case FmtStereo: - if(!(Device->Flags&DEVICE_WIDE_STEREO)) - { - /* HACK: Place the stereo channels at +/-90 degrees when using non- - * HRTF stereo output. This helps reduce the "monoization" caused - * by them panning towards the center. */ - if(Device->FmtChans == DevFmtStereo && !Device->Hrtf) - chans = StereoWideMap; - else - chans = StereoMap; - } - else - { + /* HACK: Place the stereo channels at +/-90 degrees when using non- + * HRTF stereo output. This helps reduce the "monoization" caused + * by them panning towards the center. */ + if(Device->FmtChans == DevFmtStereo && !Device->Hrtf) chans = StereoWideMap; - hwidth = DEG2RAD(60.0f); - } + else + chans = StereoMap; num_channels = 2; break; @@ -451,7 +443,7 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A /* Get the static HRIR coefficients and delays for this * channel. */ GetLerpedHrtfCoeffs(Device->Hrtf, - 0.0f, chans[c].angle, 1.0f, DryGain, + chans[c].elevation, chans[c].angle, 1.0f, DryGain, voice->Direct.Mix.Hrtf.Params[c].Coeffs, voice->Direct.Mix.Hrtf.Params[c].Delay); } @@ -464,21 +456,40 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A } else { - DryGain *= lerp(1.0f, 1.0f/sqrtf((float)Device->NumSpeakers), hwidth/F_PI); for(c = 0;c < num_channels;c++) { MixGains *gains = voice->Direct.Mix.Gains[c]; ALfloat Target[MaxChannels]; + bool ok = false; /* Special-case LFE */ if(chans[c].channel == LFE) { - for(j = 0;j < MaxChannels;j++) - gains[j].Target = 0.0f; - gains[chans[c].channel].Target = DryGain; - continue; + for(i = 0;i < MaxChannels;i++) + Target[i] = 0.0f; + Target[chans[c].channel] = DryGain; + ok = true; } - ComputeAngleGains(Device, chans[c].angle, hwidth, DryGain, Target); + else for(i = 0;i < (ALint)Device->NumSpeakers;i++) + { + /* Attempt to match the input channel to an output based on its + * location. */ + if(Device->Speaker[i].Angle == chans[c].angle && + Device->Speaker[i].Elevation == chans[c].elevation) + { + for(j = 0;j < MaxChannels;j++) + Target[j] = 0.0f; + Target[Device->Speaker[i].ChanName] = DryGain; + ok = true; + break; + } + } + if(!ok) + { + /* All else fails, virtualize it. */ + ComputeAngleGains(Device, chans[c].angle, chans[c].elevation, DryGain, Target); + } + for(i = 0;i < MaxChannels;i++) gains[i].Target = Target[i]; } diff --git a/Alc/effects/chorus.c b/Alc/effects/chorus.c index ad45c785..6e541208 100644 --- a/Alc/effects/chorus.c +++ b/Alc/effects/chorus.c @@ -93,6 +93,8 @@ static ALboolean ALchorusState_deviceUpdate(ALchorusState *state, ALCdevice *Dev static ALvoid ALchorusState_update(ALchorusState *state, ALCdevice *Device, const ALeffectslot *Slot) { + static const ALfloat left_dir[3] = { -1.0f, 0.0f, 0.0f }; + static const ALfloat right_dir[3] = { 1.0f, 0.0f, 0.0f }; ALfloat frequency = (ALfloat)Device->Frequency; ALfloat rate; ALint phase; @@ -111,8 +113,8 @@ static ALvoid ALchorusState_update(ALchorusState *state, ALCdevice *Device, cons state->delay = fastf2i(Slot->EffectProps.Chorus.Delay * frequency); /* Gains for left and right sides */ - ComputeAngleGains(Device, atan2f(-1.0f, 0.0f), 0.0f, Slot->Gain, state->Gain[0]); - ComputeAngleGains(Device, atan2f(+1.0f, 0.0f), 0.0f, Slot->Gain, state->Gain[1]); + ComputeDirectionalGains(Device, left_dir, Slot->Gain, state->Gain[0]); + ComputeDirectionalGains(Device, right_dir, Slot->Gain, state->Gain[1]); phase = Slot->EffectProps.Chorus.Phase; rate = Slot->EffectProps.Chorus.Rate; diff --git a/Alc/effects/dedicated.c b/Alc/effects/dedicated.c index 0907d6b0..ea028046 100644 --- a/Alc/effects/dedicated.c +++ b/Alc/effects/dedicated.c @@ -48,16 +48,32 @@ static ALboolean ALdedicatedState_deviceUpdate(ALdedicatedState *UNUSED(state), static ALvoid ALdedicatedState_update(ALdedicatedState *state, ALCdevice *device, const ALeffectslot *Slot) { ALfloat Gain; - ALsizei s; + ALuint i; + + for(i = 0;i < MaxChannels;i++) + state->gains[i] = 0.0f; Gain = Slot->Gain * Slot->EffectProps.Dedicated.Gain; - if(Slot->EffectType == AL_EFFECT_DEDICATED_DIALOGUE) - ComputeAngleGains(device, atan2f(0.0f, 1.0f), 0.0f, Gain, state->gains); - else if(Slot->EffectType == AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT) - { - for(s = 0;s < MaxChannels;s++) - state->gains[s] = 0.0f; + if(Slot->EffectType == AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT) state->gains[LFE] = Gain; + else if(Slot->EffectType == AL_EFFECT_DEDICATED_DIALOGUE) + { + ALboolean done = AL_FALSE; + /* Dialog goes to the front-center speaker if it exists, otherwise it + * plays from the front-center location. */ + for(i = 0;i < device->NumSpeakers;i++) + { + if(device->Speaker[i].ChanName == FrontCenter) + { + state->gains[FrontCenter] = Gain; + done = AL_TRUE; + } + } + if(!done) + { + static const ALfloat front_dir[3] = { 0.0f, 0.0f, -1.0f }; + ComputeDirectionalGains(device, front_dir, Gain, state->gains); + } } } diff --git a/Alc/effects/echo.c b/Alc/effects/echo.c index 17b7269b..69d9b84f 100644 --- a/Alc/effects/echo.c +++ b/Alc/effects/echo.c @@ -83,9 +83,10 @@ static ALboolean ALechoState_deviceUpdate(ALechoState *state, ALCdevice *Device) static ALvoid ALechoState_update(ALechoState *state, ALCdevice *Device, const ALeffectslot *Slot) { + ALfloat pandir[3] = { 0.0f, 0.0f, 0.0f }; ALuint frequency = Device->Frequency; - ALfloat lrpan, gain; - ALfloat dirGain; + ALfloat gain = Slot->Gain; + ALfloat lrpan; state->Tap[0].delay = fastf2u(Slot->EffectProps.Echo.Delay * frequency) + 1; state->Tap[1].delay = fastf2u(Slot->EffectProps.Echo.LRDelay * frequency); @@ -99,14 +100,13 @@ static ALvoid ALechoState_update(ALechoState *state, ALCdevice *Device, const AL 1.0f - Slot->EffectProps.Echo.Damping, LOWPASSFREQREF/frequency, 0.0f); - gain = Slot->Gain; - dirGain = fabsf(lrpan); - /* First tap panning */ - ComputeAngleGains(Device, atan2f(-lrpan, 0.0f), (1.0f-dirGain)*F_PI, gain, state->Gain[0]); + pandir[0] = -lrpan; + ComputeDirectionalGains(Device, pandir, gain, state->Gain[0]); /* Second tap panning */ - ComputeAngleGains(Device, atan2f(+lrpan, 0.0f), (1.0f-dirGain)*F_PI, gain, state->Gain[1]); + pandir[0] = +lrpan; + ComputeDirectionalGains(Device, pandir, gain, state->Gain[1]); } static ALvoid ALechoState_process(ALechoState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) diff --git a/Alc/effects/flanger.c b/Alc/effects/flanger.c index 6395f4bf..a38b3b13 100644 --- a/Alc/effects/flanger.c +++ b/Alc/effects/flanger.c @@ -93,6 +93,8 @@ static ALboolean ALflangerState_deviceUpdate(ALflangerState *state, ALCdevice *D static ALvoid ALflangerState_update(ALflangerState *state, ALCdevice *Device, const ALeffectslot *Slot) { + static const ALfloat left_dir[3] = { -1.0f, 0.0f, 0.0f }; + static const ALfloat right_dir[3] = { 1.0f, 0.0f, 0.0f }; ALfloat frequency = (ALfloat)Device->Frequency; ALfloat rate; ALint phase; @@ -111,8 +113,8 @@ static ALvoid ALflangerState_update(ALflangerState *state, ALCdevice *Device, co state->delay = fastf2i(Slot->EffectProps.Flanger.Delay * frequency); /* Gains for left and right sides */ - ComputeAngleGains(Device, atan2f(-1.0f, 0.0f), 0.0f, Slot->Gain, state->Gain[0]); - ComputeAngleGains(Device, atan2f(+1.0f, 0.0f), 0.0f, Slot->Gain, state->Gain[1]); + ComputeDirectionalGains(Device, left_dir, Slot->Gain, state->Gain[0]); + ComputeDirectionalGains(Device, right_dir, Slot->Gain, state->Gain[1]); phase = Slot->EffectProps.Flanger.Phase; rate = Slot->EffectProps.Flanger.Rate; diff --git a/Alc/effects/reverb.c b/Alc/effects/reverb.c index 1e9cd550..8c17076a 100644 --- a/Alc/effects/reverb.c +++ b/Alc/effects/reverb.c @@ -1031,44 +1031,54 @@ static ALvoid UpdateEchoLine(ALfloat reverbGain, ALfloat lateGain, ALfloat echoT // Update the early and late 3D panning gains. static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *ReflectionsPan, const ALfloat *LateReverbPan, ALfloat Gain, ALreverbState *State) { - ALfloat earlyPan[3] = { ReflectionsPan[0], ReflectionsPan[1], - ReflectionsPan[2] }; - ALfloat latePan[3] = { LateReverbPan[0], LateReverbPan[1], - LateReverbPan[2] }; + ALfloat earlyPan[3] = { ReflectionsPan[0], ReflectionsPan[1], ReflectionsPan[2] }; + ALfloat latePan[3] = { LateReverbPan[0], LateReverbPan[1], LateReverbPan[2] }; + ALfloat earlyLen = 0.0f; + ALfloat lateLen = 0.0f; + ALfloat length, invlen; ALfloat ambientGain; - ALfloat dirGain; - ALfloat length; + ALuint i; Gain *= ReverbBoost; - /* Attenuate reverb according to its coverage (dirGain=0 will give - * Gain*ambientGain, and dirGain=1 will give Gain). */ - ambientGain = minf(sqrtf(2.0f/Device->NumSpeakers), 1.0f); + /* Attenuate reverb according to its coverage (len=0 will give + * ambientGain, and len>=1 will be fully panned using Gain). */ + ambientGain = minf(sqrtf(2.0f/Device->NumSpeakers), 1.0f) * Gain; length = earlyPan[0]*earlyPan[0] + earlyPan[1]*earlyPan[1] + earlyPan[2]*earlyPan[2]; - if(length > 1.0f) + if(length > FLT_EPSILON) { - length = 1.0f / sqrtf(length); - earlyPan[0] *= length; - earlyPan[1] *= length; - earlyPan[2] *= length; + length = sqrtf(length); + + invlen = 1.0f / length; + earlyPan[0] *= invlen; + earlyPan[1] *= invlen; + earlyPan[2] *= invlen; + + earlyLen = minf(1.0f, length); + ComputeDirectionalGains(Device, earlyPan, Gain, State->Early.PanGain); } + length = latePan[0]*latePan[0] + latePan[1]*latePan[1] + latePan[2]*latePan[2]; - if(length > 1.0f) + if(length > FLT_EPSILON) { - length = 1.0f / sqrtf(length); - latePan[0] *= length; - latePan[1] *= length; - latePan[2] *= length; - } + length = sqrtf(length); - dirGain = sqrtf(earlyPan[0]*earlyPan[0] + earlyPan[2]*earlyPan[2]); - ComputeAngleGains(Device, atan2f(earlyPan[0], earlyPan[2]), (1.0f-dirGain)*F_PI, - lerp(ambientGain, 1.0f, dirGain) * Gain, State->Early.PanGain); + invlen = 1.0f / length; + latePan[0] *= invlen; + latePan[1] *= invlen; + latePan[2] *= invlen; - dirGain = sqrtf(latePan[0]*latePan[0] + latePan[2]*latePan[2]); - ComputeAngleGains(Device, atan2f(latePan[0], latePan[2]), (1.0f-dirGain)*F_PI, - lerp(ambientGain, 1.0f, dirGain) * Gain, State->Late.PanGain); + lateLen = minf(1.0f, length); + ComputeDirectionalGains(Device, latePan, Gain, State->Late.PanGain); + } + + for(i = 0;i < Device->NumSpeakers;i++) + { + enum Channel chan = Device->Speaker[i].ChanName; + State->Early.PanGain[chan] = lerp(ambientGain, State->Early.PanGain[chan], earlyLen); + State->Late.PanGain[chan] = lerp(ambientGain, State->Late.PanGain[chan], lateLen); + } } static ALvoid ALreverbState_update(ALreverbState *State, ALCdevice *Device, const ALeffectslot *Slot) diff --git a/Alc/panning.c b/Alc/panning.c index d0c89071..d775b746 100644 --- a/Alc/panning.c +++ b/Alc/panning.c @@ -81,200 +81,14 @@ static inline void Set3rdOrder(ALfloat coeffs[16], ALfloat w, ALfloat x, ALfloat } -void ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat hwidth, ALfloat ingain, ALfloat gains[MaxChannels]) +void ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat elevation, ALfloat ingain, ALfloat gains[MaxChannels]) { - ALfloat tmpgains[MaxChannels] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; - enum Channel Speaker2Chan[MaxChannels]; - ALfloat SpeakerAngle[MaxChannels]; - ALfloat langle, rangle; - ALfloat a; - ALuint i; - - for(i = 0;i < device->NumSpeakers;i++) - Speaker2Chan[i] = device->Speaker[i].ChanName; - for(i = 0;i < device->NumSpeakers;i++) - SpeakerAngle[i] = device->Speaker[i].Angle; - - for(i = 0;i < MaxChannels;i++) - gains[i] = 0.0f; - - /* Some easy special-cases first... */ - if(device->NumSpeakers <= 1 || hwidth >= F_PI) - { - /* Full coverage for all speakers. */ - for(i = 0;i < device->NumSpeakers;i++) - { - enum Channel chan = Speaker2Chan[i]; - gains[chan] = ingain; - } - return; - } - if(hwidth <= 0.0f) - { - /* Infinitely small sound point. */ - for(i = 0;i < device->NumSpeakers-1;i++) - { - if(angle >= SpeakerAngle[i] && angle < SpeakerAngle[i+1]) - { - /* Sound is between speakers i and i+1 */ - a = (angle-SpeakerAngle[i]) / - (SpeakerAngle[i+1]-SpeakerAngle[i]); - gains[Speaker2Chan[i]] = sqrtf(1.0f-a) * ingain; - gains[Speaker2Chan[i+1]] = sqrtf( a) * ingain; - return; - } - } - /* Sound is between last and first speakers */ - if(angle < SpeakerAngle[0]) - angle += F_2PI; - a = (angle-SpeakerAngle[i]) / - (F_2PI + SpeakerAngle[0]-SpeakerAngle[i]); - gains[Speaker2Chan[i]] = sqrtf(1.0f-a) * ingain; - gains[Speaker2Chan[0]] = sqrtf( a) * ingain; - return; - } - - if(fabsf(angle)+hwidth > F_PI) - { - /* The coverage area would go outside of -pi...+pi. Instead, rotate the - * speaker angles so it would be as if angle=0, and keep them wrapped - * within -pi...+pi. */ - if(angle > 0.0f) - { - ALuint done; - ALuint i = 0; - while(i < device->NumSpeakers && device->Speaker[i].Angle-angle < -F_PI) - i++; - for(done = 0;i < device->NumSpeakers;done++) - { - SpeakerAngle[done] = device->Speaker[i].Angle-angle; - Speaker2Chan[done] = device->Speaker[i].ChanName; - i++; - } - for(i = 0;done < device->NumSpeakers;i++) - { - SpeakerAngle[done] = device->Speaker[i].Angle-angle + F_2PI; - Speaker2Chan[done] = device->Speaker[i].ChanName; - done++; - } - } - else - { - /* NOTE: '< device->NumChan' on the iterators is correct here since - * we need to handle index 0. Because the iterators are unsigned, - * they'll underflow and wrap to become 0xFFFFFFFF, which will - * break as expected. */ - ALuint done; - ALuint i = device->NumSpeakers-1; - while(i < device->NumSpeakers && device->Speaker[i].Angle-angle > F_PI) - i--; - for(done = device->NumSpeakers-1;i < device->NumSpeakers;done--) - { - SpeakerAngle[done] = device->Speaker[i].Angle-angle; - Speaker2Chan[done] = device->Speaker[i].ChanName; - i--; - } - for(i = device->NumSpeakers-1;done < device->NumSpeakers;i--) - { - SpeakerAngle[done] = device->Speaker[i].Angle-angle - F_2PI; - Speaker2Chan[done] = device->Speaker[i].ChanName; - done--; - } - } - angle = 0.0f; - } - langle = angle - hwidth; - rangle = angle + hwidth; - - /* First speaker */ - i = 0; - do { - ALuint last = device->NumSpeakers-1; - enum Channel chan = Speaker2Chan[i]; - - if(SpeakerAngle[i] >= langle && SpeakerAngle[i] <= rangle) - { - tmpgains[chan] = 1.0f; - continue; - } - - if(SpeakerAngle[i] < langle && SpeakerAngle[i+1] > langle) - { - a = (langle-SpeakerAngle[i]) / - (SpeakerAngle[i+1]-SpeakerAngle[i]); - tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a); - } - if(SpeakerAngle[i] > rangle) - { - a = (F_2PI + rangle-SpeakerAngle[last]) / - (F_2PI + SpeakerAngle[i]-SpeakerAngle[last]); - tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a); - } - else if(SpeakerAngle[last] < rangle) - { - a = (rangle-SpeakerAngle[last]) / - (F_2PI + SpeakerAngle[i]-SpeakerAngle[last]); - tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a); - } - } while(0); - - for(i = 1;i < device->NumSpeakers-1;i++) - { - enum Channel chan = Speaker2Chan[i]; - if(SpeakerAngle[i] >= langle && SpeakerAngle[i] <= rangle) - { - tmpgains[chan] = 1.0f; - continue; - } - - if(SpeakerAngle[i] < langle && SpeakerAngle[i+1] > langle) - { - a = (langle-SpeakerAngle[i]) / - (SpeakerAngle[i+1]-SpeakerAngle[i]); - tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a); - } - if(SpeakerAngle[i] > rangle && SpeakerAngle[i-1] < rangle) - { - a = (rangle-SpeakerAngle[i-1]) / - (SpeakerAngle[i]-SpeakerAngle[i-1]); - tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a); - } - } - - /* Last speaker */ - i = device->NumSpeakers-1; - do { - enum Channel chan = Speaker2Chan[i]; - if(SpeakerAngle[i] >= langle && SpeakerAngle[i] <= rangle) - { - tmpgains[Speaker2Chan[i]] = 1.0f; - continue; - } - if(SpeakerAngle[i] > rangle && SpeakerAngle[i-1] < rangle) - { - a = (rangle-SpeakerAngle[i-1]) / - (SpeakerAngle[i]-SpeakerAngle[i-1]); - tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a); - } - if(SpeakerAngle[i] < langle) - { - a = (langle-SpeakerAngle[i]) / - (F_2PI + SpeakerAngle[0]-SpeakerAngle[i]); - tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a); - } - else if(SpeakerAngle[0] > langle) - { - a = (F_2PI + langle-SpeakerAngle[i]) / - (F_2PI + SpeakerAngle[0]-SpeakerAngle[i]); - tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a); - } - } while(0); - - for(i = 0;i < device->NumSpeakers;i++) - { - enum Channel chan = device->Speaker[i].ChanName; - gains[chan] = sqrtf(tmpgains[chan]) * ingain; - } + ALfloat dir[3] = { + -sinf(angle) * cosf(elevation), + sinf(elevation), + -cosf(angle) * cosf(elevation) + }; + ComputeDirectionalGains(device, dir, ingain, gains); } void ComputeDirectionalGains(const ALCdevice *device, const ALfloat dir[3], ALfloat ingain, ALfloat gains[MaxChannels]) @@ -323,6 +137,7 @@ ALvoid aluInitPanning(ALCdevice *device) device->NumSpeakers = 1; device->Speaker[0].ChanName = FrontCenter; device->Speaker[0].Angle = DEG2RAD(0.0f); + device->Speaker[0].Elevation = DEG2RAD(0.0f); Set0thOrder(device->Speaker[0].Coeff, 1.4142f); break; @@ -332,6 +147,8 @@ ALvoid aluInitPanning(ALCdevice *device) device->Speaker[1].ChanName = FrontRight; device->Speaker[0].Angle = DEG2RAD(-90.0f); device->Speaker[1].Angle = DEG2RAD( 90.0f); + device->Speaker[0].Elevation = DEG2RAD(0.0f); + device->Speaker[1].Elevation = DEG2RAD(0.0f); Set1stOrder(device->Speaker[0].Coeff, 0.7071f, -0.5f, 0.0f, 0.0f); Set1stOrder(device->Speaker[1].Coeff, 0.7071f, 0.5f, 0.0f, 0.0f); break; @@ -346,6 +163,10 @@ ALvoid aluInitPanning(ALCdevice *device) device->Speaker[1].Angle = DEG2RAD( -45.0f); device->Speaker[2].Angle = DEG2RAD( 45.0f); device->Speaker[3].Angle = DEG2RAD( 135.0f); + device->Speaker[0].Elevation = DEG2RAD(0.0f); + device->Speaker[1].Elevation = DEG2RAD(0.0f); + device->Speaker[2].Elevation = DEG2RAD(0.0f); + device->Speaker[3].Elevation = DEG2RAD(0.0f); Set2ndOrder(device->Speaker[0].Coeff, 0.353543f, -0.306192f, 0.306181f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.117193f); Set2ndOrder(device->Speaker[1].Coeff, 0.353558f, 0.306181f, 0.306192f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.117183f); Set2ndOrder(device->Speaker[2].Coeff, 0.353543f, 0.306181f, -0.306192f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.117193f); @@ -364,6 +185,11 @@ ALvoid aluInitPanning(ALCdevice *device) device->Speaker[2].Angle = DEG2RAD( 0.0f); device->Speaker[3].Angle = DEG2RAD( 30.0f); device->Speaker[4].Angle = DEG2RAD( 110.0f); + device->Speaker[0].Elevation = DEG2RAD(0.0f); + device->Speaker[1].Elevation = DEG2RAD(0.0f); + device->Speaker[2].Elevation = DEG2RAD(0.0f); + device->Speaker[3].Elevation = DEG2RAD(0.0f); + device->Speaker[4].Elevation = DEG2RAD(0.0f); Set3rdOrder(device->Speaker[0].Coeff, 0.470934f, -0.369630f, 0.349383f, 0.0f, 0.0f, 0.0f, 0.0f, -0.031379f, -0.058143f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.007116f, -0.043968f); Set3rdOrder(device->Speaker[1].Coeff, 0.208954f, 0.212846f, 0.238350f, 0.0f, 0.0f, 0.0f, 0.0f, -0.017738f, 0.204014f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.051023f, 0.047490f); Set3rdOrder(device->Speaker[2].Coeff, 0.109403f, 0.179490f, -0.000002f, 0.0f, 0.0f, 0.0f, 0.0f, 0.142031f, -0.000002f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.072024f, -0.000001f); @@ -383,6 +209,11 @@ ALvoid aluInitPanning(ALCdevice *device) device->Speaker[2].Angle = DEG2RAD( 0.0f); device->Speaker[3].Angle = DEG2RAD( 30.0f); device->Speaker[4].Angle = DEG2RAD( 90.0f); + device->Speaker[0].Elevation = DEG2RAD(0.0f); + device->Speaker[1].Elevation = DEG2RAD(0.0f); + device->Speaker[2].Elevation = DEG2RAD(0.0f); + device->Speaker[3].Elevation = DEG2RAD(0.0f); + device->Speaker[4].Elevation = DEG2RAD(0.0f); Set3rdOrder(device->Speaker[0].Coeff, 0.289151f, -0.081301f, 0.401292f, 0.0f, 0.0f, 0.0f, 0.0f, -0.188208f, -0.071420f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.010099f, -0.032897f); Set3rdOrder(device->Speaker[1].Coeff, 0.167065f, 0.200583f, 0.172695f, 0.0f, 0.0f, 0.0f, 0.0f, 0.029855f, 0.186407f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.039241f, 0.068910f); Set3rdOrder(device->Speaker[2].Coeff, 0.109403f, 0.179490f, -0.000002f, 0.0f, 0.0f, 0.0f, 0.0f, 0.142031f, -0.000002f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.072024f, -0.000001f); @@ -404,6 +235,12 @@ ALvoid aluInitPanning(ALCdevice *device) device->Speaker[3].Angle = DEG2RAD( 30.0f); device->Speaker[4].Angle = DEG2RAD( 90.0f); device->Speaker[5].Angle = DEG2RAD(180.0f); + device->Speaker[0].Elevation = DEG2RAD(0.0f); + device->Speaker[1].Elevation = DEG2RAD(0.0f); + device->Speaker[2].Elevation = DEG2RAD(0.0f); + device->Speaker[3].Elevation = DEG2RAD(0.0f); + device->Speaker[4].Elevation = DEG2RAD(0.0f); + device->Speaker[5].Elevation = DEG2RAD(0.0f); Set3rdOrder(device->Speaker[0].Coeff, 0.289151f, -0.081301f, 0.401292f, 0.0f, 0.0f, 0.0f, 0.0f, -0.188208f, -0.071420f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.010099f, -0.032897f); Set3rdOrder(device->Speaker[1].Coeff, 0.167065f, 0.200583f, 0.172695f, 0.0f, 0.0f, 0.0f, 0.0f, 0.029855f, 0.186407f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.039241f, 0.068910f); Set3rdOrder(device->Speaker[2].Coeff, 0.109403f, 0.179490f, -0.000002f, 0.0f, 0.0f, 0.0f, 0.0f, 0.142031f, -0.000002f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.072024f, -0.000001f); @@ -428,6 +265,13 @@ ALvoid aluInitPanning(ALCdevice *device) device->Speaker[4].Angle = DEG2RAD( 30.0f); device->Speaker[5].Angle = DEG2RAD( 90.0f); device->Speaker[6].Angle = DEG2RAD( 150.0f); + device->Speaker[0].Elevation = DEG2RAD(0.0f); + device->Speaker[1].Elevation = DEG2RAD(0.0f); + device->Speaker[2].Elevation = DEG2RAD(0.0f); + device->Speaker[3].Elevation = DEG2RAD(0.0f); + device->Speaker[4].Elevation = DEG2RAD(0.0f); + device->Speaker[5].Elevation = DEG2RAD(0.0f); + device->Speaker[6].Elevation = DEG2RAD(0.0f); Set3rdOrder(device->Speaker[0].Coeff, 0.224752f, -0.295009f, 0.170325f, 0.0f, 0.0f, 0.0f, 0.0f, 0.105349f, -0.182473f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.000000f, 0.065799f); Set3rdOrder(device->Speaker[1].Coeff, 0.224739f, 0.000002f, 0.340644f, 0.0f, 0.0f, 0.0f, 0.0f, -0.210697f, 0.000002f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.000000f, -0.065795f); Set3rdOrder(device->Speaker[2].Coeff, 0.167065f, 0.200583f, 0.172695f, 0.0f, 0.0f, 0.0f, 0.0f, 0.029855f, 0.186407f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.039241f, 0.068910f); |