Separate calculating ambisonic coefficients from the panning gains
This commit is contained in:
parent
79e0f3e747
commit
f547ef6d39
16
Alc/ALu.c
16
Alc/ALu.c
@ -471,7 +471,7 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A
|
||||
{ SideRight, DEG2RAD( 90.0f), DEG2RAD(0.0f) }
|
||||
};
|
||||
|
||||
ALCdevice *Device = ALContext->Device;
|
||||
const ALCdevice *Device = ALContext->Device;
|
||||
ALfloat SourceVolume,ListenerGain,MinVolume,MaxVolume;
|
||||
ALbufferlistitem *BufferListItem;
|
||||
enum FmtChannels Channels;
|
||||
@ -646,7 +646,7 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A
|
||||
MixGains *gains = voice->Direct.Gains[c];
|
||||
ALfloat Target[MAX_OUTPUT_CHANNELS];
|
||||
|
||||
ComputeBFormatGains(Device, matrix.m[c], DryGain, Target);
|
||||
ComputeBFormatGains(Device->AmbiCoeffs, Device->NumChannels, matrix.m[c], DryGain, Target);
|
||||
for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
|
||||
gains[i].Target = Target[i];
|
||||
}
|
||||
@ -751,6 +751,7 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A
|
||||
{
|
||||
MixGains *gains = voice->Direct.Gains[c];
|
||||
ALfloat Target[MAX_OUTPUT_CHANNELS];
|
||||
ALfloat coeffs[MAX_AMBI_COEFFS];
|
||||
|
||||
/* Special-case LFE */
|
||||
if(chans[c].channel == LFE)
|
||||
@ -763,7 +764,9 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A
|
||||
continue;
|
||||
}
|
||||
|
||||
ComputeAngleGains(Device, chans[c].angle, chans[c].elevation, DryGain, Target);
|
||||
CalcAngleCoeffs(chans[c].angle, chans[c].elevation, coeffs);
|
||||
|
||||
ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, DryGain, Target);
|
||||
for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
|
||||
gains[i].Target = Target[i];
|
||||
}
|
||||
@ -826,7 +829,7 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A
|
||||
|
||||
ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCcontext *ALContext)
|
||||
{
|
||||
ALCdevice *Device = ALContext->Device;
|
||||
const ALCdevice *Device = ALContext->Device;
|
||||
aluVector Position, Velocity, Direction, SourceToListener;
|
||||
ALfloat InnerAngle,OuterAngle,Angle,Distance,ClampedDist;
|
||||
ALfloat MinVolume,MaxVolume,MinDist,MaxDist,Rolloff;
|
||||
@ -1223,6 +1226,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte
|
||||
ALfloat dir[3] = { 0.0f, 0.0f, -1.0f };
|
||||
ALfloat radius = ALSource->Radius;
|
||||
ALfloat Target[MAX_OUTPUT_CHANNELS];
|
||||
ALfloat coeffs[MAX_AMBI_COEFFS];
|
||||
|
||||
/* Get the localized direction, and compute panned gains. */
|
||||
if(Distance > FLT_EPSILON)
|
||||
@ -1242,10 +1246,12 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte
|
||||
dir[1] *= dirfact;
|
||||
dir[2] *= dirfact;
|
||||
}
|
||||
ComputeDirectionalGains(Device, dir, DryGain, Target);
|
||||
CalcDirectionCoeffs(dir, coeffs);
|
||||
|
||||
ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, DryGain, Target);
|
||||
for(j = 0;j < MAX_OUTPUT_CHANNELS;j++)
|
||||
gains[j].Target = Target[j];
|
||||
|
||||
UpdateDryStepping(&voice->Direct, 1, (voice->Direct.Moving ? 64 : 0));
|
||||
voice->Direct.Moving = AL_TRUE;
|
||||
|
||||
|
@ -63,7 +63,7 @@ static ALboolean ALautowahState_deviceUpdate(ALautowahState *state, ALCdevice *d
|
||||
return AL_TRUE;
|
||||
}
|
||||
|
||||
static ALvoid ALautowahState_update(ALautowahState *state, ALCdevice *device, const ALeffectslot *slot)
|
||||
static ALvoid ALautowahState_update(ALautowahState *state, const ALCdevice *device, const ALeffectslot *slot)
|
||||
{
|
||||
ALfloat attackTime, releaseTime;
|
||||
|
||||
@ -75,7 +75,7 @@ static ALvoid ALautowahState_update(ALautowahState *state, ALCdevice *device, co
|
||||
state->PeakGain = slot->EffectProps.Autowah.PeakGain;
|
||||
state->Resonance = slot->EffectProps.Autowah.Resonance;
|
||||
|
||||
ComputeAmbientGains(device, slot->Gain, state->Gain);
|
||||
ComputeAmbientGains(device->AmbiCoeffs, device->NumChannels, slot->Gain, state->Gain);
|
||||
}
|
||||
|
||||
static ALvoid ALautowahState_process(ALautowahState *state, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[BUFFERSIZE], ALuint NumChannels)
|
||||
|
@ -91,11 +91,10 @@ static ALboolean ALchorusState_deviceUpdate(ALchorusState *state, ALCdevice *Dev
|
||||
return AL_TRUE;
|
||||
}
|
||||
|
||||
static ALvoid ALchorusState_update(ALchorusState *state, ALCdevice *Device, const ALeffectslot *Slot)
|
||||
static ALvoid ALchorusState_update(ALchorusState *state, const 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 coeffs[MAX_AMBI_COEFFS];
|
||||
ALfloat rate;
|
||||
ALint phase;
|
||||
|
||||
@ -113,8 +112,10 @@ static ALvoid ALchorusState_update(ALchorusState *state, ALCdevice *Device, cons
|
||||
state->delay = fastf2i(Slot->EffectProps.Chorus.Delay * frequency);
|
||||
|
||||
/* Gains for left and right sides */
|
||||
ComputeDirectionalGains(Device, left_dir, Slot->Gain, state->Gain[0]);
|
||||
ComputeDirectionalGains(Device, right_dir, Slot->Gain, state->Gain[1]);
|
||||
CalcXYZCoeffs(-1.0f, 0.0f, 0.0f, coeffs);
|
||||
ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, Slot->Gain, state->Gain[0]);
|
||||
CalcXYZCoeffs( 1.0f, 0.0f, 0.0f, coeffs);
|
||||
ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, Slot->Gain, state->Gain[1]);
|
||||
|
||||
phase = Slot->EffectProps.Chorus.Phase;
|
||||
rate = Slot->EffectProps.Chorus.Rate;
|
||||
|
@ -55,11 +55,11 @@ static ALboolean ALcompressorState_deviceUpdate(ALcompressorState *state, ALCdev
|
||||
return AL_TRUE;
|
||||
}
|
||||
|
||||
static ALvoid ALcompressorState_update(ALcompressorState *state, ALCdevice *device, const ALeffectslot *slot)
|
||||
static ALvoid ALcompressorState_update(ALcompressorState *state, const ALCdevice *device, const ALeffectslot *slot)
|
||||
{
|
||||
state->Enabled = slot->EffectProps.Compressor.OnOff;
|
||||
|
||||
ComputeAmbientGains(device, slot->Gain, state->Gain);
|
||||
ComputeAmbientGains(device->AmbiCoeffs, device->NumChannels, slot->Gain, state->Gain);
|
||||
}
|
||||
|
||||
static ALvoid ALcompressorState_process(ALcompressorState *state, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[BUFFERSIZE], ALuint NumChannels)
|
||||
|
@ -45,7 +45,7 @@ static ALboolean ALdedicatedState_deviceUpdate(ALdedicatedState *UNUSED(state),
|
||||
return AL_TRUE;
|
||||
}
|
||||
|
||||
static ALvoid ALdedicatedState_update(ALdedicatedState *state, ALCdevice *device, const ALeffectslot *Slot)
|
||||
static ALvoid ALdedicatedState_update(ALdedicatedState *state, const ALCdevice *device, const ALeffectslot *Slot)
|
||||
{
|
||||
ALfloat Gain;
|
||||
ALuint i;
|
||||
@ -69,8 +69,9 @@ static ALvoid ALdedicatedState_update(ALdedicatedState *state, ALCdevice *device
|
||||
state->gains[idx] = Gain;
|
||||
else
|
||||
{
|
||||
static const ALfloat front_dir[3] = { 0.0f, 0.0f, -1.0f };
|
||||
ComputeDirectionalGains(device, front_dir, Gain, state->gains);
|
||||
ALfloat coeffs[MAX_AMBI_COEFFS];
|
||||
CalcXYZCoeffs(0.0f, 0.0f, -1.0f, coeffs);
|
||||
ComputePanningGains(device->AmbiCoeffs, device->NumChannels, coeffs, Gain, state->gains);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ static ALboolean ALdistortionState_deviceUpdate(ALdistortionState *UNUSED(state)
|
||||
return AL_TRUE;
|
||||
}
|
||||
|
||||
static ALvoid ALdistortionState_update(ALdistortionState *state, ALCdevice *Device, const ALeffectslot *Slot)
|
||||
static ALvoid ALdistortionState_update(ALdistortionState *state, const ALCdevice *Device, const ALeffectslot *Slot)
|
||||
{
|
||||
ALfloat frequency = (ALfloat)Device->Frequency;
|
||||
ALfloat bandwidth;
|
||||
@ -83,7 +83,7 @@ static ALvoid ALdistortionState_update(ALdistortionState *state, ALCdevice *Devi
|
||||
cutoff / (frequency*4.0f), calc_rcpQ_from_bandwidth(cutoff / (frequency*4.0f), bandwidth)
|
||||
);
|
||||
|
||||
ComputeAmbientGains(Device, Slot->Gain, state->Gain);
|
||||
ComputeAmbientGains(Device->AmbiCoeffs, Device->NumChannels, Slot->Gain, state->Gain);
|
||||
}
|
||||
|
||||
static ALvoid ALdistortionState_process(ALdistortionState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels)
|
||||
|
@ -81,10 +81,10 @@ static ALboolean ALechoState_deviceUpdate(ALechoState *state, ALCdevice *Device)
|
||||
return AL_TRUE;
|
||||
}
|
||||
|
||||
static ALvoid ALechoState_update(ALechoState *state, ALCdevice *Device, const ALeffectslot *Slot)
|
||||
static ALvoid ALechoState_update(ALechoState *state, const ALCdevice *Device, const ALeffectslot *Slot)
|
||||
{
|
||||
ALfloat pandir[3] = { 0.0f, 0.0f, 0.0f };
|
||||
ALuint frequency = Device->Frequency;
|
||||
ALfloat coeffs[MAX_AMBI_COEFFS];
|
||||
ALfloat gain, lrpan;
|
||||
|
||||
state->Tap[0].delay = fastf2u(Slot->EffectProps.Echo.Delay * frequency) + 1;
|
||||
@ -103,12 +103,12 @@ static ALvoid ALechoState_update(ALechoState *state, ALCdevice *Device, const AL
|
||||
gain = Slot->Gain;
|
||||
|
||||
/* First tap panning */
|
||||
pandir[0] = -lrpan;
|
||||
ComputeDirectionalGains(Device, pandir, gain, state->Gain[0]);
|
||||
CalcXYZCoeffs(-lrpan, 0.0f, 0.0f, coeffs);
|
||||
ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, gain, state->Gain[0]);
|
||||
|
||||
/* Second tap panning */
|
||||
pandir[0] = +lrpan;
|
||||
ComputeDirectionalGains(Device, pandir, gain, state->Gain[1]);
|
||||
CalcXYZCoeffs( lrpan, 0.0f, 0.0f, coeffs);
|
||||
ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, gain, state->Gain[1]);
|
||||
}
|
||||
|
||||
static ALvoid ALechoState_process(ALechoState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels)
|
||||
|
@ -90,12 +90,12 @@ static ALboolean ALequalizerState_deviceUpdate(ALequalizerState *UNUSED(state),
|
||||
return AL_TRUE;
|
||||
}
|
||||
|
||||
static ALvoid ALequalizerState_update(ALequalizerState *state, ALCdevice *device, const ALeffectslot *slot)
|
||||
static ALvoid ALequalizerState_update(ALequalizerState *state, const ALCdevice *device, const ALeffectslot *slot)
|
||||
{
|
||||
ALfloat frequency = (ALfloat)device->Frequency;
|
||||
ALfloat gain, freq_mult;
|
||||
|
||||
ComputeAmbientGains(device, slot->Gain, state->Gain);
|
||||
ComputeAmbientGains(device->AmbiCoeffs, device->NumChannels, slot->Gain, state->Gain);
|
||||
|
||||
/* Calculate coefficients for the each type of filter. Note that the shelf
|
||||
* filters' gain is for the reference frequency, which is the centerpoint
|
||||
|
@ -91,11 +91,10 @@ static ALboolean ALflangerState_deviceUpdate(ALflangerState *state, ALCdevice *D
|
||||
return AL_TRUE;
|
||||
}
|
||||
|
||||
static ALvoid ALflangerState_update(ALflangerState *state, ALCdevice *Device, const ALeffectslot *Slot)
|
||||
static ALvoid ALflangerState_update(ALflangerState *state, const 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 coeffs[MAX_AMBI_COEFFS];
|
||||
ALfloat rate;
|
||||
ALint phase;
|
||||
|
||||
@ -113,8 +112,10 @@ static ALvoid ALflangerState_update(ALflangerState *state, ALCdevice *Device, co
|
||||
state->delay = fastf2i(Slot->EffectProps.Flanger.Delay * frequency);
|
||||
|
||||
/* Gains for left and right sides */
|
||||
ComputeDirectionalGains(Device, left_dir, Slot->Gain, state->Gain[0]);
|
||||
ComputeDirectionalGains(Device, right_dir, Slot->Gain, state->Gain[1]);
|
||||
CalcXYZCoeffs(-1.0f, 0.0f, 0.0f, coeffs);
|
||||
ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, Slot->Gain, state->Gain[0]);
|
||||
CalcXYZCoeffs( 1.0f, 0.0f, 0.0f, coeffs);
|
||||
ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, Slot->Gain, state->Gain[1]);
|
||||
|
||||
phase = Slot->EffectProps.Flanger.Phase;
|
||||
rate = Slot->EffectProps.Flanger.Rate;
|
||||
|
@ -123,7 +123,7 @@ static ALboolean ALmodulatorState_deviceUpdate(ALmodulatorState *UNUSED(state),
|
||||
return AL_TRUE;
|
||||
}
|
||||
|
||||
static ALvoid ALmodulatorState_update(ALmodulatorState *state, ALCdevice *Device, const ALeffectslot *Slot)
|
||||
static ALvoid ALmodulatorState_update(ALmodulatorState *state, const ALCdevice *Device, const ALeffectslot *Slot)
|
||||
{
|
||||
ALfloat cw, a;
|
||||
|
||||
@ -148,7 +148,7 @@ static ALvoid ALmodulatorState_update(ALmodulatorState *state, ALCdevice *Device
|
||||
state->Filter.b2 = 0.0f;
|
||||
state->Filter.input_gain = a;
|
||||
|
||||
ComputeAmbientGains(Device, Slot->Gain, state->Gain);
|
||||
ComputeAmbientGains(Device->AmbiCoeffs, Device->NumChannels, Slot->Gain, state->Gain);
|
||||
}
|
||||
|
||||
static ALvoid ALmodulatorState_process(ALmodulatorState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels)
|
||||
|
@ -33,7 +33,7 @@ static ALboolean ALnullState_deviceUpdate(ALnullState* UNUSED(state), ALCdevice*
|
||||
/* This updates the effect state. This is called any time the effect is
|
||||
* (re)loaded into a slot.
|
||||
*/
|
||||
static ALvoid ALnullState_update(ALnullState* UNUSED(state), ALCdevice* UNUSED(device), const ALeffectslot* UNUSED(slot))
|
||||
static ALvoid ALnullState_update(ALnullState* UNUSED(state), const ALCdevice* UNUSED(device), const ALeffectslot* UNUSED(slot))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1065,6 +1065,7 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection
|
||||
}, LatePanAngles[4] = {
|
||||
DEG2RAD(45.0f), DEG2RAD(-45.0f), DEG2RAD(135.0f), DEG2RAD(-135.0f)
|
||||
};
|
||||
ALfloat coeffs[MAX_AMBI_COEFFS];
|
||||
ALfloat length, ev, az;
|
||||
ALuint i;
|
||||
|
||||
@ -1072,7 +1073,10 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection
|
||||
if(!(length > FLT_EPSILON))
|
||||
{
|
||||
for(i = 0;i < 4;i++)
|
||||
ComputeAngleGains(Device, EarlyPanAngles[i], 0.0f, Gain, State->Early.PanGain[i]);
|
||||
{
|
||||
CalcAngleCoeffs(EarlyPanAngles[i], 0.0f, coeffs);
|
||||
ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, Gain, State->Early.PanGain[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1090,7 +1094,8 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection
|
||||
float offset, naz, nev;
|
||||
naz = EarlyPanAngles[i] + (modff((az-EarlyPanAngles[i])*length/F_TAU + 1.5f, &offset)-0.5f)*F_TAU;
|
||||
nev = (modff((ev )*length/F_TAU + 1.5f, &offset)-0.5f)*F_TAU;
|
||||
ComputeAngleGains(Device, naz, nev, Gain, State->Early.PanGain[i]);
|
||||
CalcAngleCoeffs(naz, nev, coeffs);
|
||||
ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, Gain, State->Early.PanGain[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1098,7 +1103,10 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection
|
||||
if(!(length > FLT_EPSILON))
|
||||
{
|
||||
for(i = 0;i < 4;i++)
|
||||
ComputeAngleGains(Device, LatePanAngles[i], 0.0f, Gain, State->Late.PanGain[i]);
|
||||
{
|
||||
CalcAngleCoeffs(LatePanAngles[i], 0.0f, coeffs);
|
||||
ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, Gain, State->Late.PanGain[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1111,12 +1119,13 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection
|
||||
float offset, naz, nev;
|
||||
naz = LatePanAngles[i] + (modff((az-LatePanAngles[i])*length/F_TAU + 1.5f, &offset)-0.5f)*F_TAU;
|
||||
nev = (modff((ev )*length/F_TAU + 1.5f, &offset)-0.5f)*F_TAU;
|
||||
ComputeAngleGains(Device, naz, nev, Gain, State->Late.PanGain[i]);
|
||||
CalcAngleCoeffs(naz, nev, coeffs);
|
||||
ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, Gain, State->Late.PanGain[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ALvoid ALreverbState_update(ALreverbState *State, ALCdevice *Device, const ALeffectslot *Slot)
|
||||
static ALvoid ALreverbState_update(ALreverbState *State, const ALCdevice *Device, const ALeffectslot *Slot)
|
||||
{
|
||||
const ALeffectProps *props = &Slot->EffectProps;
|
||||
ALuint frequency = Device->Frequency;
|
||||
|
@ -33,6 +33,9 @@
|
||||
#include "bool.h"
|
||||
|
||||
|
||||
extern inline void CalcXYZCoeffs(ALfloat x, ALfloat y, ALfloat z, ALfloat coeffs[MAX_AMBI_COEFFS]);
|
||||
|
||||
|
||||
#define ZERO_ORDER_SCALE 0.0f
|
||||
#define FIRST_ORDER_SCALE 1.0f
|
||||
#define SECOND_ORDER_SCALE (1.0f / 1.22474f)
|
||||
@ -82,35 +85,8 @@ static const ALfloat FuMa2N3DScale[MAX_AMBI_COEFFS] = {
|
||||
};
|
||||
|
||||
|
||||
void ComputeAmbientGains(const ALCdevice *device, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS])
|
||||
void CalcDirectionCoeffs(const ALfloat dir[3], ALfloat coeffs[MAX_AMBI_COEFFS])
|
||||
{
|
||||
ALuint i;
|
||||
|
||||
for(i = 0;i < device->NumChannels;i++)
|
||||
{
|
||||
// The W coefficients are based on a mathematical average of the
|
||||
// output. The square root of the base average provides for a more
|
||||
// perceptual average volume, better suited to non-directional gains.
|
||||
gains[i] = sqrtf(device->AmbiCoeffs[i][0]) * ingain;
|
||||
}
|
||||
for(;i < MAX_OUTPUT_CHANNELS;i++)
|
||||
gains[i] = 0.0f;
|
||||
}
|
||||
|
||||
void ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat elevation, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS])
|
||||
{
|
||||
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[MAX_OUTPUT_CHANNELS])
|
||||
{
|
||||
ALfloat coeffs[MAX_AMBI_COEFFS];
|
||||
ALuint i, j;
|
||||
/* Convert from OpenAL coords to Ambisonics. */
|
||||
ALfloat x = -dir[2];
|
||||
ALfloat y = -dir[0];
|
||||
@ -136,27 +112,58 @@ void ComputeDirectionalGains(const ALCdevice *device, const ALfloat dir[3], ALfl
|
||||
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) */
|
||||
}
|
||||
|
||||
for(i = 0;i < device->NumChannels;i++)
|
||||
void CalcAngleCoeffs(ALfloat angle, ALfloat elevation, ALfloat coeffs[MAX_AMBI_COEFFS])
|
||||
{
|
||||
ALfloat dir[3] = {
|
||||
sinf(angle) * cosf(elevation),
|
||||
sinf(elevation),
|
||||
-cosf(angle) * cosf(elevation)
|
||||
};
|
||||
CalcDirectionCoeffs(dir, coeffs);
|
||||
}
|
||||
|
||||
|
||||
void ComputeAmbientGains(const ChannelConfig *chancoeffs, ALuint numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS])
|
||||
{
|
||||
ALuint i;
|
||||
|
||||
for(i = 0;i < numchans;i++)
|
||||
{
|
||||
// The W coefficients are based on a mathematical average of the
|
||||
// output. The square root of the base average provides for a more
|
||||
// perceptual average volume, better suited to non-directional gains.
|
||||
gains[i] = sqrtf(chancoeffs[i][0]) * ingain;
|
||||
}
|
||||
for(;i < MAX_OUTPUT_CHANNELS;i++)
|
||||
gains[i] = 0.0f;
|
||||
}
|
||||
|
||||
void ComputePanningGains(const ChannelConfig *chancoeffs, ALuint numchans, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS])
|
||||
{
|
||||
ALuint i, j;
|
||||
|
||||
for(i = 0;i < numchans;i++)
|
||||
{
|
||||
float gain = 0.0f;
|
||||
for(j = 0;j < MAX_AMBI_COEFFS;j++)
|
||||
gain += device->AmbiCoeffs[i][j]*coeffs[j];
|
||||
gain += chancoeffs[i][j]*coeffs[j];
|
||||
gains[i] = gain * ingain;
|
||||
}
|
||||
for(;i < MAX_OUTPUT_CHANNELS;i++)
|
||||
gains[i] = 0.0f;
|
||||
}
|
||||
|
||||
void ComputeBFormatGains(const ALCdevice *device, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS])
|
||||
void ComputeBFormatGains(const ChannelConfig *chancoeffs, ALuint numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS])
|
||||
{
|
||||
ALuint i, j;
|
||||
|
||||
for(i = 0;i < device->NumChannels;i++)
|
||||
for(i = 0;i < numchans;i++)
|
||||
{
|
||||
float gain = 0.0f;
|
||||
for(j = 0;j < 4;j++)
|
||||
gain += device->AmbiCoeffs[i][j] * mtx[j];
|
||||
gain += chancoeffs[i][j] * mtx[j];
|
||||
gains[i] = gain * ingain;
|
||||
}
|
||||
for(;i < MAX_OUTPUT_CHANNELS;i++)
|
||||
|
@ -21,7 +21,7 @@ struct ALeffectStateVtable {
|
||||
void (*const Destruct)(ALeffectState *state);
|
||||
|
||||
ALboolean (*const deviceUpdate)(ALeffectState *state, ALCdevice *device);
|
||||
void (*const update)(ALeffectState *state, ALCdevice *device, const struct ALeffectslot *slot);
|
||||
void (*const update)(ALeffectState *state, const ALCdevice *device, const struct ALeffectslot *slot);
|
||||
void (*const process)(ALeffectState *state, ALuint samplesToDo, const ALfloat *restrict samplesIn, ALfloat (*restrict samplesOut)[BUFFERSIZE], ALuint numChannels);
|
||||
|
||||
void (*const Delete)(void *ptr);
|
||||
@ -30,7 +30,7 @@ struct ALeffectStateVtable {
|
||||
#define DEFINE_ALEFFECTSTATE_VTABLE(T) \
|
||||
DECLARE_THUNK(T, ALeffectState, void, Destruct) \
|
||||
DECLARE_THUNK1(T, ALeffectState, ALboolean, deviceUpdate, ALCdevice*) \
|
||||
DECLARE_THUNK2(T, ALeffectState, void, update, ALCdevice*, const ALeffectslot*) \
|
||||
DECLARE_THUNK2(T, ALeffectState, void, update, const ALCdevice*, const ALeffectslot*) \
|
||||
DECLARE_THUNK4(T, ALeffectState, void, process, ALuint, const ALfloat*restrict, ALfloatBUFFERSIZE*restrict, ALuint) \
|
||||
static void T##_ALeffectState_Delete(void *ptr) \
|
||||
{ return T##_Delete(STATIC_UPCAST(T, ALeffectState, (ALeffectState*)ptr)); } \
|
||||
|
@ -277,36 +277,56 @@ void aluInitMixer(void);
|
||||
ALvoid aluInitPanning(ALCdevice *Device);
|
||||
|
||||
/**
|
||||
* ComputeDirectionalGains
|
||||
* CalcDirectionCoeffs
|
||||
*
|
||||
* Sets channel gains based on a direction. The direction must be a 3-component
|
||||
* vector no longer than 1 unit.
|
||||
* Calculates ambisonic coefficients based on a direction vector. The vector
|
||||
* must not be longer than 1 unit.
|
||||
*/
|
||||
void ComputeDirectionalGains(const ALCdevice *device, const ALfloat dir[3], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
|
||||
void CalcDirectionCoeffs(const ALfloat dir[3], ALfloat coeffs[MAX_AMBI_COEFFS]);
|
||||
|
||||
/**
|
||||
* ComputeAngleGains
|
||||
* CalcXYZCoeffs
|
||||
*
|
||||
* Sets channel gains based on angle and elevation. The angle and elevation
|
||||
* parameters are in radians, going right and up respectively.
|
||||
* Same as CalcDirectionCoeffs except the direction is specified as separate x,
|
||||
* y, and z parameters instead of an array.
|
||||
*/
|
||||
void ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat elevation, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
|
||||
inline void CalcXYZCoeffs(ALfloat x, ALfloat y, ALfloat z, ALfloat coeffs[MAX_AMBI_COEFFS])
|
||||
{
|
||||
ALfloat dir[3] = { x, y, z };
|
||||
CalcDirectionCoeffs(dir, coeffs);
|
||||
}
|
||||
|
||||
/**
|
||||
* CalcAngleCoeffs
|
||||
*
|
||||
* Calculates ambisonic coefficients based on angle and elevation. The angle
|
||||
* and elevation parameters are in radians, going right and up respectively.
|
||||
*/
|
||||
void CalcAngleCoeffs(ALfloat angle, ALfloat elevation, ALfloat coeffs[MAX_AMBI_COEFFS]);
|
||||
|
||||
/**
|
||||
* ComputeAmbientGains
|
||||
*
|
||||
* Sets channel gains for ambient, omni-directional sounds.
|
||||
* Computes channel gains for ambient, omni-directional sounds.
|
||||
*/
|
||||
void ComputeAmbientGains(const ALCdevice *device, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
|
||||
void ComputeAmbientGains(const ChannelConfig *chancoeffs, ALuint numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
|
||||
|
||||
/**
|
||||
* ComputePanningGains
|
||||
*
|
||||
* Computes panning gains using the given channel decoder coefficients and the
|
||||
* pre-calculated direction or angle coefficients.
|
||||
*/
|
||||
void ComputePanningGains(const ChannelConfig *chancoeffs, ALuint numchans, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
|
||||
|
||||
/**
|
||||
* ComputeBFormatGains
|
||||
*
|
||||
* Sets channel gains for a given (first-order) B-Format channel. The matrix is
|
||||
* a 1x4 'slice' of the rotation matrix for a given channel used to orient the
|
||||
* coefficients.
|
||||
* Sets channel gains for a given (first-order) B-Format input channel. The
|
||||
* matrix is a 1x4 'slice' of the rotation matrix for the given channel used to
|
||||
* orient the soundfield.
|
||||
*/
|
||||
void ComputeBFormatGains(const ALCdevice *device, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
|
||||
void ComputeBFormatGains(const ChannelConfig *chancoeffs, ALuint numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
|
||||
|
||||
|
||||
ALvoid UpdateContextSources(ALCcontext *context);
|
||||
|
Loading…
Reference in New Issue
Block a user