aboutsummaryrefslogtreecommitdiffstats
path: root/alc/panning.cpp
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2023-11-28 12:51:46 +0100
committerSven Gothel <[email protected]>2023-11-28 12:51:46 +0100
commit1aaf4f070011490bcece50394b9b32dfa593fd9e (patch)
tree17d68284e401a35eea3d3a574d986d446a60763a /alc/panning.cpp
parent6e7cee4fa9a8af03f28ca26cd89f8357390dfc90 (diff)
parent571b546f35eead77ce109f8d4dd6c3de3199d573 (diff)
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'alc/panning.cpp')
-rw-r--r--alc/panning.cpp92
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}; });