Add a specific output for first-order sources
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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];
|
||||
|
||||
Reference in New Issue
Block a user