aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2016-04-15 22:05:47 -0700
committerChris Robinson <[email protected]>2016-04-15 22:05:47 -0700
commita6c70992b01b168d561c448fa235a86c9697b6ef (patch)
treec7fcc5d4d66e0f50a34e982abb954421c596c5d8
parente16032e1f0c92ff23c70393eccbac7def14d4bab (diff)
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.
-rw-r--r--Alc/ALu.c13
-rw-r--r--Alc/effects/autowah.c2
-rw-r--r--Alc/effects/chorus.c8
-rw-r--r--Alc/effects/compressor.c4
-rw-r--r--Alc/effects/dedicated.c11
-rw-r--r--Alc/effects/distortion.c2
-rw-r--r--Alc/effects/echo.c6
-rw-r--r--Alc/effects/equalizer.c4
-rw-r--r--Alc/effects/flanger.c8
-rw-r--r--Alc/effects/modulator.c4
-rw-r--r--Alc/effects/reverb.c21
-rw-r--r--Alc/panning.c166
-rw-r--r--OpenAL32/Include/alMain.h16
-rw-r--r--OpenAL32/Include/alu.h25
14 files changed, 160 insertions, 130 deletions
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 1703b43b..769ea627 100644
--- a/Alc/ALu.c
+++ b/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++)
diff --git a/Alc/effects/autowah.c b/Alc/effects/autowah.c
index 20ae26e4..7c5abfb1 100644
--- a/Alc/effects/autowah.c
+++ b/Alc/effects/autowah.c
@@ -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)
diff --git a/Alc/effects/chorus.c b/Alc/effects/chorus.c
index a55983ab..94c9fc47 100644
--- a/Alc/effects/chorus.c
+++ b/Alc/effects/chorus.c
@@ -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;
diff --git a/Alc/effects/compressor.c b/Alc/effects/compressor.c
index 4e1d55f1..bc4955b9 100644
--- a/Alc/effects/compressor.c
+++ b/Alc/effects/compressor.c
@@ -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)
diff --git a/Alc/effects/dedicated.c b/Alc/effects/dedicated.c
index 9fd10177..20acfdcf 100644
--- a/Alc/effects/dedicated.c
+++ b/Alc/effects/dedicated.c
@@ -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;
}
}
}
diff --git a/Alc/effects/distortion.c b/Alc/effects/distortion.c
index 92eb1a6d..7a4c2f62 100644
--- a/Alc/effects/distortion.c
+++ b/Alc/effects/distortion.c
@@ -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)
diff --git a/Alc/effects/echo.c b/Alc/effects/echo.c
index 00bf5d9f..9fd31864 100644
--- a/Alc/effects/echo.c
+++ b/Alc/effects/echo.c
@@ -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)
diff --git a/Alc/effects/equalizer.c b/Alc/effects/equalizer.c
index f3383bd2..e0fa010e 100644
--- a/Alc/effects/equalizer.c
+++ b/Alc/effects/equalizer.c
@@ -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
diff --git a/Alc/effects/flanger.c b/Alc/effects/flanger.c
index c323c17a..e394f9f2 100644
--- a/Alc/effects/flanger.c
+++ b/Alc/effects/flanger.c
@@ -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;
diff --git a/Alc/effects/modulator.c b/Alc/effects/modulator.c
index 03e0d458..fb75043a 100644
--- a/Alc/effects/modulator.c
+++ b/Alc/effects/modulator.c
@@ -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)
diff --git a/Alc/effects/reverb.c b/Alc/effects/reverb.c
index e5c19d82..bb980ac2 100644
--- a/Alc/effects/reverb.c
+++ b/Alc/effects/reverb.c
@@ -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]);
}
}
diff --git a/Alc/panning.c b/Alc/panning.c
index 9ad9d2a7..0e04f074 100644
--- a/Alc/panning.c
+++ b/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;
+ 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;
- memset(device->FOAOut.AmbiCoeffs, 0, sizeof(device->FOAOut.AmbiCoeffs));
- for(i = 0;i < device->Dry.NumChannels;i++)
+ memcpy(&device->FOAOut.Ambi, &device->Dry.Ambi, sizeof(device->FOAOut.Ambi));
+ device->FOAOut.CoeffCount = device->Dry.CoeffCount;
+ }
+ else
{
- 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;
+ 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;
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 52296a15..12c4c610 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -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;
diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h
index 8b11bdd4..c6b5aba0 100644
--- a/OpenAL32/Include/alu.h
+++ b/OpenAL32/Include/alu.h
@@ -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]);