More directly map coefficients for ambisonic mixing buffers
Instead of looping over all the coefficients for each channel with multiplies, when we know only one will have a non-0 factor for ambisonic mixing buffers, just index the one with a non-0 factor.
This commit is contained in:
parent
e16032e1f0
commit
a6c70992b0
13
Alc/ALu.c
13
Alc/ALu.c
@ -519,8 +519,8 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A
|
||||
voice->Direct.OutBuffer = Device->FOAOut.Buffer;
|
||||
voice->Direct.OutChannels = Device->FOAOut.NumChannels;
|
||||
for(c = 0;c < num_channels;c++)
|
||||
ComputeFirstOrderGains(Device->FOAOut.AmbiCoeffs, Device->FOAOut.NumChannels, matrix.m[c],
|
||||
DryGain, voice->Direct.Gains[c].Target);
|
||||
ComputeFirstOrderGains(Device->FOAOut, matrix.m[c], DryGain,
|
||||
voice->Direct.Gains[c].Target);
|
||||
|
||||
for(i = 0;i < NumSends;i++)
|
||||
{
|
||||
@ -682,9 +682,8 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A
|
||||
else
|
||||
{
|
||||
CalcAngleCoeffs(chans[c].angle, chans[c].elevation, coeffs);
|
||||
ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels,
|
||||
Device->Dry.CoeffCount, coeffs, DryGain, voice->Direct.Gains[c].Target
|
||||
);
|
||||
ComputePanningGains(Device->Dry, coeffs, DryGain,
|
||||
voice->Direct.Gains[c].Target);
|
||||
}
|
||||
|
||||
for(i = 0;i < NumSends;i++)
|
||||
@ -1184,9 +1183,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte
|
||||
else
|
||||
{
|
||||
CalcDirectionCoeffs(dir, coeffs);
|
||||
ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels,
|
||||
Device->Dry.CoeffCount, coeffs, DryGain, voice->Direct.Gains[0].Target
|
||||
);
|
||||
ComputePanningGains(Device->Dry, coeffs, DryGain, voice->Direct.Gains[0].Target);
|
||||
}
|
||||
|
||||
for(i = 0;i < NumSends;i++)
|
||||
|
@ -75,7 +75,7 @@ static ALvoid ALautowahState_update(ALautowahState *state, const ALCdevice *devi
|
||||
state->PeakGain = slot->EffectProps.Autowah.PeakGain;
|
||||
state->Resonance = slot->EffectProps.Autowah.Resonance;
|
||||
|
||||
ComputeAmbientGains(device->Dry.AmbiCoeffs, device->Dry.NumChannels, slot->Gain, state->Gain);
|
||||
ComputeAmbientGains(device->Dry, slot->Gain, state->Gain);
|
||||
}
|
||||
|
||||
static ALvoid ALautowahState_process(ALautowahState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels)
|
||||
|
@ -113,13 +113,9 @@ static ALvoid ALchorusState_update(ALchorusState *state, const ALCdevice *Device
|
||||
|
||||
/* Gains for left and right sides */
|
||||
CalcXYZCoeffs(-1.0f, 0.0f, 0.0f, coeffs);
|
||||
ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels,
|
||||
Device->Dry.CoeffCount, coeffs, Slot->Gain, state->Gain[0]
|
||||
);
|
||||
ComputePanningGains(Device->Dry, coeffs, Slot->Gain, state->Gain[0]);
|
||||
CalcXYZCoeffs( 1.0f, 0.0f, 0.0f, coeffs);
|
||||
ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels,
|
||||
Device->Dry.CoeffCount, coeffs, Slot->Gain, state->Gain[1]
|
||||
);
|
||||
ComputePanningGains(Device->Dry, coeffs, Slot->Gain, state->Gain[1]);
|
||||
|
||||
phase = Slot->EffectProps.Chorus.Phase;
|
||||
rate = Slot->EffectProps.Chorus.Rate;
|
||||
|
@ -72,8 +72,8 @@ static ALvoid ALcompressorState_update(ALcompressorState *state, const ALCdevice
|
||||
STATIC_CAST(ALeffectState,state)->OutBuffer = device->FOAOut.Buffer;
|
||||
STATIC_CAST(ALeffectState,state)->OutChannels = device->FOAOut.NumChannels;
|
||||
for(i = 0;i < 4;i++)
|
||||
ComputeFirstOrderGains(device->FOAOut.AmbiCoeffs, device->FOAOut.NumChannels,
|
||||
matrix.m[i], slot->Gain, state->Gain[i]);
|
||||
ComputeFirstOrderGains(device->FOAOut, matrix.m[i], slot->Gain,
|
||||
state->Gain[i]);
|
||||
}
|
||||
|
||||
static ALvoid ALcompressorState_process(ALcompressorState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels)
|
||||
|
@ -59,9 +59,9 @@ static ALvoid ALdedicatedState_update(ALdedicatedState *state, const ALCdevice *
|
||||
int idx;
|
||||
if((idx=GetChannelIdxByName(device->RealOut, LFE)) != -1)
|
||||
{
|
||||
state->gains[idx] = Gain;
|
||||
STATIC_CAST(ALeffectState,state)->OutBuffer = device->RealOut.Buffer;
|
||||
STATIC_CAST(ALeffectState,state)->OutChannels = device->RealOut.NumChannels;
|
||||
state->gains[idx] = Gain;
|
||||
}
|
||||
}
|
||||
else if(Slot->EffectType == AL_EFFECT_DEDICATED_DIALOGUE)
|
||||
@ -71,23 +71,22 @@ static ALvoid ALdedicatedState_update(ALdedicatedState *state, const ALCdevice *
|
||||
* plays from the front-center location. */
|
||||
if((idx=GetChannelIdxByName(device->RealOut, FrontCenter)) != -1)
|
||||
{
|
||||
state->gains[idx] = Gain;
|
||||
STATIC_CAST(ALeffectState,state)->OutBuffer = device->RealOut.Buffer;
|
||||
STATIC_CAST(ALeffectState,state)->OutChannels = device->RealOut.NumChannels;
|
||||
state->gains[idx] = Gain;
|
||||
}
|
||||
else
|
||||
{
|
||||
STATIC_CAST(ALeffectState,state)->OutBuffer = device->Dry.Buffer;
|
||||
STATIC_CAST(ALeffectState,state)->OutChannels = device->Dry.NumChannels;
|
||||
if((idx=GetChannelIdxByName(device->Dry, FrontCenter)) != -1)
|
||||
state->gains[idx] = Gain;
|
||||
else
|
||||
{
|
||||
ALfloat coeffs[MAX_AMBI_COEFFS];
|
||||
CalcXYZCoeffs(0.0f, 0.0f, -1.0f, coeffs);
|
||||
ComputePanningGains(device->Dry.AmbiCoeffs, device->Dry.NumChannels,
|
||||
device->Dry.CoeffCount, coeffs, Gain, state->gains);
|
||||
ComputePanningGains(device->Dry, coeffs, Gain, state->gains);
|
||||
}
|
||||
STATIC_CAST(ALeffectState,state)->OutBuffer = device->Dry.Buffer;
|
||||
STATIC_CAST(ALeffectState,state)->OutChannels = device->Dry.NumChannels;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ static ALvoid ALdistortionState_update(ALdistortionState *state, const ALCdevice
|
||||
cutoff / (frequency*4.0f), calc_rcpQ_from_bandwidth(cutoff / (frequency*4.0f), bandwidth)
|
||||
);
|
||||
|
||||
ComputeAmbientGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels, Slot->Gain, state->Gain);
|
||||
ComputeAmbientGains(Device->Dry, Slot->Gain, state->Gain);
|
||||
}
|
||||
|
||||
static ALvoid ALdistortionState_process(ALdistortionState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels)
|
||||
|
@ -104,13 +104,11 @@ static ALvoid ALechoState_update(ALechoState *state, const ALCdevice *Device, co
|
||||
|
||||
/* First tap panning */
|
||||
CalcXYZCoeffs(-lrpan, 0.0f, 0.0f, coeffs);
|
||||
ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels,
|
||||
Device->Dry.CoeffCount, coeffs, gain, state->Gain[0]);
|
||||
ComputePanningGains(Device->Dry, coeffs, gain, state->Gain[0]);
|
||||
|
||||
/* Second tap panning */
|
||||
CalcXYZCoeffs( lrpan, 0.0f, 0.0f, coeffs);
|
||||
ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels,
|
||||
Device->Dry.CoeffCount, coeffs, gain, state->Gain[1]);
|
||||
ComputePanningGains(Device->Dry, coeffs, gain, state->Gain[1]);
|
||||
}
|
||||
|
||||
static ALvoid ALechoState_process(ALechoState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels)
|
||||
|
@ -113,8 +113,8 @@ static ALvoid ALequalizerState_update(ALequalizerState *state, const ALCdevice *
|
||||
STATIC_CAST(ALeffectState,state)->OutBuffer = device->FOAOut.Buffer;
|
||||
STATIC_CAST(ALeffectState,state)->OutChannels = device->FOAOut.NumChannels;
|
||||
for(i = 0;i < MAX_EFFECT_CHANNELS;i++)
|
||||
ComputeFirstOrderGains(device->FOAOut.AmbiCoeffs, device->FOAOut.NumChannels,
|
||||
matrix.m[i], slot->Gain, state->Gain[i]);
|
||||
ComputeFirstOrderGains(device->FOAOut, matrix.m[i], slot->Gain,
|
||||
state->Gain[i]);
|
||||
|
||||
/* Calculate coefficients for the each type of filter. Note that the shelf
|
||||
* filters' gain is for the reference frequency, which is the centerpoint
|
||||
|
@ -113,13 +113,9 @@ static ALvoid ALflangerState_update(ALflangerState *state, const ALCdevice *Devi
|
||||
|
||||
/* Gains for left and right sides */
|
||||
CalcXYZCoeffs(-1.0f, 0.0f, 0.0f, coeffs);
|
||||
ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels,
|
||||
Device->Dry.CoeffCount, coeffs, Slot->Gain, state->Gain[0]
|
||||
);
|
||||
ComputePanningGains(Device->Dry, coeffs, Slot->Gain, state->Gain[0]);
|
||||
CalcXYZCoeffs( 1.0f, 0.0f, 0.0f, coeffs);
|
||||
ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels,
|
||||
Device->Dry.CoeffCount, coeffs, Slot->Gain, state->Gain[1]
|
||||
);
|
||||
ComputePanningGains(Device->Dry, coeffs, Slot->Gain, state->Gain[1]);
|
||||
|
||||
phase = Slot->EffectProps.Flanger.Phase;
|
||||
rate = Slot->EffectProps.Flanger.Rate;
|
||||
|
@ -132,8 +132,8 @@ static ALvoid ALmodulatorState_update(ALmodulatorState *state, const ALCdevice *
|
||||
STATIC_CAST(ALeffectState,state)->OutBuffer = Device->FOAOut.Buffer;
|
||||
STATIC_CAST(ALeffectState,state)->OutChannels = Device->FOAOut.NumChannels;
|
||||
for(i = 0;i < MAX_EFFECT_CHANNELS;i++)
|
||||
ComputeFirstOrderGains(Device->FOAOut.AmbiCoeffs, Device->FOAOut.NumChannels,
|
||||
matrix.m[i], Slot->Gain, state->Gain[i]);
|
||||
ComputeFirstOrderGains(Device->FOAOut, matrix.m[i], Slot->Gain,
|
||||
state->Gain[i]);
|
||||
}
|
||||
|
||||
static ALvoid ALmodulatorState_process(ALmodulatorState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels)
|
||||
|
@ -720,8 +720,7 @@ static ALvoid UpdateMixedPanning(const ALCdevice *Device, const ALfloat *Reflect
|
||||
length = minf(length, 1.0f);
|
||||
|
||||
CalcDirectionCoeffs(pan, coeffs);
|
||||
ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels,
|
||||
Device->Dry.CoeffCount, coeffs, Gain, DirGains);
|
||||
ComputePanningGains(Device->Dry, coeffs, Gain, DirGains);
|
||||
for(i = 0;i < Device->Dry.NumChannels;i++)
|
||||
State->Early.PanGain[3][i] = DirGains[i] * EarlyGain * length;
|
||||
for(i = 0;i < Device->RealOut.NumChannels;i++)
|
||||
@ -745,8 +744,7 @@ static ALvoid UpdateMixedPanning(const ALCdevice *Device, const ALfloat *Reflect
|
||||
length = minf(length, 1.0f);
|
||||
|
||||
CalcDirectionCoeffs(pan, coeffs);
|
||||
ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels,
|
||||
Device->Dry.CoeffCount, coeffs, Gain, DirGains);
|
||||
ComputePanningGains(Device->Dry, coeffs, Gain, DirGains);
|
||||
for(i = 0;i < Device->Dry.NumChannels;i++)
|
||||
State->Late.PanGain[3][i] = DirGains[i] * LateGain * length;
|
||||
for(i = 0;i < Device->RealOut.NumChannels;i++)
|
||||
@ -763,8 +761,7 @@ static ALvoid UpdateDirectPanning(const ALCdevice *Device, const ALfloat *Reflec
|
||||
ALuint i;
|
||||
|
||||
/* Apply a boost of about 3dB to better match the expected stereo output volume. */
|
||||
ComputeAmbientGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels,
|
||||
Gain*1.414213562f, AmbientGains);
|
||||
ComputeAmbientGains(Device->Dry, Gain*1.414213562f, AmbientGains);
|
||||
|
||||
memset(State->Early.PanGain, 0, sizeof(State->Early.PanGain));
|
||||
length = sqrtf(ReflectionsPan[0]*ReflectionsPan[0] + ReflectionsPan[1]*ReflectionsPan[1] + ReflectionsPan[2]*ReflectionsPan[2]);
|
||||
@ -787,8 +784,7 @@ static ALvoid UpdateDirectPanning(const ALCdevice *Device, const ALfloat *Reflec
|
||||
length = minf(length, 1.0f);
|
||||
|
||||
CalcDirectionCoeffs(pan, coeffs);
|
||||
ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels,
|
||||
Device->Dry.CoeffCount, coeffs, Gain, DirGains);
|
||||
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;
|
||||
}
|
||||
@ -810,8 +806,7 @@ static ALvoid UpdateDirectPanning(const ALCdevice *Device, const ALfloat *Reflec
|
||||
length = minf(length, 1.0f);
|
||||
|
||||
CalcDirectionCoeffs(pan, coeffs);
|
||||
ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels,
|
||||
Device->Dry.CoeffCount, coeffs, Gain, DirGains);
|
||||
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;
|
||||
}
|
||||
@ -861,8 +856,7 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection
|
||||
for(i = 0;i < 4;i++)
|
||||
{
|
||||
CalcDirectionCoeffs(PanDirs[i], coeffs);
|
||||
ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels,
|
||||
Device->Dry.CoeffCount, coeffs, Gain*EarlyGain*gain[i],
|
||||
ComputePanningGains(Device->Dry, coeffs, Gain*EarlyGain*gain[i],
|
||||
State->Early.PanGain[i]);
|
||||
}
|
||||
|
||||
@ -893,8 +887,7 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection
|
||||
for(i = 0;i < 4;i++)
|
||||
{
|
||||
CalcDirectionCoeffs(PanDirs[i], coeffs);
|
||||
ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels,
|
||||
Device->Dry.CoeffCount, coeffs, Gain*LateGain*gain[i],
|
||||
ComputePanningGains(Device->Dry, coeffs, Gain*LateGain*gain[i],
|
||||
State->Late.PanGain[i]);
|
||||
}
|
||||
}
|
||||
|
168
Alc/panning.c
168
Alc/panning.c
@ -149,7 +149,7 @@ void CalcAngleCoeffs(ALfloat azimuth, ALfloat elevation, ALfloat coeffs[MAX_AMBI
|
||||
}
|
||||
|
||||
|
||||
void ComputeAmbientGains(const ChannelConfig *chancoeffs, ALuint numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS])
|
||||
void ComputeAmbientGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS])
|
||||
{
|
||||
ALuint i;
|
||||
|
||||
@ -164,7 +164,22 @@ void ComputeAmbientGains(const ChannelConfig *chancoeffs, ALuint numchans, ALflo
|
||||
gains[i] = 0.0f;
|
||||
}
|
||||
|
||||
void ComputePanningGains(const ChannelConfig *chancoeffs, ALuint numchans, ALuint numcoeffs, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS])
|
||||
void ComputeAmbientGainsBF(const BFChannelConfig *chanmap, ALuint numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS])
|
||||
{
|
||||
ALfloat gain = 0.0f;
|
||||
ALuint i;
|
||||
|
||||
for(i = 0;i < numchans;i++)
|
||||
{
|
||||
if(chanmap[i].Index == 0)
|
||||
gain += chanmap[i].Scale;
|
||||
}
|
||||
gains[0] = gain * 1.414213562f * ingain;
|
||||
for(i = 1;i < MAX_OUTPUT_CHANNELS;i++)
|
||||
gains[i] = 0.0f;
|
||||
}
|
||||
|
||||
void ComputePanningGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, ALuint numcoeffs, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS])
|
||||
{
|
||||
ALuint i, j;
|
||||
|
||||
@ -189,7 +204,7 @@ void ComputePanningGainsBF(const BFChannelConfig *chanmap, ALuint numchans, cons
|
||||
gains[i] = 0.0f;
|
||||
}
|
||||
|
||||
void ComputeFirstOrderGains(const ChannelConfig *chancoeffs, ALuint numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS])
|
||||
void ComputeFirstOrderGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS])
|
||||
{
|
||||
ALuint i, j;
|
||||
|
||||
@ -524,16 +539,34 @@ static void InitPanning(ALCdevice *device)
|
||||
|
||||
for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
|
||||
device->Dry.ChannelName[i] = device->RealOut.ChannelName[i];
|
||||
SetChannelMap(device->Dry.ChannelName, device->Dry.AmbiCoeffs, chanmap, count,
|
||||
&device->Dry.NumChannels, AL_TRUE);
|
||||
device->Dry.CoeffCount = coeffcount;
|
||||
|
||||
memset(device->FOAOut.AmbiCoeffs, 0, sizeof(device->FOAOut.AmbiCoeffs));
|
||||
for(i = 0;i < device->Dry.NumChannels;i++)
|
||||
if(device->FmtChans == DevFmtBFormat3D)
|
||||
{
|
||||
device->FOAOut.AmbiCoeffs[i][0] = device->Dry.AmbiCoeffs[i][0];
|
||||
for(j = 1;j < 4;j++)
|
||||
device->FOAOut.AmbiCoeffs[i][j] = device->Dry.AmbiCoeffs[i][j] * ambiscale;
|
||||
for(i = 0;i < count;i++)
|
||||
{
|
||||
ALuint acn = FuMa2ACN[i];
|
||||
device->Dry.Ambi.Map[i].Scale = 1.0f/FuMa2N3DScale[acn];
|
||||
device->Dry.Ambi.Map[i].Index = acn;
|
||||
}
|
||||
device->Dry.CoeffCount = 0;
|
||||
device->Dry.NumChannels = count;
|
||||
|
||||
memcpy(&device->FOAOut.Ambi, &device->Dry.Ambi, sizeof(device->FOAOut.Ambi));
|
||||
device->FOAOut.CoeffCount = device->Dry.CoeffCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetChannelMap(device->Dry.ChannelName, device->Dry.Ambi.Coeffs, chanmap, count,
|
||||
&device->Dry.NumChannels, AL_TRUE);
|
||||
device->Dry.CoeffCount = coeffcount;
|
||||
|
||||
memset(&device->FOAOut.Ambi, 0, sizeof(device->FOAOut.Ambi));
|
||||
for(i = 0;i < device->Dry.NumChannels;i++)
|
||||
{
|
||||
device->FOAOut.Ambi.Coeffs[i][0] = device->Dry.Ambi.Coeffs[i][0];
|
||||
for(j = 1;j < 4;j++)
|
||||
device->FOAOut.Ambi.Coeffs[i][j] = device->Dry.Ambi.Coeffs[i][j] * ambiscale;
|
||||
}
|
||||
device->FOAOut.CoeffCount = 4;
|
||||
}
|
||||
}
|
||||
|
||||
@ -585,78 +618,60 @@ static void InitCustomPanning(ALCdevice *device, const AmbDecConf *conf, const A
|
||||
|
||||
for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
|
||||
device->Dry.ChannelName[i] = device->RealOut.ChannelName[i];
|
||||
SetChannelMap(device->Dry.ChannelName, device->Dry.AmbiCoeffs, chanmap,
|
||||
SetChannelMap(device->Dry.ChannelName, device->Dry.Ambi.Coeffs, chanmap,
|
||||
conf->NumSpeakers, &device->Dry.NumChannels, AL_FALSE);
|
||||
device->Dry.CoeffCount = (conf->ChanMask > 0x1ff) ? 16 :
|
||||
(conf->ChanMask > 0xf) ? 9 : 4;
|
||||
|
||||
memset(device->FOAOut.AmbiCoeffs, 0, sizeof(device->FOAOut.AmbiCoeffs));
|
||||
memset(&device->FOAOut.Ambi, 0, sizeof(device->FOAOut.Ambi));
|
||||
for(i = 0;i < device->Dry.NumChannels;i++)
|
||||
{
|
||||
device->FOAOut.AmbiCoeffs[i][0] = device->Dry.AmbiCoeffs[i][0];
|
||||
device->FOAOut.Ambi.Coeffs[i][0] = device->Dry.Ambi.Coeffs[i][0];
|
||||
for(j = 1;j < 4;j++)
|
||||
device->FOAOut.AmbiCoeffs[i][j] = device->Dry.AmbiCoeffs[i][j] * ambiscale;
|
||||
device->FOAOut.Ambi.Coeffs[i][j] = device->Dry.Ambi.Coeffs[i][j] * ambiscale;
|
||||
}
|
||||
device->FOAOut.CoeffCount = 4;
|
||||
}
|
||||
|
||||
static void InitHQPanning(ALCdevice *device, const AmbDecConf *conf, const ALuint speakermap[MAX_OUTPUT_CHANNELS])
|
||||
{
|
||||
/* NOTE: This is ACN/N3D ordering and scaling, rather than FuMa. */
|
||||
static const ChannelMap Ambi3D[9] = {
|
||||
/* Zeroth order */
|
||||
{ Aux0, { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } },
|
||||
/* First order */
|
||||
{ Aux1, { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } },
|
||||
{ Aux2, { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } },
|
||||
{ Aux3, { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } },
|
||||
/* Second order */
|
||||
{ Aux4, { 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f } },
|
||||
{ Aux5, { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f } },
|
||||
{ Aux6, { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f } },
|
||||
{ Aux7, { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f } },
|
||||
{ Aux8, { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } },
|
||||
}, Ambi2D[7] = {
|
||||
/* Zeroth order */
|
||||
{ Aux0, { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } },
|
||||
/* First order */
|
||||
{ Aux1, { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } },
|
||||
{ Aux2, { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } },
|
||||
/* Second order */
|
||||
{ Aux3, { 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } },
|
||||
{ Aux4, { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } },
|
||||
/* Third order */
|
||||
{ Aux5, { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } },
|
||||
{ Aux6, { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } },
|
||||
};
|
||||
const ChannelMap *chanmap = NULL;
|
||||
const char *devname;
|
||||
int decflags = 0;
|
||||
size_t count;
|
||||
ALuint i;
|
||||
|
||||
if((conf->ChanMask & ~0x831b))
|
||||
{
|
||||
count = (conf->ChanMask > 0xf) ? 9 : 4;
|
||||
chanmap = Ambi3D;
|
||||
}
|
||||
count = (conf->ChanMask > 0xf) ? (conf->ChanMask > 0x1ff) ? 16: 9 : 4;
|
||||
else
|
||||
{
|
||||
count = (conf->ChanMask > 0xf) ? (conf->ChanMask > 0x1ff) ? 7 : 5 : 3;
|
||||
chanmap = Ambi2D;
|
||||
}
|
||||
|
||||
devname = al_string_get_cstr(device->DeviceName);
|
||||
if(GetConfigValueBool(devname, "decoder", "distance-comp", 1))
|
||||
decflags |= BFDF_DistanceComp;
|
||||
|
||||
for(i = 0;i < count;i++)
|
||||
device->Dry.ChannelName[i] = chanmap[i].ChanName;
|
||||
device->Dry.ChannelName[i] = Aux0 + i;
|
||||
for(;i < MAX_OUTPUT_CHANNELS;i++)
|
||||
device->Dry.ChannelName[i] = InvalidChannel;
|
||||
SetChannelMap(device->Dry.ChannelName, device->Dry.AmbiCoeffs, chanmap, count,
|
||||
&device->Dry.NumChannels, AL_FALSE);
|
||||
device->Dry.CoeffCount = (conf->ChanMask > 0x1ff) ? 16 :
|
||||
(conf->ChanMask > 0xf) ? 9 : 4;
|
||||
if((conf->ChanMask & ~0x831b))
|
||||
{
|
||||
for(i = 0;i < count;i++)
|
||||
{
|
||||
device->Dry.Ambi.Map[i].Scale = 1.0f;
|
||||
device->Dry.Ambi.Map[i].Index = i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
static int map[MAX_AMBI_COEFFS] = { 0, 1, 3, 4, 8, 9, 15 };
|
||||
for(i = 0;i < count;i++)
|
||||
{
|
||||
device->Dry.Ambi.Map[i].Scale = 1.0f;
|
||||
device->Dry.Ambi.Map[i].Index = map[i];
|
||||
}
|
||||
}
|
||||
device->Dry.CoeffCount = 0;
|
||||
device->Dry.NumChannels = count;
|
||||
|
||||
TRACE("Enabling %s-band %s-order%s ambisonic decoder\n",
|
||||
(conf->FreqBands == 1) ? "single" : "dual",
|
||||
@ -667,15 +682,19 @@ static void InitHQPanning(ALCdevice *device, const AmbDecConf *conf, const ALuin
|
||||
speakermap, decflags);
|
||||
|
||||
if(bformatdec_getOrder(device->AmbiDecoder) < 2)
|
||||
memcpy(device->FOAOut.AmbiCoeffs, device->Dry.AmbiCoeffs,
|
||||
sizeof(device->FOAOut.AmbiCoeffs));
|
||||
{
|
||||
memcpy(&device->FOAOut.Ambi, &device->Dry.Ambi, sizeof(device->FOAOut.Ambi));
|
||||
device->FOAOut.CoeffCount = device->Dry.CoeffCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(device->FOAOut.AmbiCoeffs, 0, sizeof(device->FOAOut.AmbiCoeffs));
|
||||
device->FOAOut.AmbiCoeffs[0][0] = 1.0f;
|
||||
device->FOAOut.AmbiCoeffs[1][1] = 1.0f;
|
||||
device->FOAOut.AmbiCoeffs[2][2] = 1.0f;
|
||||
device->FOAOut.AmbiCoeffs[3][3] = 1.0f;
|
||||
memset(&device->FOAOut.Ambi, 0, sizeof(device->FOAOut.Ambi));
|
||||
for(i = 0;i < 4;i++)
|
||||
{
|
||||
device->FOAOut.Ambi.Map[i].Scale = 1.0f;
|
||||
device->FOAOut.Ambi.Map[i].Index = i;
|
||||
}
|
||||
device->FOAOut.CoeffCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -713,12 +732,12 @@ static void InitHrtfPanning(ALCdevice *device)
|
||||
device->Dry.ChannelName[i] = chanmap[i].ChanName;
|
||||
for(;i < MAX_OUTPUT_CHANNELS;i++)
|
||||
device->Dry.ChannelName[i] = InvalidChannel;
|
||||
SetChannelMap(device->Dry.ChannelName, device->Dry.AmbiCoeffs, chanmap, count,
|
||||
SetChannelMap(device->Dry.ChannelName, device->Dry.Ambi.Coeffs, chanmap, count,
|
||||
&device->Dry.NumChannels, AL_TRUE);
|
||||
device->Dry.CoeffCount = 4;
|
||||
|
||||
memcpy(device->FOAOut.AmbiCoeffs, device->Dry.AmbiCoeffs,
|
||||
sizeof(device->FOAOut.AmbiCoeffs));
|
||||
memcpy(&device->FOAOut.Ambi, &device->Dry.Ambi, sizeof(device->FOAOut.Ambi));
|
||||
device->FOAOut.CoeffCount = device->Dry.CoeffCount;
|
||||
|
||||
for(i = 0;i < device->Dry.NumChannels;i++)
|
||||
{
|
||||
@ -738,12 +757,17 @@ static void InitUhjPanning(ALCdevice *device)
|
||||
device->Dry.ChannelName[i] = chanmap[i].ChanName;
|
||||
for(;i < MAX_OUTPUT_CHANNELS;i++)
|
||||
device->Dry.ChannelName[i] = InvalidChannel;
|
||||
SetChannelMap(device->Dry.ChannelName, device->Dry.AmbiCoeffs, chanmap, count,
|
||||
&device->Dry.NumChannels, AL_TRUE);
|
||||
device->Dry.CoeffCount = 4;
|
||||
for(i = 0;i < count;i++)
|
||||
{
|
||||
ALuint acn = FuMa2ACN[i];
|
||||
device->Dry.Ambi.Map[i].Scale = 1.0f/FuMa2N3DScale[acn];
|
||||
device->Dry.Ambi.Map[i].Index = acn;
|
||||
}
|
||||
device->Dry.CoeffCount = 0;
|
||||
device->Dry.NumChannels = count;
|
||||
|
||||
memcpy(device->FOAOut.AmbiCoeffs, device->Dry.AmbiCoeffs,
|
||||
sizeof(device->FOAOut.AmbiCoeffs));
|
||||
memcpy(&device->FOAOut.Ambi, &device->Dry.Ambi, sizeof(device->FOAOut.Ambi));
|
||||
device->FOAOut.CoeffCount = device->Dry.CoeffCount;
|
||||
}
|
||||
|
||||
void aluInitRenderer(ALCdevice *device, ALint hrtf_id, enum HrtfRequestMode hrtf_appreq, enum HrtfRequestMode hrtf_userreq)
|
||||
@ -759,7 +783,7 @@ void aluInitRenderer(ALCdevice *device, ALint hrtf_id, enum HrtfRequestMode hrtf
|
||||
al_string_clear(&device->Hrtf_Name);
|
||||
device->Render_Mode = NormalRender;
|
||||
|
||||
memset(device->Dry.AmbiCoeffs, 0, sizeof(device->Dry.AmbiCoeffs));
|
||||
memset(&device->Dry.Ambi, 0, sizeof(device->Dry.Ambi));
|
||||
device->Dry.CoeffCount = 0;
|
||||
device->Dry.NumChannels = 0;
|
||||
|
||||
|
@ -509,8 +509,12 @@ struct ALCdevice_struct
|
||||
struct {
|
||||
/* Channel names for the dry buffer mix. */
|
||||
enum Channel ChannelName[MAX_OUTPUT_CHANNELS];
|
||||
/* Ambisonic coefficients for mixing to the dry buffer. */
|
||||
ChannelConfig AmbiCoeffs[MAX_OUTPUT_CHANNELS];
|
||||
union {
|
||||
/* Ambisonic coefficients for mixing to the dry buffer. */
|
||||
ChannelConfig Coeffs[MAX_OUTPUT_CHANNELS];
|
||||
/* Coefficient channel mapping for mixing to the dry buffer. */
|
||||
BFChannelConfig Map[MAX_OUTPUT_CHANNELS];
|
||||
} Ambi;
|
||||
/* Number of coefficients in each ChannelConfig to mix together (4 for
|
||||
* first-order, 9 for second-order, etc).
|
||||
*/
|
||||
@ -523,8 +527,12 @@ struct ALCdevice_struct
|
||||
|
||||
/* First-order ambisonics output, to be upsampled to the dry buffer if different. */
|
||||
struct {
|
||||
/* Ambisonic coefficients for mixing. */
|
||||
ChannelConfig AmbiCoeffs[MAX_OUTPUT_CHANNELS];
|
||||
union {
|
||||
ChannelConfig Coeffs[MAX_OUTPUT_CHANNELS];
|
||||
BFChannelConfig Map[MAX_OUTPUT_CHANNELS];
|
||||
} Ambi;
|
||||
/* Will only be 4 or 0. */
|
||||
ALuint CoeffCount;
|
||||
|
||||
ALfloat (*Buffer)[BUFFERSIZE];
|
||||
ALuint NumChannels;
|
||||
|
@ -330,7 +330,14 @@ void CalcAngleCoeffs(ALfloat azimuth, ALfloat elevation, ALfloat coeffs[MAX_AMBI
|
||||
*
|
||||
* Computes channel gains for ambient, omni-directional sounds.
|
||||
*/
|
||||
void ComputeAmbientGains(const ChannelConfig *chancoeffs, ALuint numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
|
||||
#define ComputeAmbientGains(b, g, o) do { \
|
||||
if((b).CoeffCount > 0) \
|
||||
ComputeAmbientGainsMC((b).Ambi.Coeffs, (b).NumChannels, g, o); \
|
||||
else \
|
||||
ComputeAmbientGainsBF((b).Ambi.Map, (b).NumChannels, g, o); \
|
||||
} while (0)
|
||||
void ComputeAmbientGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
|
||||
void ComputeAmbientGainsBF(const BFChannelConfig *chanmap, ALuint numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
|
||||
|
||||
/**
|
||||
* ComputePanningGains
|
||||
@ -338,7 +345,13 @@ void ComputeAmbientGains(const ChannelConfig *chancoeffs, ALuint numchans, ALflo
|
||||
* Computes panning gains using the given channel decoder coefficients and the
|
||||
* pre-calculated direction or angle coefficients.
|
||||
*/
|
||||
void ComputePanningGains(const ChannelConfig *chancoeffs, ALuint numchans, ALuint numcoeffs, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
|
||||
#define ComputePanningGains(b, c, g, o) do { \
|
||||
if((b).CoeffCount > 0) \
|
||||
ComputePanningGainsMC((b).Ambi.Coeffs, (b).NumChannels, (b).CoeffCount, c, g, o);\
|
||||
else \
|
||||
ComputePanningGainsBF((b).Ambi.Map, (b).NumChannels, c, g, o); \
|
||||
} while (0)
|
||||
void ComputePanningGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, ALuint numcoeffs, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
|
||||
void ComputePanningGainsBF(const BFChannelConfig *chanmap, ALuint numchans, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
|
||||
|
||||
/**
|
||||
@ -348,7 +361,13 @@ void ComputePanningGainsBF(const BFChannelConfig *chanmap, ALuint numchans, cons
|
||||
* a 1x4 'slice' of a transform matrix for the input channel, used to scale and
|
||||
* orient the sound samples.
|
||||
*/
|
||||
void ComputeFirstOrderGains(const ChannelConfig *chancoeffs, ALuint numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
|
||||
#define ComputeFirstOrderGains(b, m, g, o) do { \
|
||||
if((b).CoeffCount > 0) \
|
||||
ComputeFirstOrderGainsMC((b).Ambi.Coeffs, (b).NumChannels, m, g, o); \
|
||||
else \
|
||||
ComputeFirstOrderGainsBF((b).Ambi.Map, (b).NumChannels, m, g, o); \
|
||||
} while (0)
|
||||
void ComputeFirstOrderGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
|
||||
void ComputeFirstOrderGainsBF(const BFChannelConfig *chanmap, ALuint numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user