aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2022-09-12 02:49:21 -0700
committerChris Robinson <[email protected]>2022-09-12 02:49:21 -0700
commit2d49920e7a2069ea6f0b4529f59286f8955d145f (patch)
tree40174f7b01d320b74ef0a75cb58ad5c3a6b64b67
parentc027ef7bf7acb590f20ce8edd51c8db254f3b651 (diff)
Don't pack ambdec coefficients
Tne coefficients are placed as for full 3D ACN handling. The ChanMask just indicates which have potentially useful values. This could be a bit more agressive and clear ChanMask bits for channels that don't contribute to output, so that a decoder the specifies height-related channel bits, but leaves their coefficients all 0, can be handled as 2D. I don't expect many ambdec files to be like that, though.
-rw-r--r--alc/panning.cpp86
-rw-r--r--core/ambdec.cpp7
2 files changed, 25 insertions, 68 deletions
diff --git a/alc/panning.cpp b/alc/panning.cpp
index 6826b539..e36de17b 100644
--- a/alc/panning.cpp
+++ b/alc/panning.cpp
@@ -351,44 +351,10 @@ DecoderView MakeDecoderView(ALCdevice *device, const AmbDecConf *conf,
std::min(al::size(conf->LFOrderGain), al::size(decoder.mOrderGainLF)),
std::begin(decoder.mOrderGainLF));
- std::array<uint8_t,MaxAmbiChannels> idx_map{};
- if(decoder.mIs3D)
- {
- uint flags{conf->ChanMask};
- auto elem = idx_map.begin();
- while(flags)
- {
- int acn{al::countr_zero(flags)};
- flags &= ~(1u<<acn);
-
- *elem = static_cast<uint8_t>(acn);
- ++elem;
- }
- }
- else
- {
- uint flags{conf->ChanMask};
- auto elem = idx_map.begin();
- while(flags)
- {
- int acn{al::countr_zero(flags)};
- flags &= ~(1u<<acn);
-
- switch(acn)
- {
- case 0: *elem = 0; break;
- case 1: *elem = 1; break;
- case 3: *elem = 2; break;
- case 4: *elem = 3; break;
- case 8: *elem = 4; break;
- case 9: *elem = 5; break;
- case 15: *elem = 6; break;
- default: return ret;
- }
- ++elem;
- }
- }
- const auto num_coeffs = static_cast<uint>(al::popcount(conf->ChanMask));
+ const auto num_coeffs = decoder.mIs3D ? AmbiChannelsFromOrder(decoder.mOrder)
+ : Ambi2DChannelsFromOrder(decoder.mOrder);
+ const auto idx_map = decoder.mIs3D ? AmbiIndex::FromACN().data()
+ : AmbiIndex::FromACN2D().data();
const auto hfmatrix = conf->HFMatrix;
const auto lfmatrix = conf->LFMatrix;
@@ -445,16 +411,16 @@ DecoderView MakeDecoderView(ALCdevice *device, const AmbDecConf *conf,
}
decoder.mChannels[chan_count] = ch;
- for(size_t src{0};src < num_coeffs;++src)
+ for(size_t dst{0};dst < num_coeffs;++dst)
{
- const size_t dst{idx_map[src]};
+ const size_t src{idx_map[dst]};
decoder.mCoeffs[chan_count][dst] = hfmatrix[chan_count][src];
}
if(conf->FreqBands > 1)
{
- for(size_t src{0};src < num_coeffs;++src)
+ for(size_t dst{0};dst < num_coeffs;++dst)
{
- const size_t dst{idx_map[src]};
+ const size_t src{idx_map[dst]};
decoder.mCoeffsLF[chan_count][dst] = lfmatrix[chan_count][src];
}
}
@@ -628,6 +594,8 @@ void InitPanning(ALCdevice *device, const bool hqdec=false, const bool stablize=
}
}
+ const size_t ambicount{decoder.mIs3D ? AmbiChannelsFromOrder(decoder.mOrder) :
+ Ambi2DChannelsFromOrder(decoder.mOrder)};
const bool dual_band{hqdec && !decoder.mCoeffsLF.empty()};
al::vector<ChannelDec> chancoeffs, chancoeffslf;
for(size_t i{0u};i < decoder.mChannels.size();++i)
@@ -640,39 +608,29 @@ void InitPanning(ALCdevice *device, const bool hqdec=false, const bool stablize=
continue;
}
+ auto ordermap = decoder.mIs3D ? AmbiIndex::OrderFromChannel().data()
+ : AmbiIndex::OrderFrom2DChannel().data();
+
chancoeffs.resize(maxz(chancoeffs.size(), idx+1u), ChannelDec{});
- al::span<float,MaxAmbiChannels> coeffs{chancoeffs[idx]};
- size_t ambichan{0};
- for(uint o{0};o < decoder.mOrder+1u;++o)
- {
- const float order_gain{decoder.mOrderGain[o]};
- const size_t order_max{decoder.mIs3D ? AmbiChannelsFromOrder(o) :
- Ambi2DChannelsFromOrder(o)};
- for(;ambichan < order_max;++ambichan)
- coeffs[ambichan] = decoder.mCoeffs[i][ambichan] * order_gain;
- }
+ al::span<const float,MaxAmbiChannels> src{decoder.mCoeffs[i]};
+ al::span<float,MaxAmbiChannels> dst{chancoeffs[idx]};
+ for(size_t ambichan{0};ambichan < ambicount;++ambichan)
+ dst[ambichan] = src[ambichan] * decoder.mOrderGain[ordermap[ambichan]];
+
if(!dual_band)
continue;
chancoeffslf.resize(maxz(chancoeffslf.size(), idx+1u), ChannelDec{});
- coeffs = chancoeffslf[idx];
- ambichan = 0;
- for(uint o{0};o < decoder.mOrder+1u;++o)
- {
- const float order_gain{decoder.mOrderGainLF[o]};
- const size_t order_max{decoder.mIs3D ? AmbiChannelsFromOrder(o) :
- Ambi2DChannelsFromOrder(o)};
- for(;ambichan < order_max;++ambichan)
- coeffs[ambichan] = decoder.mCoeffsLF[i][ambichan] * order_gain;
- }
+ src = decoder.mCoeffsLF[i];
+ dst = chancoeffslf[idx];
+ for(size_t ambichan{0};ambichan < ambicount;++ambichan)
+ dst[ambichan] = src[ambichan] * decoder.mOrderGainLF[ordermap[ambichan]];
}
/* For non-DevFmtAmbi3D, set the ambisonic order. */
device->mAmbiOrder = decoder.mOrder;
device->m2DMixing = !decoder.mIs3D;
- const size_t ambicount{decoder.mIs3D ? AmbiChannelsFromOrder(decoder.mOrder) :
- Ambi2DChannelsFromOrder(decoder.mOrder)};
const al::span<const uint8_t> acnmap{decoder.mIs3D ? AmbiIndex::FromACN().data() :
AmbiIndex::FromACN2D().data(), ambicount};
auto&& coeffscale = GetAmbiScales(decoder.mScaling);
diff --git a/core/ambdec.cpp b/core/ambdec.cpp
index fcaf0388..4e4c7e1e 100644
--- a/core/ambdec.cpp
+++ b/core/ambdec.cpp
@@ -153,16 +153,15 @@ al::optional<std::string> AmbDecConf::load(const char *fname) noexcept
AmbDecConf::CoeffArray &mtxrow = matrix[pos++];
mtxrow.fill(0.0f);
- std::size_t curidx{0u};
float value{};
while(mask)
{
- auto idx = al::countr_zero(mask);
+ auto idx = static_cast<unsigned>(al::countr_zero(mask));
mask &= ~(1u << idx);
istr >> value;
- if(curidx < mtxrow.size())
- mtxrow[curidx++] = value;
+ if(idx < mtxrow.size())
+ mtxrow[idx] = value;
}
}
else