Add an option to specify the ambisonic output configuration
This commit is contained in:
@@ -3427,6 +3427,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
|
||||
device->FmtType = DevFmtTypeDefault;
|
||||
device->Frequency = DEFAULT_OUTPUT_RATE;
|
||||
device->IsHeadphones = AL_FALSE;
|
||||
device->AmbiFmt = AmbiFormat_Default;
|
||||
device->NumUpdates = 4;
|
||||
device->UpdateSize = 1024;
|
||||
|
||||
@@ -3544,6 +3545,18 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
|
||||
}
|
||||
almtx_init(&device->BackendLock, almtx_plain);
|
||||
|
||||
if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "ambi-format", &fmt))
|
||||
{
|
||||
if(strcasecmp(fmt, "fuma") == 0)
|
||||
device->AmbiFmt = AmbiFormat_FuMa;
|
||||
else if(strcasecmp(fmt, "acn+sn3d") == 0)
|
||||
device->AmbiFmt = AmbiFormat_ACN_SN3D;
|
||||
else if(strcasecmp(fmt, "acn+n3d") == 0)
|
||||
device->AmbiFmt = AmbiFormat_ACN_N3D;
|
||||
else
|
||||
ERR("Unsupported ambi-format: %s\n", fmt);
|
||||
}
|
||||
|
||||
if(DefaultEffect.type != AL_EFFECT_NULL)
|
||||
{
|
||||
device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
|
||||
@@ -3706,6 +3719,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName,
|
||||
return NULL;
|
||||
}
|
||||
device->IsHeadphones = AL_FALSE;
|
||||
device->AmbiFmt = AmbiFormat_Default;
|
||||
|
||||
device->UpdateSize = samples;
|
||||
device->NumUpdates = 1;
|
||||
@@ -3903,6 +3917,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN
|
||||
device->FmtChans = DevFmtChannelsDefault;
|
||||
device->FmtType = DevFmtTypeDefault;
|
||||
device->IsHeadphones = AL_FALSE;
|
||||
device->AmbiFmt = AmbiFormat_Default;
|
||||
|
||||
ConfigValueUInt(NULL, NULL, "sources", &device->SourcesMax);
|
||||
if(device->SourcesMax == 0) device->SourcesMax = 256;
|
||||
|
||||
+31
-26
@@ -63,6 +63,10 @@ static const ALuint FuMa2ACN[MAX_AMBI_COEFFS] = {
|
||||
15, /* P */
|
||||
9, /* Q */
|
||||
};
|
||||
static const ALuint ACN2ACN[MAX_AMBI_COEFFS] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15
|
||||
};
|
||||
|
||||
/* NOTE: These are scale factors as applied to Ambisonics content. Decoder
|
||||
* coefficients should be divided by these values to get proper N3D scalings.
|
||||
@@ -596,44 +600,45 @@ static void InitPanning(ALCdevice *device)
|
||||
device->FOAOut.Ambi = device->Dry.Ambi;
|
||||
device->FOAOut.CoeffCount = device->Dry.CoeffCount;
|
||||
}
|
||||
else if(device->FmtChans == DevFmtAmbi1)
|
||||
else if(device->FmtChans >= DevFmtAmbi1 && device->FmtChans <= DevFmtAmbi3)
|
||||
{
|
||||
count = 4;
|
||||
for(i = 0;i < count;i++)
|
||||
{
|
||||
device->Dry.Ambi.Map[i].Scale = 1.0f/SN3D2N3DScale[i];
|
||||
device->Dry.Ambi.Map[i].Index = i;
|
||||
}
|
||||
device->Dry.CoeffCount = 0;
|
||||
device->Dry.NumChannels = count;
|
||||
const ALuint *acnmap = (device->AmbiFmt == AmbiFormat_FuMa) ? FuMa2ACN : ACN2ACN;
|
||||
const ALfloat *n3dcale = (device->AmbiFmt == AmbiFormat_FuMa) ? FuMa2N3DScale :
|
||||
(device->AmbiFmt == AmbiFormat_ACN_SN3D) ? SN3D2N3DScale :
|
||||
/*(device->AmbiFmt == AmbiFormat_ACN_N3D) ?*/ UnitScale;
|
||||
|
||||
device->FOAOut.Ambi = device->Dry.Ambi;
|
||||
device->FOAOut.CoeffCount = device->Dry.CoeffCount;
|
||||
}
|
||||
else if(device->FmtChans == DevFmtAmbi2 || device->FmtChans == DevFmtAmbi3)
|
||||
{
|
||||
count = (device->FmtChans == DevFmtAmbi3) ? 16 :
|
||||
(device->FmtChans == DevFmtAmbi2) ? 9 : 1;
|
||||
(device->FmtChans == DevFmtAmbi2) ? 9 :
|
||||
(device->FmtChans == DevFmtAmbi1) ? 4 : 1;
|
||||
for(i = 0;i < count;i++)
|
||||
{
|
||||
device->Dry.Ambi.Map[i].Scale = 1.0f/SN3D2N3DScale[i];
|
||||
device->Dry.Ambi.Map[i].Index = i;
|
||||
ALuint acn = acnmap[i];
|
||||
device->Dry.Ambi.Map[i].Scale = 1.0f/n3dcale[acn];
|
||||
device->Dry.Ambi.Map[i].Index = acn;
|
||||
}
|
||||
device->Dry.CoeffCount = 0;
|
||||
device->Dry.NumChannels = count;
|
||||
|
||||
/* FOA output is always ACN+N3D for higher-order ambisonic output. The
|
||||
* upsampler expects this and will convert it for output.
|
||||
*/
|
||||
memset(&device->FOAOut.Ambi, 0, sizeof(device->FOAOut.Ambi));
|
||||
for(i = 0;i < 4;i++)
|
||||
if(device->FmtChans == DevFmtAmbi1)
|
||||
{
|
||||
device->FOAOut.Ambi.Map[i].Scale = 1.0f;
|
||||
device->FOAOut.Ambi.Map[i].Index = i;
|
||||
device->FOAOut.Ambi = device->Dry.Ambi;
|
||||
device->FOAOut.CoeffCount = device->Dry.CoeffCount;
|
||||
}
|
||||
device->FOAOut.CoeffCount = 0;
|
||||
else
|
||||
{
|
||||
/* FOA output is always ACN+N3D for higher-order ambisonic output.
|
||||
* The upsampler expects this and will convert it for output.
|
||||
*/
|
||||
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;
|
||||
|
||||
ambiup_reset(device->AmbiUp, device);
|
||||
ambiup_reset(device->AmbiUp, device);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -463,6 +463,14 @@ inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType typ
|
||||
return ChannelsFromDevFmt(chans) * BytesFromDevFmt(type);
|
||||
}
|
||||
|
||||
enum AmbiFormat {
|
||||
AmbiFormat_FuMa, /* FuMa channel order and normalization */
|
||||
AmbiFormat_ACN_SN3D, /* ACN channel order and SN3D normalization */
|
||||
AmbiFormat_ACN_N3D, /* ACN channel order and N3D normalization */
|
||||
|
||||
AmbiFormat_Default = AmbiFormat_ACN_SN3D
|
||||
};
|
||||
|
||||
|
||||
extern const struct EffectList {
|
||||
const char *name;
|
||||
@@ -557,6 +565,10 @@ struct ALCdevice_struct
|
||||
enum DevFmtChannels FmtChans;
|
||||
enum DevFmtType FmtType;
|
||||
ALboolean IsHeadphones;
|
||||
/* For DevFmtAmbi* output only, specifies the channel order and
|
||||
* normalization.
|
||||
*/
|
||||
enum AmbiFormat AmbiFmt;
|
||||
|
||||
al_string DeviceName;
|
||||
|
||||
|
||||
@@ -97,6 +97,11 @@
|
||||
# disabled.
|
||||
#stereo-panning = uhj
|
||||
|
||||
## ambi-format:
|
||||
# Specifies the channel order and normalization for the "ambi*" set of channel
|
||||
# configurations. Valid settings are: fuma, acn+sn3d, acn+n3d
|
||||
#ambi-format = acn+sn3d
|
||||
|
||||
## hrtf:
|
||||
# Controls HRTF processing. These filters provide better spatialization of
|
||||
# sounds while using headphones, but do require a bit more CPU power. The
|
||||
|
||||
Reference in New Issue
Block a user