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:
Chris Robinson 2016-04-15 22:05:47 -07:00
parent e16032e1f0
commit a6c70992b0
14 changed files with 161 additions and 131 deletions

View File

@ -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++)

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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;
}
}
}

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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]);
}
}

View File

@ -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,
if(device->FmtChans == DevFmtBFormat3D)
{
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.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;
}
}
@ -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;

View File

@ -509,8 +509,12 @@ struct ALCdevice_struct
struct {
/* Channel names for the dry buffer mix. */
enum Channel ChannelName[MAX_OUTPUT_CHANNELS];
union {
/* Ambisonic coefficients for mixing to the dry buffer. */
ChannelConfig AmbiCoeffs[MAX_OUTPUT_CHANNELS];
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;

View File

@ -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]);