aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c20
-rw-r--r--Alc/ALu.c4
-rw-r--r--Alc/bformatdec.c8
-rw-r--r--Alc/bformatdec.h1
-rw-r--r--Alc/effects/compressor.c5
-rw-r--r--Alc/effects/equalizer.c5
-rw-r--r--Alc/effects/modulator.c5
-rw-r--r--Alc/panning.c10
-rw-r--r--OpenAL32/Include/alMain.h9
9 files changed, 62 insertions, 5 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 091a5473..8ca33592 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -2133,7 +2133,9 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
/* Allocate extra channels for any post-filter output. */
size = device->Dry.NumChannels * sizeof(device->Dry.Buffer[0]);
- if(device->Hrtf || device->Uhj_Encoder || device->AmbiDecoder)
+ if(device->AmbiDecoder && bformatdec_getOrder(device->AmbiDecoder) >= 2)
+ size += (ChannelsFromDevFmt(device->FmtChans)+4) * sizeof(device->Dry.Buffer[0]);
+ else if(device->Hrtf || device->Uhj_Encoder || device->AmbiDecoder)
size += ChannelsFromDevFmt(device->FmtChans) * sizeof(device->Dry.Buffer[0]);
device->Dry.Buffer = al_calloc(16, size);
if(!device->Dry.Buffer)
@@ -2157,6 +2159,22 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
device->RealOut.NumChannels = device->Dry.NumChannels;
}
+ if(device->AmbiDecoder && bformatdec_getOrder(device->AmbiDecoder) >= 2)
+ {
+ /* Higher-order high quality decoding requires upsampling first-order
+ * content, so make sure to mix it separately.
+ */
+ device->FOAOut.Buffer = device->RealOut.Buffer + device->RealOut.NumChannels;
+ device->FOAOut.NumChannels = 4;
+ }
+ else
+ {
+ device->FOAOut.Buffer = device->Dry.Buffer;
+ device->FOAOut.NumChannels = device->Dry.NumChannels;
+ memcpy(device->FOAOut.AmbiCoeffs, device->Dry.AmbiCoeffs,
+ sizeof(device->FOAOut.AmbiCoeffs));
+ }
+
SetMixerFPUMode(&oldMode);
V0(device->Backend,lock)();
context = ATOMIC_LOAD(&device->ContextList);
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 55ed84dc..b5b7de9c 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -513,8 +513,10 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A
0.0f, -V[0]*scale, V[1]*scale, -V[2]*scale
);
+ voice->Direct.OutBuffer = Device->FOAOut.Buffer;
+ voice->Direct.OutChannels = Device->FOAOut.NumChannels;
for(c = 0;c < num_channels;c++)
- ComputeFirstOrderGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels, matrix.m[c],
+ ComputeFirstOrderGains(Device->FOAOut.AmbiCoeffs, Device->FOAOut.NumChannels, matrix.m[c],
DryGain, voice->Direct.Gains[c].Target);
/* Rebuild the matrix, without the second- or third-order output
diff --git a/Alc/bformatdec.c b/Alc/bformatdec.c
index f5a8e8c4..37be67e4 100644
--- a/Alc/bformatdec.c
+++ b/Alc/bformatdec.c
@@ -142,6 +142,14 @@ void bformatdec_free(BFormatDec *dec)
}
}
+int bformatdec_getOrder(const struct BFormatDec *dec)
+{
+ if(dec->NumChannels > 9) return 3;
+ if(dec->NumChannels > 4) return 2;
+ if(dec->NumChannels > 1) return 1;
+ return 0;
+}
+
void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALuint chancount, ALuint srate, const ALuint chanmap[MAX_OUTPUT_CHANNELS])
{
const ALfloat *coeff_scale = UnitScale;
diff --git a/Alc/bformatdec.h b/Alc/bformatdec.h
index a322f41d..5f17d711 100644
--- a/Alc/bformatdec.h
+++ b/Alc/bformatdec.h
@@ -8,6 +8,7 @@ struct BFormatDec;
struct BFormatDec *bformatdec_alloc();
void bformatdec_free(struct BFormatDec *dec);
+int bformatdec_getOrder(const struct BFormatDec *dec);
void bformatdec_reset(struct BFormatDec *dec, const struct AmbDecConf *conf, ALuint chancount, ALuint srate, const ALuint chanmap[MAX_OUTPUT_CHANNELS]);
void bformatdec_process(struct BFormatDec *dec, ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALuint OutChannels, ALfloat (*restrict InSamples)[BUFFERSIZE], ALuint SamplesToDo);
diff --git a/Alc/effects/compressor.c b/Alc/effects/compressor.c
index ae859793..6358f672 100644
--- a/Alc/effects/compressor.c
+++ b/Alc/effects/compressor.c
@@ -70,8 +70,11 @@ static ALvoid ALcompressorState_update(ALcompressorState *state, const ALCdevice
0.0f, 0.0f, scale, 0.0f,
0.0f, 0.0f, 0.0f, scale
);
+
+ STATIC_CAST(ALeffectState,state)->OutBuffer = device->FOAOut.Buffer;
+ STATIC_CAST(ALeffectState,state)->OutChannels = device->FOAOut.NumChannels;
for(i = 0;i < 4;i++)
- ComputeFirstOrderGains(device->Dry.AmbiCoeffs, device->Dry.NumChannels,
+ ComputeFirstOrderGains(device->FOAOut.AmbiCoeffs, device->FOAOut.NumChannels,
matrix.m[i], slot->Gain, state->Gain[i]);
}
diff --git a/Alc/effects/equalizer.c b/Alc/effects/equalizer.c
index 479a8536..ffc9830f 100644
--- a/Alc/effects/equalizer.c
+++ b/Alc/effects/equalizer.c
@@ -110,8 +110,11 @@ static ALvoid ALequalizerState_update(ALequalizerState *state, const ALCdevice *
0.0f, 0.0f, gain, 0.0f,
0.0f, 0.0f, 0.0f, gain
);
+
+ 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->Dry.AmbiCoeffs, device->Dry.NumChannels,
+ ComputeFirstOrderGains(device->FOAOut.AmbiCoeffs, device->FOAOut.NumChannels,
matrix.m[i], slot->Gain, state->Gain[i]);
/* Calculate coefficients for the each type of filter. Note that the shelf
diff --git a/Alc/effects/modulator.c b/Alc/effects/modulator.c
index 4183b908..c283d4b0 100644
--- a/Alc/effects/modulator.c
+++ b/Alc/effects/modulator.c
@@ -129,8 +129,11 @@ static ALvoid ALmodulatorState_update(ALmodulatorState *state, const ALCdevice *
0.0f, 0.0f, scale, 0.0f,
0.0f, 0.0f, 0.0f, scale
);
+
+ 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->Dry.AmbiCoeffs, Device->Dry.NumChannels,
+ ComputeFirstOrderGains(Device->FOAOut.AmbiCoeffs, Device->FOAOut.NumChannels,
matrix.m[i], Slot->Gain, state->Gain[i]);
}
diff --git a/Alc/panning.c b/Alc/panning.c
index 16c84b6d..401d29d6 100644
--- a/Alc/panning.c
+++ b/Alc/panning.c
@@ -646,6 +646,16 @@ ALvoid aluInitPanning(ALCdevice *device)
TRACE("Enabling %s-band ambisonic decoder\n", (conf.FreqBands==1)?"single":"dual");
bformatdec_reset(device->AmbiDecoder, &conf, count, device->Frequency, speakermap);
ambdec_deinit(&conf);
+
+ if(bformatdec_getOrder(device->AmbiDecoder) >= 2)
+ {
+ 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;
+ }
+
return;
ambi_fail:
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index c71e844f..b870059b 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -507,6 +507,15 @@ struct ALCdevice_struct
ALuint NumChannels;
} Dry;
+ /* First-order ambisonics output, to be upsampled to the dry buffer if different. */
+ struct {
+ /* Ambisonic coefficients for mixing. */
+ ChannelConfig AmbiCoeffs[MAX_OUTPUT_CHANNELS];
+
+ ALfloat (*Buffer)[BUFFERSIZE];
+ ALuint NumChannels;
+ } FOAOut;
+
/* Virtual output, to be post-processed to the real output. */
struct {
ALfloat (*Buffer)[BUFFERSIZE];