aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2016-04-24 21:42:59 -0700
committerChris Robinson <[email protected]>2016-04-24 21:42:59 -0700
commitf0871c8cfcb329e847fd48256fd32f20d2c7e827 (patch)
tree6094609d7c173efa66894705d63d1f018bbf0f63
parentfdee577940a4669e9723a16c4c625567694589ec (diff)
Improve radius behavior with scaling of ambisonic coefficients
-rw-r--r--Alc/ALu.c57
-rw-r--r--Alc/bformatdec.c26
-rw-r--r--Alc/effects/chorus.c4
-rw-r--r--Alc/effects/dedicated.c2
-rw-r--r--Alc/effects/echo.c14
-rw-r--r--Alc/effects/flanger.c4
-rw-r--r--Alc/effects/reverb.c12
-rw-r--r--Alc/hrtf.c5
-rw-r--r--Alc/hrtf.h2
-rw-r--r--Alc/panning.c57
-rw-r--r--OpenAL32/Include/alu.h11
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