aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2019-01-05 19:21:25 -0800
committerChris Robinson <[email protected]>2019-01-05 19:21:25 -0800
commitcff20c2fe8cdc34958c2634ad742491bd7389e13 (patch)
treee40d09391c7a38a5785599661ea0ec2159395e6e /Alc
parent641bbf075d741cbe6cdf0c361a9d0ba84a562796 (diff)
Use BFormatDec for custom and built-in ambisonic decoding
Diffstat (limited to 'Alc')
-rw-r--r--Alc/bformatdec.cpp68
-rw-r--r--Alc/bformatdec.h7
-rw-r--r--Alc/panning.cpp207
3 files changed, 178 insertions, 104 deletions
diff --git a/Alc/bformatdec.cpp b/Alc/bformatdec.cpp
index a6c8f4c6..84f18833 100644
--- a/Alc/bformatdec.cpp
+++ b/Alc/bformatdec.cpp
@@ -75,16 +75,23 @@ inline auto GetAmbiScales(AmbDecScale scaletype) noexcept -> const std::array<fl
} // namespace
-void BFormatDec::reset(const AmbDecConf *conf, ALsizei chancount, ALuint srate, const ALsizei (&chanmap)[MAX_OUTPUT_CHANNELS])
+void BFormatDec::reset(const AmbDecConf *conf, bool allow_2band, ALsizei inchans, ALuint srate, const ALsizei (&chanmap)[MAX_OUTPUT_CHANNELS])
{
mSamples.clear();
mSamplesHF = nullptr;
mSamplesLF = nullptr;
- mNumChannels = chancount;
- mSamples.resize(chancount * 2);
- mSamplesHF = mSamples.data();
- mSamplesLF = mSamplesHF + chancount;
+ mMatrix = MatrixU{};
+ mDualBand = allow_2band && (conf->FreqBands == 2);
+ if(!mDualBand)
+ mSamples.resize(1);
+ else
+ {
+ mSamples.resize(inchans * 2);
+ mSamplesHF = mSamples.data();
+ mSamplesLF = mSamplesHF + inchans;
+ }
+ mNumChannels = inchans;
mEnabled = std::accumulate(std::begin(chanmap), std::begin(chanmap)+conf->Speakers.size(), 0u,
[](ALuint mask, const ALsizei &chan) noexcept -> ALuint
@@ -118,8 +125,6 @@ void BFormatDec::reset(const AmbDecConf *conf, ALsizei chancount, ALuint srate,
const std::array<float,MAX_AMBI_COEFFS> &coeff_scale = GetAmbiScales(conf->CoeffScale);
const ALsizei coeff_count{periphonic ? MAX_AMBI_COEFFS : MAX_AMBI2D_COEFFS};
- mMatrix = MatrixU{};
- mDualBand = (conf->FreqBands == 2);
if(!mDualBand)
{
for(size_t i{0u};i < conf->Speakers.size();i++)
@@ -164,6 +169,55 @@ void BFormatDec::reset(const AmbDecConf *conf, ALsizei chancount, ALuint srate,
}
}
+void BFormatDec::reset(ALsizei inchans, ALuint srate, ALsizei chancount, const ChannelDec (&chancoeffs)[MAX_OUTPUT_CHANNELS], const ALsizei (&chanmap)[MAX_OUTPUT_CHANNELS])
+{
+ mSamples.clear();
+ mSamplesHF = nullptr;
+ mSamplesLF = nullptr;
+
+ mMatrix = MatrixU{};
+ mDualBand = false;
+ mSamples.resize(1);
+ mNumChannels = inchans;
+
+ mEnabled = std::accumulate(std::begin(chanmap), std::begin(chanmap)+chancount, 0u,
+ [](ALuint mask, const ALsizei &chan) noexcept -> ALuint
+ { return mask | (1 << chan); }
+ );
+
+ const ALfloat xover_norm{400.0f / (float)srate};
+
+ const ALsizei out_order{
+ (inchans > 7) ? 4 :
+ (inchans > 5) ? 3 :
+ (inchans > 3) ? 2 : 1};
+ {
+ const ALfloat (&hfscales)[MAX_AMBI_COEFFS] = GetDecoderHFScales(out_order);
+ /* The specified filter gain is for the mid-point/reference gain. The
+ * gain at the shelf itself will be the square of that, so specify the
+ * square-root of the desired shelf gain.
+ */
+ const ALfloat gain0{std::sqrt(Ambi3DDecoderHFScale[0] / hfscales[0])};
+ const ALfloat gain1{std::sqrt(Ambi3DDecoderHFScale[1] / hfscales[1])};
+
+ mUpSampler[0].Shelf.setParams(BiquadType::HighShelf, gain0, xover_norm,
+ calc_rcpQ_from_slope(gain0, 1.0f));
+ mUpSampler[1].Shelf.setParams(BiquadType::HighShelf, gain1, xover_norm,
+ calc_rcpQ_from_slope(gain1, 1.0f));
+ for(ALsizei i{2};i < 4;i++)
+ mUpSampler[i].Shelf.copyParamsFrom(mUpSampler[1].Shelf);
+ }
+
+ for(size_t i{0u};i < chancount;i++)
+ {
+ const ALfloat (&coeffs)[MAX_AMBI_COEFFS] = chancoeffs[chanmap[i]];
+ ALfloat (&mtx)[MAX_AMBI_COEFFS] = mMatrix.Single[chanmap[i]];
+
+ std::copy_n(std::begin(coeffs), inchans, std::begin(mtx));
+ }
+}
+
+
void BFormatDec::process(ALfloat (*OutBuffer)[BUFFERSIZE], const ALsizei OutChannels, const ALfloat (*InSamples)[BUFFERSIZE], const ALsizei SamplesToDo)
{
ASSUME(OutChannels > 0);
diff --git a/Alc/bformatdec.h b/Alc/bformatdec.h
index 144c22a2..acc71b18 100644
--- a/Alc/bformatdec.h
+++ b/Alc/bformatdec.h
@@ -4,12 +4,15 @@
#include "alMain.h"
#include "filters/biquad.h"
#include "filters/splitter.h"
+#include "ambidefs.h"
#include "almalloc.h"
struct AmbDecConf;
+using ChannelDec = ALfloat[MAX_AMBI_COEFFS];
+
class BFormatDec {
public:
static constexpr size_t sNumBands{2};
@@ -38,7 +41,9 @@ private:
ALboolean mDualBand;
public:
- void reset(const AmbDecConf *conf, ALsizei chancount, ALuint srate, const ALsizei (&chanmap)[MAX_OUTPUT_CHANNELS]);
+ void reset(const AmbDecConf *conf, bool allow_2band, ALsizei inchans, ALuint srate, const ALsizei (&chanmap)[MAX_OUTPUT_CHANNELS]);
+
+ void reset(ALsizei inchans, ALuint srate, ALsizei chancount, const ChannelDec (&chancoeffs)[MAX_OUTPUT_CHANNELS], const ALsizei (&chanmap)[MAX_OUTPUT_CHANNELS]);
/* Decodes the ambisonic input to the given output channels. */
void process(ALfloat (*OutBuffer)[BUFFERSIZE], const ALsizei OutChannels, const ALfloat (*InSamples)[BUFFERSIZE], const ALsizei SamplesToDo);
diff --git a/Alc/panning.cpp b/Alc/panning.cpp
index 1582cbae..820d2268 100644
--- a/Alc/panning.cpp
+++ b/Alc/panning.cpp
@@ -101,28 +101,9 @@ inline const char *GetLabelFromChannel(Channel channel)
struct ChannelMap {
Channel ChanName;
- ChannelConfig Config;
+ ALfloat Config[MAX_AMBI2D_COEFFS];
};
-void SetChannelMap(const Channel (&devchans)[MAX_OUTPUT_CHANNELS], ChannelConfig *ambicoeffs,
- const ChannelMap *chanmap, const size_t count, ALsizei *outcount)
-{
- auto copy_coeffs = [&devchans,ambicoeffs](ALsizei maxchans, const ChannelMap &channel) -> ALsizei
- {
- const ALint idx{GetChannelIndex(devchans, channel.ChanName)};
- if(idx < 0)
- {
- ERR("Failed to find %s channel in device\n", GetLabelFromChannel(channel.ChanName));
- return maxchans;
- }
-
- std::copy(std::begin(channel.Config), std::end(channel.Config), ambicoeffs[idx]);
- return maxi(maxchans, idx+1);
- };
- ALsizei maxcount{std::accumulate(chanmap, chanmap+count, ALsizei{0}, copy_coeffs)};
- *outcount = mini(maxcount, MAX_OUTPUT_CHANNELS);
-}
-
bool MakeSpeakerMap(ALCdevice *device, const AmbDecConf *conf, ALsizei (&speakermap)[MAX_OUTPUT_CHANNELS])
{
auto map_spkr = [device](const AmbDecConf::SpeakerConf &speaker) -> ALsizei
@@ -213,36 +194,36 @@ bool MakeSpeakerMap(ALCdevice *device, const AmbDecConf *conf, ALsizei (&speaker
constexpr ChannelMap MonoCfg[1] = {
{ FrontCenter, { 1.0f } },
}, StereoCfg[2] = {
- { FrontLeft, { 5.00000000e-1f, 2.88675135e-1f, 0.0f, 5.52305643e-2f } },
- { FrontRight, { 5.00000000e-1f, -2.88675135e-1f, 0.0f, 5.52305643e-2f } },
+ { FrontLeft, { 5.00000000e-1f, 2.88675135e-1f, 5.52305643e-2f } },
+ { FrontRight, { 5.00000000e-1f, -2.88675135e-1f, 5.52305643e-2f } },
}, QuadCfg[4] = {
- { BackLeft, { 3.53553391e-1f, 2.04124145e-1f, 0.0f, -2.04124145e-1f } },
- { FrontLeft, { 3.53553391e-1f, 2.04124145e-1f, 0.0f, 2.04124145e-1f } },
- { FrontRight, { 3.53553391e-1f, -2.04124145e-1f, 0.0f, 2.04124145e-1f } },
- { BackRight, { 3.53553391e-1f, -2.04124145e-1f, 0.0f, -2.04124145e-1f } },
+ { BackLeft, { 3.53553391e-1f, 2.04124145e-1f, -2.04124145e-1f } },
+ { FrontLeft, { 3.53553391e-1f, 2.04124145e-1f, 2.04124145e-1f } },
+ { FrontRight, { 3.53553391e-1f, -2.04124145e-1f, 2.04124145e-1f } },
+ { BackRight, { 3.53553391e-1f, -2.04124145e-1f, -2.04124145e-1f } },
}, X51SideCfg[4] = {
- { SideLeft, { 3.33000782e-1f, 1.89084803e-1f, 0.0f, -2.00042375e-1f, -2.12307769e-2f, 0.0f, 0.0f, 0.0f, -1.14579885e-2f } },
- { FrontLeft, { 1.88542860e-1f, 1.27709292e-1f, 0.0f, 1.66295695e-1f, 7.30571517e-2f, 0.0f, 0.0f, 0.0f, 2.10901184e-2f } },
- { FrontRight, { 1.88542860e-1f, -1.27709292e-1f, 0.0f, 1.66295695e-1f, -7.30571517e-2f, 0.0f, 0.0f, 0.0f, 2.10901184e-2f } },
- { SideRight, { 3.33000782e-1f, -1.89084803e-1f, 0.0f, -2.00042375e-1f, 2.12307769e-2f, 0.0f, 0.0f, 0.0f, -1.14579885e-2f } },
+ { SideLeft, { 3.33000782e-1f, 1.89084803e-1f, -2.00042375e-1f, -2.12307769e-2f, -1.14579885e-2f } },
+ { FrontLeft, { 1.88542860e-1f, 1.27709292e-1f, 1.66295695e-1f, 7.30571517e-2f, 2.10901184e-2f } },
+ { FrontRight, { 1.88542860e-1f, -1.27709292e-1f, 1.66295695e-1f, -7.30571517e-2f, 2.10901184e-2f } },
+ { SideRight, { 3.33000782e-1f, -1.89084803e-1f, -2.00042375e-1f, 2.12307769e-2f, -1.14579885e-2f } },
}, X51RearCfg[4] = {
- { BackLeft, { 3.33000782e-1f, 1.89084803e-1f, 0.0f, -2.00042375e-1f, -2.12307769e-2f, 0.0f, 0.0f, 0.0f, -1.14579885e-2f } },
- { FrontLeft, { 1.88542860e-1f, 1.27709292e-1f, 0.0f, 1.66295695e-1f, 7.30571517e-2f, 0.0f, 0.0f, 0.0f, 2.10901184e-2f } },
- { FrontRight, { 1.88542860e-1f, -1.27709292e-1f, 0.0f, 1.66295695e-1f, -7.30571517e-2f, 0.0f, 0.0f, 0.0f, 2.10901184e-2f } },
- { BackRight, { 3.33000782e-1f, -1.89084803e-1f, 0.0f, -2.00042375e-1f, 2.12307769e-2f, 0.0f, 0.0f, 0.0f, -1.14579885e-2f } },
+ { BackLeft, { 3.33000782e-1f, 1.89084803e-1f, -2.00042375e-1f, -2.12307769e-2f, -1.14579885e-2f } },
+ { FrontLeft, { 1.88542860e-1f, 1.27709292e-1f, 1.66295695e-1f, 7.30571517e-2f, 2.10901184e-2f } },
+ { FrontRight, { 1.88542860e-1f, -1.27709292e-1f, 1.66295695e-1f, -7.30571517e-2f, 2.10901184e-2f } },
+ { BackRight, { 3.33000782e-1f, -1.89084803e-1f, -2.00042375e-1f, 2.12307769e-2f, -1.14579885e-2f } },
}, X61Cfg[6] = {
- { SideLeft, { 2.04460341e-1f, 2.17177926e-1f, 0.0f, -4.39996780e-2f, -2.60790269e-2f, 0.0f, 0.0f, 0.0f, -6.87239792e-2f } },
- { FrontLeft, { 1.58923161e-1f, 9.21772680e-2f, 0.0f, 1.59658796e-1f, 6.66278083e-2f, 0.0f, 0.0f, 0.0f, 3.84686854e-2f } },
- { FrontRight, { 1.58923161e-1f, -9.21772680e-2f, 0.0f, 1.59658796e-1f, -6.66278083e-2f, 0.0f, 0.0f, 0.0f, 3.84686854e-2f } },
- { SideRight, { 2.04460341e-1f, -2.17177926e-1f, 0.0f, -4.39996780e-2f, 2.60790269e-2f, 0.0f, 0.0f, 0.0f, -6.87239792e-2f } },
- { BackCenter, { 2.50001688e-1f, 0.00000000e+0f, 0.0f, -2.50000094e-1f, 0.00000000e+0f, 0.0f, 0.0f, 0.0f, 6.05133395e-2f } },
+ { SideLeft, { 2.04460341e-1f, 2.17177926e-1f, -4.39996780e-2f, -2.60790269e-2f, -6.87239792e-2f } },
+ { FrontLeft, { 1.58923161e-1f, 9.21772680e-2f, 1.59658796e-1f, 6.66278083e-2f, 3.84686854e-2f } },
+ { FrontRight, { 1.58923161e-1f, -9.21772680e-2f, 1.59658796e-1f, -6.66278083e-2f, 3.84686854e-2f } },
+ { SideRight, { 2.04460341e-1f, -2.17177926e-1f, -4.39996780e-2f, 2.60790269e-2f, -6.87239792e-2f } },
+ { BackCenter, { 2.50001688e-1f, 0.00000000e+0f, -2.50000094e-1f, 0.00000000e+0f, 6.05133395e-2f } },
}, X71Cfg[6] = {
- { BackLeft, { 2.04124145e-1f, 1.08880247e-1f, 0.0f, -1.88586120e-1f, -1.29099444e-1f, 0.0f, 0.0f, 0.0f, 7.45355993e-2f, 3.73460789e-2f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.00000000e+0f } },
- { SideLeft, { 2.04124145e-1f, 2.17760495e-1f, 0.0f, 0.00000000e+0f, 0.00000000e+0f, 0.0f, 0.0f, 0.0f, -1.49071198e-1f, -3.73460789e-2f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.00000000e+0f } },
- { FrontLeft, { 2.04124145e-1f, 1.08880247e-1f, 0.0f, 1.88586120e-1f, 1.29099444e-1f, 0.0f, 0.0f, 0.0f, 7.45355993e-2f, 3.73460789e-2f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.00000000e+0f } },
- { FrontRight, { 2.04124145e-1f, -1.08880247e-1f, 0.0f, 1.88586120e-1f, -1.29099444e-1f, 0.0f, 0.0f, 0.0f, 7.45355993e-2f, -3.73460789e-2f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.00000000e+0f } },
- { SideRight, { 2.04124145e-1f, -2.17760495e-1f, 0.0f, 0.00000000e+0f, 0.00000000e+0f, 0.0f, 0.0f, 0.0f, -1.49071198e-1f, 3.73460789e-2f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.00000000e+0f } },
- { BackRight, { 2.04124145e-1f, -1.08880247e-1f, 0.0f, -1.88586120e-1f, 1.29099444e-1f, 0.0f, 0.0f, 0.0f, 7.45355993e-2f, -3.73460789e-2f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.00000000e+0f } },
+ { BackLeft, { 2.04124145e-1f, 1.08880247e-1f, -1.88586120e-1f, -1.29099444e-1f, 7.45355993e-2f, 3.73460789e-2f, 0.00000000e+0f } },
+ { SideLeft, { 2.04124145e-1f, 2.17760495e-1f, 0.00000000e+0f, 0.00000000e+0f, -1.49071198e-1f, -3.73460789e-2f, 0.00000000e+0f } },
+ { FrontLeft, { 2.04124145e-1f, 1.08880247e-1f, 1.88586120e-1f, 1.29099444e-1f, 7.45355993e-2f, 3.73460789e-2f, 0.00000000e+0f } },
+ { FrontRight, { 2.04124145e-1f, -1.08880247e-1f, 1.88586120e-1f, -1.29099444e-1f, 7.45355993e-2f, -3.73460789e-2f, 0.00000000e+0f } },
+ { SideRight, { 2.04124145e-1f, -2.17760495e-1f, 0.00000000e+0f, 0.00000000e+0f, -1.49071198e-1f, 3.73460789e-2f, 0.00000000e+0f } },
+ { BackRight, { 2.04124145e-1f, -1.08880247e-1f, -1.88586120e-1f, 1.29099444e-1f, 7.45355993e-2f, -3.73460789e-2f, 0.00000000e+0f } },
};
void InitNearFieldCtrl(ALCdevice *device, ALfloat ctrl_dist, ALsizei order, const ALsizei *RESTRICT chans_per_order)
@@ -326,12 +307,6 @@ void InitDistanceComp(ALCdevice *device, const AmbDecConf *conf, const ALsizei (
}
}
-auto GetAmbiScales(AmbDecScale scaletype) noexcept -> const std::array<float,MAX_AMBI_COEFFS>&
-{
- if(scaletype == AmbDecScale::FuMa) return AmbiScale::FromFuMa;
- if(scaletype == AmbDecScale::SN3D) return AmbiScale::FromSN3D;
- return AmbiScale::FromN3D;
-}
auto GetAmbiScales(AmbiNorm scaletype) noexcept -> const std::array<float,MAX_AMBI_COEFFS>&
{
@@ -364,37 +339,37 @@ void InitPanning(ALCdevice *device)
case DevFmtStereo:
count = static_cast<ALsizei>(COUNTOF(StereoCfg));
chanmap = StereoCfg;
- coeffcount = 4;
+ coeffcount = 3;
break;
case DevFmtQuad:
count = static_cast<ALsizei>(COUNTOF(QuadCfg));
chanmap = QuadCfg;
- coeffcount = 4;
+ coeffcount = 3;
break;
case DevFmtX51:
count = static_cast<ALsizei>(COUNTOF(X51SideCfg));
chanmap = X51SideCfg;
- coeffcount = 9;
+ coeffcount = 5;
break;
case DevFmtX51Rear:
count = static_cast<ALsizei>(COUNTOF(X51RearCfg));
chanmap = X51RearCfg;
- coeffcount = 9;
+ coeffcount = 5;
break;
case DevFmtX61:
count = static_cast<ALsizei>(COUNTOF(X61Cfg));
chanmap = X61Cfg;
- coeffcount = 9;
+ coeffcount = 5;
break;
case DevFmtX71:
count = static_cast<ALsizei>(COUNTOF(X71Cfg));
chanmap = X71Cfg;
- coeffcount = 16;
+ coeffcount = 7;
break;
case DevFmtAmbi3D:
@@ -445,12 +420,40 @@ void InitPanning(ALCdevice *device)
InitNearFieldCtrl(device, nfc_delay * SPEEDOFSOUNDMETRESPERSEC,
device->mAmbiOrder, chans_per_order);
}
+
+ device->RealOut.NumChannels = 0;
}
else
{
- SetChannelMap(device->RealOut.ChannelName, device->Dry.Ambi.Coeffs,
- chanmap, count, &device->Dry.NumChannels);
- device->Dry.CoeffCount = coeffcount;
+ ChannelDec chancoeffs[MAX_OUTPUT_CHANNELS]{};
+ ALsizei idxmap[MAX_OUTPUT_CHANNELS]{};
+ for(ALsizei i{0};i < count;++i)
+ {
+ const ALint idx{GetChannelIdxByName(device->RealOut, chanmap[i].ChanName)};
+ if(idx < 0)
+ {
+ ERR("Failed to find %s channel in device\n",
+ GetLabelFromChannel(chanmap[i].ChanName));
+ continue;
+ }
+ idxmap[i] = idx;
+ std::copy_n(chanmap[i].Config, coeffcount, chancoeffs[i]);
+ }
+
+ std::transform(AmbiIndex::From2D.begin(), AmbiIndex::From2D.begin()+coeffcount,
+ std::begin(device->Dry.Ambi.Map),
+ [](const ALsizei &index) noexcept { return BFChannelConfig{1.0f, index}; }
+ );
+ device->Dry.CoeffCount = 0;
+ device->Dry.NumChannels = coeffcount;
+
+ TRACE("Enabling %s-order%s ambisonic decoder\n",
+ (coeffcount > 5) ? "third" :
+ (coeffcount > 3) ? "second" : "first",
+ ""
+ );
+ device->AmbiDecoder.reset(new BFormatDec{});
+ device->AmbiDecoder->reset(coeffcount, device->Frequency, count, chancoeffs, idxmap);
if(coeffcount <= 4)
{
@@ -461,18 +464,16 @@ void InitPanning(ALCdevice *device)
else
{
device->FOAOut.Ambi = AmbiConfig{};
- std::transform(AmbiIndex::From3D.begin(), AmbiIndex::From3D.begin()+4,
+ std::transform(AmbiIndex::From2D.begin(), AmbiIndex::From2D.begin()+3,
std::begin(device->FOAOut.Ambi.Map),
[](const ALsizei &acn) noexcept { return BFChannelConfig{1.0f, acn}; }
);
device->FOAOut.CoeffCount = 0;
- device->FOAOut.NumChannels = 4;
-
- device->AmbiUp.reset(new AmbiUpsampler{});
- device->AmbiUp->reset(device);
+ device->FOAOut.NumChannels = 3;
}
+
+ device->RealOut.NumChannels = device->channelsFromFmt();
}
- device->RealOut.NumChannels = 0;
}
void InitCustomPanning(ALCdevice *device, const AmbDecConf *conf, const ALsizei (&speakermap)[MAX_OUTPUT_CHANNELS])
@@ -481,28 +482,35 @@ void InitCustomPanning(ALCdevice *device, const AmbDecConf *conf, const ALsizei
ERR("Basic renderer uses the high-frequency matrix as single-band (xover_freq = %.0fhz)\n",
conf->XOverFreq);
- const std::array<float,MAX_AMBI_COEFFS> &coeff_scale = GetAmbiScales(conf->CoeffScale);
- ChannelMap chanmap[MAX_OUTPUT_CHANNELS]{};
- for(size_t i{0u};i < conf->Speakers.size();i++)
+ ALsizei count;
+ if((conf->ChanMask&AMBI_PERIPHONIC_MASK))
{
- chanmap[i].ChanName = device->RealOut.ChannelName[speakermap[i]];
- std::fill(std::begin(chanmap[i].Config), std::end(chanmap[i].Config), 0.0f);
-
- for(ALsizei j{0},k{0};j < MAX_AMBI_COEFFS;j++)
- {
- if(!(conf->ChanMask&(1<<j)))
- continue;
- chanmap[i].Config[j] = conf->HFMatrix[i][k++] / coeff_scale[j] *
- ((j >= 9) ? conf->HFOrderGain[3] :
- (j >= 4) ? conf->HFOrderGain[2] :
- (j >= 1) ? conf->HFOrderGain[1] : conf->HFOrderGain[0]);
- }
+ count = (conf->ChanMask > AMBI_2ORDER_MASK) ? 16 :
+ (conf->ChanMask > AMBI_1ORDER_MASK) ? 9 : 4;
+ std::transform(AmbiIndex::From3D.begin(), AmbiIndex::From3D.begin()+count,
+ std::begin(device->Dry.Ambi.Map),
+ [](const ALsizei &index) noexcept { return BFChannelConfig{1.0f, index}; }
+ );
}
+ else
+ {
+ count = (conf->ChanMask > AMBI_2ORDER_MASK) ? 7 :
+ (conf->ChanMask > AMBI_1ORDER_MASK) ? 5 : 3;
+ std::transform(AmbiIndex::From2D.begin(), AmbiIndex::From2D.begin()+count,
+ std::begin(device->Dry.Ambi.Map),
+ [](const ALsizei &index) noexcept { return BFChannelConfig{1.0f, index}; }
+ );
+ }
+ device->Dry.CoeffCount = 0;
+ device->Dry.NumChannels = count;
- SetChannelMap(device->RealOut.ChannelName, device->Dry.Ambi.Coeffs, chanmap,
- conf->Speakers.size(), &device->Dry.NumChannels);
- device->Dry.CoeffCount = (conf->ChanMask > AMBI_2ORDER_MASK) ? 16 :
- (conf->ChanMask > AMBI_1ORDER_MASK) ? 9 : 4;
+ TRACE("Enabling %s-order%s ambisonic decoder\n",
+ (conf->ChanMask > AMBI_2ORDER_MASK) ? "third" :
+ (conf->ChanMask > AMBI_1ORDER_MASK) ? "second" : "first",
+ (conf->ChanMask&AMBI_PERIPHONIC_MASK) ? " periphonic" : ""
+ );
+ device->AmbiDecoder.reset(new BFormatDec{});
+ device->AmbiDecoder->reset(conf, false, count, device->Frequency, speakermap);
if(conf->ChanMask <= AMBI_1ORDER_MASK)
{
@@ -512,21 +520,28 @@ void InitCustomPanning(ALCdevice *device, const AmbDecConf *conf, const ALsizei
}
else
{
- static constexpr ALsizei count{4};
-
device->FOAOut.Ambi = AmbiConfig{};
- std::transform(AmbiIndex::From3D.begin(), AmbiIndex::From3D.begin()+count,
- std::begin(device->FOAOut.Ambi.Map),
- [](const ALsizei &index) noexcept { return BFChannelConfig{1.0f, index}; }
- );
+ if((conf->ChanMask&AMBI_PERIPHONIC_MASK))
+ {
+ count = 4;
+ std::transform(AmbiIndex::From3D.begin(), AmbiIndex::From3D.begin()+count,
+ std::begin(device->FOAOut.Ambi.Map),
+ [](const ALsizei &index) noexcept { return BFChannelConfig{1.0f, index}; }
+ );
+ }
+ else
+ {
+ count = 3;
+ std::transform(AmbiIndex::From2D.begin(), AmbiIndex::From2D.begin()+count,
+ std::begin(device->FOAOut.Ambi.Map),
+ [](const ALsizei &index) noexcept { return BFChannelConfig{1.0f, index}; }
+ );
+ }
device->FOAOut.CoeffCount = 0;
device->FOAOut.NumChannels = count;
-
- device->AmbiUp.reset(new AmbiUpsampler{});
- device->AmbiUp->reset(device);
}
- device->RealOut.NumChannels = 0;
+ device->RealOut.NumChannels = device->channelsFromFmt();
InitDistanceComp(device, conf, speakermap);
}
@@ -565,7 +580,7 @@ void InitHQPanning(ALCdevice *device, const AmbDecConf *conf, const ALsizei (&sp
(conf->ChanMask&AMBI_PERIPHONIC_MASK) ? " periphonic" : ""
);
device->AmbiDecoder.reset(new BFormatDec{});
- device->AmbiDecoder->reset(conf, count, device->Frequency, speakermap);
+ device->AmbiDecoder->reset(conf, true, count, device->Frequency, speakermap);
if(conf->ChanMask <= AMBI_1ORDER_MASK)
{