From f0871c8cfcb329e847fd48256fd32f20d2c7e827 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 24 Apr 2016 21:42:59 -0700 Subject: [PATCH] Improve radius behavior with scaling of ambisonic coefficients --- Alc/ALu.c | 57 ++++++++++++++++++++----------------------------- Alc/bformatdec.c | 26 +++++++++++----------- Alc/effects/chorus.c | 4 ++-- Alc/effects/dedicated.c | 2 +- Alc/effects/echo.c | 14 ++++++++---- Alc/effects/flanger.c | 4 ++-- Alc/effects/reverb.c | 12 +++++------ Alc/hrtf.c | 5 ++++- Alc/hrtf.h | 2 +- Alc/panning.c | 57 ++++++++++++++++++++++++++++++++++++++++++++----- OpenAL32/Include/alu.h | 11 +++++----- 11 files changed, 120 insertions(+), 74 deletions(-) diff --git a/Alc/ALu.c b/Alc/ALu.c index 6d07afe2..e137a904 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -567,7 +567,7 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A * channel-match. */ for(c = 0;c < num_channels;c++) { - CalcAngleCoeffs(chans[c].angle, chans[c].elevation, coeffs); + CalcAngleCoeffs(chans[c].angle, chans[c].elevation, 0.0f, coeffs); for(i = 0;i < NumSends;i++) { @@ -618,13 +618,13 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A /* Get the static HRIR coefficients and delays for this channel. */ GetLerpedHrtfCoeffs(Device->Hrtf, - chans[c].elevation, chans[c].angle, 1.0f, DryGain, + chans[c].elevation, chans[c].angle, 0.0f, DryGain, voice->Direct.Hrtf[c].Target.Coeffs, voice->Direct.Hrtf[c].Target.Delay ); /* Normal panning for auxiliary sends. */ - CalcAngleCoeffs(chans[c].angle, chans[c].elevation, coeffs); + CalcAngleCoeffs(chans[c].angle, chans[c].elevation, 0.0f, coeffs); for(i = 0;i < NumSends;i++) { @@ -680,11 +680,11 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A for(j = 2;j < MAX_OUTPUT_CHANNELS;j++) voice->Direct.Gains[c].Target[j] = 0.0f; - CalcAngleCoeffs(chans[c].angle, chans[c].elevation, coeffs); + CalcAngleCoeffs(chans[c].angle, chans[c].elevation, 0.0f, coeffs); } else { - CalcAngleCoeffs(chans[c].angle, chans[c].elevation, coeffs); + CalcAngleCoeffs(chans[c].angle, chans[c].elevation, 0.0f, coeffs); ComputePanningGains(Device->Dry, coeffs, DryGain, voice->Direct.Gains[c].Target); } @@ -1091,8 +1091,8 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte aluVector dir = {{ 0.0f, 0.0f, -1.0f, 0.0f }}; ALfloat ev = 0.0f, az = 0.0f; ALfloat radius = ALSource->Radius; - ALfloat dirfact = 1.0f; ALfloat coeffs[MAX_AMBI_COEFFS]; + ALfloat spread = 0.0f; voice->Direct.OutBuffer = Device->RealOut.Buffer; voice->Direct.OutChannels = Device->RealOut.NumChannels; @@ -1110,23 +1110,17 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte ev = asinf(clampf(dir.v[1], -1.0f, 1.0f)); az = atan2f(dir.v[0], -dir.v[2]); } - if(radius > 0.0f) - { - if(radius >= Distance) - dirfact *= Distance / radius * 0.5f; - else - dirfact *= 1.0f - (asinf(radius / Distance) / F_PI); - } + if(radius > Distance) + spread = F_TAU - Distance/radius*F_PI; + else if(Distance > FLT_EPSILON) + spread = asinf(radius / Distance) * 2.0f; /* Get the HRIR coefficients and delays. */ - GetLerpedHrtfCoeffs(Device->Hrtf, ev, az, dirfact, DryGain, + GetLerpedHrtfCoeffs(Device->Hrtf, ev, az, spread, DryGain, voice->Direct.Hrtf[0].Target.Coeffs, voice->Direct.Hrtf[0].Target.Delay); - dir.v[0] *= dirfact; - dir.v[1] *= dirfact; - dir.v[2] *= dirfact; - CalcDirectionCoeffs(dir.v, coeffs); + CalcDirectionCoeffs(dir.v, spread, coeffs); for(i = 0;i < NumSends;i++) { @@ -1152,6 +1146,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte ALfloat dir[3] = { 0.0f, 0.0f, -1.0f }; ALfloat radius = ALSource->Radius; ALfloat coeffs[MAX_AMBI_COEFFS]; + ALfloat spread = 0.0f; /* Get the localized direction, and compute panned gains. */ if(Distance > FLT_EPSILON) @@ -1160,32 +1155,26 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte dir[1] = -SourceToListener.v[1]; dir[2] = -SourceToListener.v[2] * ZScale; } - if(radius > 0.0f) - { - ALfloat dirfact; - if(radius >= Distance) - dirfact = Distance / radius * 0.5f; - else - dirfact = 1.0f - (asinf(radius / Distance) / F_PI); - dir[0] *= dirfact; - dir[1] *= dirfact; - dir[2] *= dirfact; - } + if(radius > Distance) + spread = F_TAU - Distance/radius*F_PI; + else if(Distance > FLT_EPSILON) + spread = asinf(radius / Distance) * 2.0f; if(Device->Render_Mode == StereoPair) { /* Clamp X so it remains within 30 degrees of 0 or 180 degree azimuth. */ - coeffs[0] = clampf(-dir[0], -0.5f, 0.5f) + 0.5f; - voice->Direct.Gains[0].Target[0] = coeffs[0] * DryGain; - voice->Direct.Gains[0].Target[1] = (1.0f-coeffs[0]) * DryGain; + ALfloat x = -dir[0] * (0.5f * (cosf(spread*0.5f) + 1.0f)); + x = clampf(x, -0.5f, 0.5f) + 0.5f; + voice->Direct.Gains[0].Target[0] = x * DryGain; + voice->Direct.Gains[0].Target[1] = (1.0f-x) * DryGain; for(i = 2;i < MAX_OUTPUT_CHANNELS;i++) voice->Direct.Gains[0].Target[i] = 0.0f; - CalcDirectionCoeffs(dir, coeffs); + CalcDirectionCoeffs(dir, spread, coeffs); } else { - CalcDirectionCoeffs(dir, coeffs); + CalcDirectionCoeffs(dir, spread, coeffs); ComputePanningGains(Device->Dry, coeffs, DryGain, voice->Direct.Gains[0].Target); } diff --git a/Alc/bformatdec.c b/Alc/bformatdec.c index dd0561d0..e32053c8 100644 --- a/Alc/bformatdec.c +++ b/Alc/bformatdec.c @@ -150,19 +150,19 @@ static void init_encoder(void) { ALuint i, j; - CalcXYZCoeffs(-0.577350269f, 0.577350269f, -0.577350269f, CubeEncoder[0]); - CalcXYZCoeffs( 0.577350269f, 0.577350269f, -0.577350269f, CubeEncoder[1]); - CalcXYZCoeffs(-0.577350269f, 0.577350269f, 0.577350269f, CubeEncoder[2]); - CalcXYZCoeffs( 0.577350269f, 0.577350269f, 0.577350269f, CubeEncoder[3]); - CalcXYZCoeffs(-0.577350269f, -0.577350269f, -0.577350269f, CubeEncoder[4]); - CalcXYZCoeffs( 0.577350269f, -0.577350269f, -0.577350269f, CubeEncoder[5]); - CalcXYZCoeffs(-0.577350269f, -0.577350269f, 0.577350269f, CubeEncoder[6]); - CalcXYZCoeffs( 0.577350269f, -0.577350269f, 0.577350269f, CubeEncoder[7]); - - CalcXYZCoeffs(-0.707106781f, 0.0f, -0.707106781f, SquareEncoder[0]); - CalcXYZCoeffs( 0.707106781f, 0.0f, -0.707106781f, SquareEncoder[1]); - CalcXYZCoeffs(-0.707106781f, 0.0f, 0.707106781f, SquareEncoder[2]); - CalcXYZCoeffs( 0.707106781f, 0.0f, 0.707106781f, SquareEncoder[3]); + CalcXYZCoeffs(-0.577350269f, 0.577350269f, -0.577350269f, 0.0f, CubeEncoder[0]); + CalcXYZCoeffs( 0.577350269f, 0.577350269f, -0.577350269f, 0.0f, CubeEncoder[1]); + CalcXYZCoeffs(-0.577350269f, 0.577350269f, 0.577350269f, 0.0f, CubeEncoder[2]); + CalcXYZCoeffs( 0.577350269f, 0.577350269f, 0.577350269f, 0.0f, CubeEncoder[3]); + CalcXYZCoeffs(-0.577350269f, -0.577350269f, -0.577350269f, 0.0f, CubeEncoder[4]); + CalcXYZCoeffs( 0.577350269f, -0.577350269f, -0.577350269f, 0.0f, CubeEncoder[5]); + CalcXYZCoeffs(-0.577350269f, -0.577350269f, 0.577350269f, 0.0f, CubeEncoder[6]); + CalcXYZCoeffs( 0.577350269f, -0.577350269f, 0.577350269f, 0.0f, CubeEncoder[7]); + + CalcXYZCoeffs(-0.707106781f, 0.0f, -0.707106781f, 0.0f, SquareEncoder[0]); + CalcXYZCoeffs( 0.707106781f, 0.0f, -0.707106781f, 0.0f, SquareEncoder[1]); + CalcXYZCoeffs(-0.707106781f, 0.0f, 0.707106781f, 0.0f, SquareEncoder[2]); + CalcXYZCoeffs( 0.707106781f, 0.0f, 0.707106781f, 0.0f, SquareEncoder[3]); for(i = 0;i < 4;i++) { diff --git a/Alc/effects/chorus.c b/Alc/effects/chorus.c index 94c9fc47..9deb2a1f 100644 --- a/Alc/effects/chorus.c +++ b/Alc/effects/chorus.c @@ -112,9 +112,9 @@ static ALvoid ALchorusState_update(ALchorusState *state, const ALCdevice *Device state->delay = fastf2i(Slot->EffectProps.Chorus.Delay * frequency); /* Gains for left and right sides */ - CalcXYZCoeffs(-1.0f, 0.0f, 0.0f, coeffs); + CalcXYZCoeffs(-1.0f, 0.0f, 0.0f, 0.0f, coeffs); ComputePanningGains(Device->Dry, coeffs, Slot->Gain, state->Gain[0]); - CalcXYZCoeffs( 1.0f, 0.0f, 0.0f, coeffs); + CalcXYZCoeffs( 1.0f, 0.0f, 0.0f, 0.0f, coeffs); ComputePanningGains(Device->Dry, coeffs, Slot->Gain, state->Gain[1]); phase = Slot->EffectProps.Chorus.Phase; diff --git a/Alc/effects/dedicated.c b/Alc/effects/dedicated.c index 12b16137..f510e8fe 100644 --- a/Alc/effects/dedicated.c +++ b/Alc/effects/dedicated.c @@ -78,7 +78,7 @@ static ALvoid ALdedicatedState_update(ALdedicatedState *state, const ALCdevice * else { ALfloat coeffs[MAX_AMBI_COEFFS]; - CalcXYZCoeffs(0.0f, 0.0f, -1.0f, coeffs); + CalcXYZCoeffs(0.0f, 0.0f, -1.0f, 0.0f, coeffs); STATIC_CAST(ALeffectState,state)->OutBuffer = device->Dry.Buffer; STATIC_CAST(ALeffectState,state)->OutChannels = device->Dry.NumChannels; diff --git a/Alc/effects/echo.c b/Alc/effects/echo.c index 9fd31864..8600db70 100644 --- a/Alc/effects/echo.c +++ b/Alc/effects/echo.c @@ -85,13 +85,19 @@ static ALvoid ALechoState_update(ALechoState *state, const ALCdevice *Device, co { ALuint frequency = Device->Frequency; ALfloat coeffs[MAX_AMBI_COEFFS]; - ALfloat gain, lrpan; + ALfloat gain, lrpan, spread; state->Tap[0].delay = fastf2u(Slot->EffectProps.Echo.Delay * frequency) + 1; state->Tap[1].delay = fastf2u(Slot->EffectProps.Echo.LRDelay * frequency); state->Tap[1].delay += state->Tap[0].delay; - lrpan = Slot->EffectProps.Echo.Spread; + spread = Slot->EffectProps.Echo.Spread; + if(spread < 0.0f) lrpan = -1.0f; + else lrpan = 1.0f; + /* Convert echo spread (where 0 = omni, +/-1 = directional) to coverage + * spread (where 0 = point, tau = omni). + */ + spread = asinf(1.0f - fabsf(spread))*4.0f; state->FeedGain = Slot->EffectProps.Echo.Feedback; @@ -103,11 +109,11 @@ static ALvoid ALechoState_update(ALechoState *state, const ALCdevice *Device, co gain = Slot->Gain; /* First tap panning */ - CalcXYZCoeffs(-lrpan, 0.0f, 0.0f, coeffs); + CalcXYZCoeffs(-lrpan, 0.0f, 0.0f, spread, coeffs); ComputePanningGains(Device->Dry, coeffs, gain, state->Gain[0]); /* Second tap panning */ - CalcXYZCoeffs( lrpan, 0.0f, 0.0f, coeffs); + CalcXYZCoeffs( lrpan, 0.0f, 0.0f, spread, coeffs); ComputePanningGains(Device->Dry, coeffs, gain, state->Gain[1]); } diff --git a/Alc/effects/flanger.c b/Alc/effects/flanger.c index e394f9f2..a71eb9c2 100644 --- a/Alc/effects/flanger.c +++ b/Alc/effects/flanger.c @@ -112,9 +112,9 @@ static ALvoid ALflangerState_update(ALflangerState *state, const ALCdevice *Devi state->delay = fastf2i(Slot->EffectProps.Flanger.Delay * frequency); /* Gains for left and right sides */ - CalcXYZCoeffs(-1.0f, 0.0f, 0.0f, coeffs); + CalcXYZCoeffs(-1.0f, 0.0f, 0.0f, 0.0f, coeffs); ComputePanningGains(Device->Dry, coeffs, Slot->Gain, state->Gain[0]); - CalcXYZCoeffs( 1.0f, 0.0f, 0.0f, coeffs); + CalcXYZCoeffs( 1.0f, 0.0f, 0.0f, 0.0f, coeffs); ComputePanningGains(Device->Dry, coeffs, Slot->Gain, state->Gain[1]); phase = Slot->EffectProps.Flanger.Phase; diff --git a/Alc/effects/reverb.c b/Alc/effects/reverb.c index bb980ac2..ef3ab6c3 100644 --- a/Alc/effects/reverb.c +++ b/Alc/effects/reverb.c @@ -719,7 +719,7 @@ static ALvoid UpdateMixedPanning(const ALCdevice *Device, const ALfloat *Reflect }; length = minf(length, 1.0f); - CalcDirectionCoeffs(pan, coeffs); + CalcDirectionCoeffs(pan, 0.0f, coeffs); ComputePanningGains(Device->Dry, coeffs, Gain, DirGains); for(i = 0;i < Device->Dry.NumChannels;i++) State->Early.PanGain[3][i] = DirGains[i] * EarlyGain * length; @@ -743,7 +743,7 @@ static ALvoid UpdateMixedPanning(const ALCdevice *Device, const ALfloat *Reflect }; length = minf(length, 1.0f); - CalcDirectionCoeffs(pan, coeffs); + CalcDirectionCoeffs(pan, 0.0f, coeffs); ComputePanningGains(Device->Dry, coeffs, Gain, DirGains); for(i = 0;i < Device->Dry.NumChannels;i++) State->Late.PanGain[3][i] = DirGains[i] * LateGain * length; @@ -783,7 +783,7 @@ static ALvoid UpdateDirectPanning(const ALCdevice *Device, const ALfloat *Reflec }; length = minf(length, 1.0f); - CalcDirectionCoeffs(pan, coeffs); + CalcDirectionCoeffs(pan, 0.0f, coeffs); ComputePanningGains(Device->Dry, coeffs, Gain, DirGains); for(i = 0;i < Device->Dry.NumChannels;i++) State->Early.PanGain[i&3][i] = lerp(AmbientGains[i], DirGains[i], length) * EarlyGain; @@ -805,7 +805,7 @@ static ALvoid UpdateDirectPanning(const ALCdevice *Device, const ALfloat *Reflec }; length = minf(length, 1.0f); - CalcDirectionCoeffs(pan, coeffs); + CalcDirectionCoeffs(pan, 0.0f, coeffs); ComputePanningGains(Device->Dry, coeffs, Gain, DirGains); for(i = 0;i < Device->Dry.NumChannels;i++) State->Late.PanGain[i&3][i] = lerp(AmbientGains[i], DirGains[i], length) * LateGain; @@ -855,7 +855,7 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection } for(i = 0;i < 4;i++) { - CalcDirectionCoeffs(PanDirs[i], coeffs); + CalcDirectionCoeffs(PanDirs[i], 0.0f, coeffs); ComputePanningGains(Device->Dry, coeffs, Gain*EarlyGain*gain[i], State->Early.PanGain[i]); } @@ -886,7 +886,7 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection } for(i = 0;i < 4;i++) { - CalcDirectionCoeffs(PanDirs[i], coeffs); + CalcDirectionCoeffs(PanDirs[i], 0.0f, coeffs); ComputePanningGains(Device->Dry, coeffs, Gain*LateGain*gain[i], State->Late.PanGain[i]); } diff --git a/Alc/hrtf.c b/Alc/hrtf.c index 9549c010..1f972f87 100644 --- a/Alc/hrtf.c +++ b/Alc/hrtf.c @@ -96,12 +96,15 @@ static void CalcAzIndices(ALuint azcount, ALfloat az, ALuint *azidx, ALfloat *az * increase the apparent resolution of the HRIR data set. The coefficients * are also normalized and attenuated by the specified gain. */ -void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat dirfact, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays) +void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat spread, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays) { ALuint evidx[2], lidx[4], ridx[4]; ALfloat mu[3], blend[4]; + ALfloat dirfact; ALuint i; + dirfact = 1.0f - (spread / F_TAU); + /* Claculate elevation indices and interpolation factor. */ CalcEvIndices(Hrtf->evCount, elevation, evidx, &mu[2]); diff --git a/Alc/hrtf.h b/Alc/hrtf.h index 2b96a583..e8a127c7 100644 --- a/Alc/hrtf.h +++ b/Alc/hrtf.h @@ -30,6 +30,6 @@ void FreeHrtfList(vector_HrtfEntry *list); ALuint GetHrtfSampleRate(const struct Hrtf *Hrtf); ALuint GetHrtfIrSize(const struct Hrtf *Hrtf); -void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat dirfact, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays); +void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat spread, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays); #endif /* ALC_HRTF_H */ diff --git a/Alc/panning.c b/Alc/panning.c index 51b8e5cc..9ff97477 100644 --- a/Alc/panning.c +++ b/Alc/panning.c @@ -36,7 +36,7 @@ #include "bs2b.h" -extern inline void CalcXYZCoeffs(ALfloat x, ALfloat y, ALfloat z, ALfloat coeffs[MAX_AMBI_COEFFS]); +extern inline void CalcXYZCoeffs(ALfloat x, ALfloat y, ALfloat z, ALfloat spread, ALfloat coeffs[MAX_AMBI_COEFFS]); #define ZERO_ORDER_SCALE 0.0f @@ -109,7 +109,7 @@ static const ALfloat FuMa2N3DScale[MAX_AMBI_COEFFS] = { }; -void CalcDirectionCoeffs(const ALfloat dir[3], ALfloat coeffs[MAX_AMBI_COEFFS]) +void CalcDirectionCoeffs(const ALfloat dir[3], ALfloat spread, ALfloat coeffs[MAX_AMBI_COEFFS]) { /* Convert from OpenAL coords to Ambisonics. */ ALfloat x = -dir[2]; @@ -136,16 +136,63 @@ void CalcDirectionCoeffs(const ALfloat dir[3], ALfloat coeffs[MAX_AMBI_COEFFS]) coeffs[13] = 1.620185175f * x * (5.0f*z*z - 1.0f); /* ACN 13 = sqrt(21/8) * X * (5*Z*Z - 1) */ coeffs[14] = 5.123475383f * z * (x*x - y*y); /* ACN 14 = sqrt(105)/2 * Z * (X*X - Y*Y) */ coeffs[15] = 2.091650066f * x * (x*x - 3.0f*y*y); /* ACN 15 = sqrt(35/8) * X * (X*X - 3*Y*Y) */ + + if(spread > 0.0f) + { + /* Implement the spread by using a spherical source that subtends the + * angle spread. See: + * http://www.ppsloan.org/publications/StupidSH36.pdf - Appendix A3 + * + * The gain of the source is compensated for size, so that the + * loundness doesn't depend on the spread. + * + * ZH0 = (-sqrt_pi * (-1.f + ca)); + * ZH1 = ( 0.5f*sqrtf(3.f)*sqrt_pi * sa*sa); + * ZH2 = (-0.5f*sqrtf(5.f)*sqrt_pi * ca*(-1.f+ca)*(ca+1.f)); + * ZH3 = (-0.125f*sqrtf(7.f)*sqrt_pi * (-1.f+ca)*(ca+1.f)*(5.f*ca*ca-1.f)); + * solidangle = 2.f*F_PI*(1.f-ca) + * size_normalisation_coef = 1.f/ZH0; + * + * This is then adjusted for N3D normalization over SN3D. + */ + ALfloat ca = cosf(spread * 0.5f); + + ALfloat ZH0_norm = 1.0f; + ALfloat ZH1_norm = 0.5f * (ca+1.f); + ALfloat ZH2_norm = 0.5f * (ca+1.f)*ca; + ALfloat ZH3_norm = 0.125f * (ca+1.f)*(5.f*ca*ca-1.f); + + /* Zeroth-order */ + coeffs[0] *= ZH0_norm; + /* First-order */ + coeffs[1] *= ZH1_norm; + coeffs[2] *= ZH1_norm; + coeffs[3] *= ZH1_norm; + /* Second-order */ + coeffs[4] *= ZH2_norm; + coeffs[5] *= ZH2_norm; + coeffs[6] *= ZH2_norm; + coeffs[7] *= ZH2_norm; + coeffs[8] *= ZH2_norm; + /* Third-order */ + coeffs[9] *= ZH3_norm; + coeffs[10] *= ZH3_norm; + coeffs[11] *= ZH3_norm; + coeffs[12] *= ZH3_norm; + coeffs[13] *= ZH3_norm; + coeffs[14] *= ZH3_norm; + coeffs[15] *= ZH3_norm; + } } -void CalcAngleCoeffs(ALfloat azimuth, ALfloat elevation, ALfloat coeffs[MAX_AMBI_COEFFS]) +void CalcAngleCoeffs(ALfloat azimuth, ALfloat elevation, ALfloat spread, ALfloat coeffs[MAX_AMBI_COEFFS]) { ALfloat dir[3] = { sinf(azimuth) * cosf(elevation), sinf(elevation), -cosf(azimuth) * cosf(elevation) }; - CalcDirectionCoeffs(dir, coeffs); + CalcDirectionCoeffs(dir, spread, coeffs); } @@ -714,7 +761,7 @@ static void InitHrtfPanning(ALCdevice *device) for(i = 0;i < device->Dry.NumChannels;i++) { int chan = GetChannelIndex(CubeChannels, CubeInfo[i].Channel); - GetLerpedHrtfCoeffs(device->Hrtf, CubeInfo[i].Elevation, CubeInfo[i].Angle, 1.0f, 1.0f, + GetLerpedHrtfCoeffs(device->Hrtf, CubeInfo[i].Elevation, CubeInfo[i].Angle, 1.0f, 0.0f, device->Hrtf_Params[chan].Coeffs, device->Hrtf_Params[chan].Delay); } } diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index c6b5aba0..76a8a921 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -300,9 +300,10 @@ void aluInitEffectPanning(struct ALeffectslot *slot); * CalcDirectionCoeffs * * Calculates ambisonic coefficients based on a direction vector. The vector - * must be normalized (unit length). + * must be normalized (unit length), and the spread is the angular width of the + * sound (0...tau). */ -void CalcDirectionCoeffs(const ALfloat dir[3], ALfloat coeffs[MAX_AMBI_COEFFS]); +void CalcDirectionCoeffs(const ALfloat dir[3], ALfloat spread, ALfloat coeffs[MAX_AMBI_COEFFS]); /** * CalcXYZCoeffs @@ -310,10 +311,10 @@ void CalcDirectionCoeffs(const ALfloat dir[3], ALfloat coeffs[MAX_AMBI_COEFFS]); * Same as CalcDirectionCoeffs except the direction is specified as separate x, * y, and z parameters instead of an array. */ -inline void CalcXYZCoeffs(ALfloat x, ALfloat y, ALfloat z, ALfloat coeffs[MAX_AMBI_COEFFS]) +inline void CalcXYZCoeffs(ALfloat x, ALfloat y, ALfloat z, ALfloat spread, ALfloat coeffs[MAX_AMBI_COEFFS]) { ALfloat dir[3] = { x, y, z }; - CalcDirectionCoeffs(dir, coeffs); + CalcDirectionCoeffs(dir, spread, coeffs); } /** @@ -323,7 +324,7 @@ inline void CalcXYZCoeffs(ALfloat x, ALfloat y, ALfloat z, ALfloat coeffs[MAX_AM * azimuth and elevation parameters are in radians, going right and up * respectively. */ -void CalcAngleCoeffs(ALfloat azimuth, ALfloat elevation, ALfloat coeffs[MAX_AMBI_COEFFS]); +void CalcAngleCoeffs(ALfloat azimuth, ALfloat elevation, ALfloat spread, ALfloat coeffs[MAX_AMBI_COEFFS]); /** * ComputeAmbientGains -- 2.11.4.GIT