Add a specific output for first-order sources

This commit is contained in:
Chris Robinson
2016-03-22 17:52:20 -07:00
parent 0a03596af1
commit 713ac9e679
9 changed files with 62 additions and 5 deletions
+19 -1
View File
@@ -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);
+3 -1
View File
@@ -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
+8
View File
@@ -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;
+1
View File
@@ -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);
+4 -1
View File
@@ -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]);
}
+4 -1
View File
@@ -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
+4 -1
View File
@@ -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]);
}
+10
View File
@@ -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:
+9
View File
@@ -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];