diff options
-rw-r--r-- | Alc/bformatdec.cpp | 68 | ||||
-rw-r--r-- | Alc/bformatdec.h | 7 | ||||
-rw-r--r-- | Alc/panning.cpp | 207 |
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) { |