Improve radius behavior with scaling of ambisonic coefficients
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+12
-12
@@ -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.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, 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.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++)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
+10
-4
@@ -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]);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
+4
-1
@@ -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]);
|
||||
|
||||
|
||||
+1
-1
@@ -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 */
|
||||
|
||||
+52
-5
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user