diff options
author | Sven Gothel <[email protected]> | 2023-11-28 12:51:46 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2023-11-28 12:51:46 +0100 |
commit | 1aaf4f070011490bcece50394b9b32dfa593fd9e (patch) | |
tree | 17d68284e401a35eea3d3a574d986d446a60763a /alc/panning.cpp | |
parent | 6e7cee4fa9a8af03f28ca26cd89f8357390dfc90 (diff) | |
parent | 571b546f35eead77ce109f8d4dd6c3de3199d573 (diff) |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'alc/panning.cpp')
-rw-r--r-- | alc/panning.cpp | 92 |
1 files changed, 52 insertions, 40 deletions
diff --git a/alc/panning.cpp b/alc/panning.cpp index d118f99c..b512a42a 100644 --- a/alc/panning.cpp +++ b/alc/panning.cpp @@ -32,7 +32,9 @@ #include <memory> #include <new> #include <numeric> +#include <optional> #include <string> +#include <vector> #include "AL/al.h" #include "AL/alc.h" @@ -45,7 +47,6 @@ #include "almalloc.h" #include "alnumbers.h" #include "alnumeric.h" -#include "aloptional.h" #include "alspan.h" #include "alstring.h" #include "alu.h" @@ -313,17 +314,17 @@ void InitDistanceComp(ALCdevice *device, const al::span<const Channel> channels, } -inline auto& GetAmbiScales(DevAmbiScaling scaletype) noexcept +constexpr auto GetAmbiScales(DevAmbiScaling scaletype) noexcept { - if(scaletype == DevAmbiScaling::FuMa) return AmbiScale::FromFuMa(); - if(scaletype == DevAmbiScaling::SN3D) return AmbiScale::FromSN3D(); - return AmbiScale::FromN3D(); + if(scaletype == DevAmbiScaling::FuMa) return al::span{AmbiScale::FromFuMa}; + if(scaletype == DevAmbiScaling::SN3D) return al::span{AmbiScale::FromSN3D}; + return al::span{AmbiScale::FromN3D}; } -inline auto& GetAmbiLayout(DevAmbiLayout layouttype) noexcept +constexpr auto GetAmbiLayout(DevAmbiLayout layouttype) noexcept { - if(layouttype == DevAmbiLayout::FuMa) return AmbiIndex::FromFuMa(); - return AmbiIndex::FromACN(); + if(layouttype == DevAmbiLayout::FuMa) return al::span{AmbiIndex::FromFuMa}; + return al::span{AmbiIndex::FromACN}; } @@ -346,16 +347,16 @@ DecoderView MakeDecoderView(ALCdevice *device, const AmbDecConf *conf, } std::copy_n(std::begin(conf->HFOrderGain), - std::min(al::size(conf->HFOrderGain), al::size(decoder.mOrderGain)), + std::min(std::size(conf->HFOrderGain), std::size(decoder.mOrderGain)), std::begin(decoder.mOrderGain)); std::copy_n(std::begin(conf->LFOrderGain), - std::min(al::size(conf->LFOrderGain), al::size(decoder.mOrderGainLF)), + std::min(std::size(conf->LFOrderGain), std::size(decoder.mOrderGainLF)), std::begin(decoder.mOrderGainLF)); 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 idx_map = decoder.mIs3D ? AmbiIndex::FromACN.data() + : AmbiIndex::FromACN2D.data(); const auto hfmatrix = conf->HFMatrix; const auto lfmatrix = conf->LFMatrix; @@ -600,13 +601,13 @@ void InitPanning(ALCdevice *device, const bool hqdec=false, const bool stablize= case DevFmtX714: decoder = X714Config; break; case DevFmtX3D71: decoder = X3D71Config; break; case DevFmtAmbi3D: - auto&& acnmap = GetAmbiLayout(device->mAmbiLayout); - auto&& n3dscale = GetAmbiScales(device->mAmbiScale); + const auto acnmap = GetAmbiLayout(device->mAmbiLayout); + const auto n3dscale = GetAmbiScales(device->mAmbiScale); /* For DevFmtAmbi3D, the ambisonic order is already set. */ const size_t count{AmbiChannelsFromOrder(device->mAmbiOrder)}; std::transform(acnmap.begin(), acnmap.begin()+count, std::begin(device->Dry.AmbiMap), - [&n3dscale](const uint8_t &acn) noexcept -> BFChannelConfig + [n3dscale](const uint8_t &acn) noexcept -> BFChannelConfig { return BFChannelConfig{1.0f/n3dscale[acn], acn}; }); AllocChannels(device, count, 0); device->m2DMixing = false; @@ -628,7 +629,7 @@ 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; + std::vector<ChannelDec> chancoeffs, chancoeffslf; for(size_t i{0u};i < decoder.mChannels.size();++i) { const uint idx{device->channelIdxByName(decoder.mChannels[i])}; @@ -639,8 +640,8 @@ void InitPanning(ALCdevice *device, const bool hqdec=false, const bool stablize= continue; } - auto ordermap = decoder.mIs3D ? AmbiIndex::OrderFromChannel().data() - : AmbiIndex::OrderFrom2DChannel().data(); + auto ordermap = decoder.mIs3D ? AmbiIndex::OrderFromChannel.data() + : AmbiIndex::OrderFrom2DChannel.data(); chancoeffs.resize(maxz(chancoeffs.size(), idx+1u), ChannelDec{}); al::span<const float,MaxAmbiChannels> src{decoder.mCoeffs[i]}; @@ -662,11 +663,11 @@ void InitPanning(ALCdevice *device, const bool hqdec=false, const bool stablize= device->mAmbiOrder = decoder.mOrder; device->m2DMixing = !decoder.mIs3D; - const al::span<const uint8_t> acnmap{decoder.mIs3D ? AmbiIndex::FromACN().data() : - AmbiIndex::FromACN2D().data(), ambicount}; - auto&& coeffscale = GetAmbiScales(decoder.mScaling); + const al::span<const uint8_t> acnmap{decoder.mIs3D ? AmbiIndex::FromACN.data() : + AmbiIndex::FromACN2D.data(), ambicount}; + const auto coeffscale = GetAmbiScales(decoder.mScaling); std::transform(acnmap.begin(), acnmap.end(), std::begin(device->Dry.AmbiMap), - [&coeffscale](const uint8_t &acn) noexcept + [coeffscale](const uint8_t &acn) noexcept { return BFChannelConfig{1.0f/coeffscale[acn], acn}; }); AllocChannels(device, ambicount, device->channelsFromFmt()); @@ -676,7 +677,7 @@ void InitPanning(ALCdevice *device, const bool hqdec=false, const bool stablize= /* Only enable the stablizer if the decoder does not output to the * front-center channel. */ - const auto cidx = device->RealOut.ChannelIndex[FrontCenter]; + const size_t cidx{device->RealOut.ChannelIndex[FrontCenter]}; bool hasfc{false}; if(cidx < chancoeffs.size()) { @@ -818,9 +819,9 @@ void InitHrtfPanning(ALCdevice *device) /*RMS 8.340921354e-01f, 7.182670250e-01f, 5.107426573e-01f, 2.541870634e-01f*/ }; - static_assert(al::size(AmbiPoints1O) == al::size(AmbiMatrix1O), "First-Order Ambisonic HRTF mismatch"); - static_assert(al::size(AmbiPoints2O) == al::size(AmbiMatrix2O), "Second-Order Ambisonic HRTF mismatch"); - static_assert(al::size(AmbiPoints3O) == al::size(AmbiMatrix3O), "Third-Order Ambisonic HRTF mismatch"); + static_assert(std::size(AmbiPoints1O) == std::size(AmbiMatrix1O), "First-Order Ambisonic HRTF mismatch"); + static_assert(std::size(AmbiPoints2O) == std::size(AmbiMatrix2O), "Second-Order Ambisonic HRTF mismatch"); + static_assert(std::size(AmbiPoints3O) == std::size(AmbiMatrix3O), "Third-Order Ambisonic HRTF mismatch"); /* A 700hz crossover frequency provides tighter sound imaging at the sweet * spot with ambisonic decoding, as the distance between the ears is closer @@ -901,7 +902,7 @@ void InitHrtfPanning(ALCdevice *device) device->m2DMixing = false; const size_t count{AmbiChannelsFromOrder(ambi_order)}; - std::transform(AmbiIndex::FromACN().begin(), AmbiIndex::FromACN().begin()+count, + std::transform(AmbiIndex::FromACN.begin(), AmbiIndex::FromACN.begin()+count, std::begin(device->Dry.AmbiMap), [](const uint8_t &index) noexcept { return BFChannelConfig{1.0f, index}; } ); @@ -924,16 +925,16 @@ void InitUhjPanning(ALCdevice *device) device->mAmbiOrder = 1; device->m2DMixing = true; - auto acnmap_begin = AmbiIndex::FromFuMa2D().begin(); + auto acnmap_begin = AmbiIndex::FromFuMa2D.begin(); std::transform(acnmap_begin, acnmap_begin + count, std::begin(device->Dry.AmbiMap), [](const uint8_t &acn) noexcept -> BFChannelConfig - { return BFChannelConfig{1.0f/AmbiScale::FromUHJ()[acn], acn}; }); + { return BFChannelConfig{1.0f/AmbiScale::FromUHJ[acn], acn}; }); AllocChannels(device, count, device->channelsFromFmt()); } } // namespace -void aluInitRenderer(ALCdevice *device, int hrtf_id, al::optional<StereoEncoding> stereomode) +void aluInitRenderer(ALCdevice *device, int hrtf_id, std::optional<StereoEncoding> stereomode) { /* Hold the HRTF the device last used, in case it's used again. */ HrtfStorePtr old_hrtf{std::move(device->mHrtf)}; @@ -978,28 +979,39 @@ void aluInitRenderer(ALCdevice *device, int hrtf_id, al::optional<StereoEncoding { ERR("Failed to load layout file %s\n", config); ERR(" %s\n", err->c_str()); + return false; } else if(conf.NumSpeakers > MAX_OUTPUT_CHANNELS) + { ERR("Unsupported decoder speaker count %zu (max %d)\n", conf.NumSpeakers, MAX_OUTPUT_CHANNELS); + return false; + } else if(conf.ChanMask > Ambi3OrderMask) + { ERR("Unsupported decoder channel mask 0x%04x (max 0x%x)\n", conf.ChanMask, Ambi3OrderMask); - else - { - device->mXOverFreq = clampf(conf.XOverFreq, 100.0f, 1000.0f); - - decoder_store = std::make_unique<DecoderConfig<DualBand,MAX_OUTPUT_CHANNELS>>(); - decoder = MakeDecoderView(device, &conf, *decoder_store); - for(size_t i{0};i < decoder.mChannels.size();++i) - speakerdists[i] = conf.Speakers[i].Distance; + return false; } + + TRACE("Using %s decoder: \"%s\"\n", DevFmtChannelsString(device->FmtChans), + conf.Description.c_str()); + device->mXOverFreq = clampf(conf.XOverFreq, 100.0f, 1000.0f); + + decoder_store = std::make_unique<DecoderConfig<DualBand,MAX_OUTPUT_CHANNELS>>(); + decoder = MakeDecoderView(device, &conf, *decoder_store); + for(size_t i{0};i < decoder.mChannels.size();++i) + speakerdists[i] = conf.Speakers[i].Distance; + return true; }; + bool usingCustom{false}; if(layout) { if(auto decopt = device->configValue<std::string>("decoder", layout)) - load_config(decopt->c_str()); + usingCustom = load_config(decopt->c_str()); } + if(!usingCustom && device->FmtChans != DevFmtAmbi3D) + TRACE("Using built-in %s decoder\n", DevFmtChannelsString(device->FmtChans)); /* Enable the stablizer only for formats that have front-left, front- * right, and front-center outputs. @@ -1143,7 +1155,7 @@ void aluInitEffectPanning(EffectSlot *slot, ALCcontext *context) slot->mWetBuffer.resize(count); - auto acnmap_begin = AmbiIndex::FromACN().begin(); + auto acnmap_begin = AmbiIndex::FromACN.begin(); auto iter = std::transform(acnmap_begin, acnmap_begin + count, slot->Wet.AmbiMap.begin(), [](const uint8_t &acn) noexcept -> BFChannelConfig { return BFChannelConfig{1.0f, acn}; }); |