aboutsummaryrefslogtreecommitdiffstats
path: root/alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2021-04-25 18:08:08 -0700
committerChris Robinson <[email protected]>2021-04-25 18:08:08 -0700
commit2479483645bf719233fa5d39bc91682f12d71350 (patch)
treede4d9f11e4d4549adc6e7a43b9c4a1d630f91feb /alc
parent8d09d03ed363ab1735b1933588d8242ba85ddf10 (diff)
Move bformatdec to core
Diffstat (limited to 'alc')
-rw-r--r--alc/alc.cpp4
-rw-r--r--alc/alu.cpp4
-rw-r--r--alc/bformatdec.cpp263
-rw-r--r--alc/bformatdec.h71
-rw-r--r--alc/front_stablizer.h36
-rw-r--r--alc/panning.cpp4
6 files changed, 6 insertions, 376 deletions
diff --git a/alc/alc.cpp b/alc/alc.cpp
index 8ba1c8a2..d06ca067 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -77,9 +77,9 @@
#include "alstring.h"
#include "alu.h"
#include "atomic.h"
-#include "bformatdec.h"
#include "core/ambidefs.h"
#include "core/async_event.h"
+#include "core/bformatdec.h"
#include "core/bs2b.h"
#include "core/cpu_caps.h"
#include "core/devformat.h"
@@ -89,11 +89,11 @@
#include "core/filters/nfc.h"
#include "core/filters/splitter.h"
#include "core/fpu_ctrl.h"
+#include "core/front_stablizer.h"
#include "core/hrtf.h"
#include "core/logging.h"
#include "core/uhjfilter.h"
#include "effects/base.h"
-#include "front_stablizer.h"
#include "inprogext.h"
#include "intrusive_ptr.h"
#include "opthelpers.h"
diff --git a/alc/alu.cpp b/alc/alu.cpp
index a97bc18b..14ffd8b5 100644
--- a/alc/alu.cpp
+++ b/alc/alu.cpp
@@ -51,9 +51,9 @@
#include "alspan.h"
#include "alstring.h"
#include "atomic.h"
-#include "bformatdec.h"
#include "core/ambidefs.h"
#include "core/async_event.h"
+#include "core/bformatdec.h"
#include "core/bs2b.h"
#include "core/bsinc_tables.h"
#include "core/cpu_caps.h"
@@ -62,6 +62,7 @@
#include "core/filters/nfc.h"
#include "core/filters/splitter.h"
#include "core/fpu_ctrl.h"
+#include "core/front_stablizer.h"
#include "core/hrtf.h"
#include "core/mastering.h"
#include "core/mixer.h"
@@ -69,7 +70,6 @@
#include "core/uhjfilter.h"
#include "effects/base.h"
#include "effectslot.h"
-#include "front_stablizer.h"
#include "inprogext.h"
#include "math_defs.h"
#include "opthelpers.h"
diff --git a/alc/bformatdec.cpp b/alc/bformatdec.cpp
deleted file mode 100644
index e29af045..00000000
--- a/alc/bformatdec.cpp
+++ /dev/null
@@ -1,263 +0,0 @@
-
-#include "config.h"
-
-#include "bformatdec.h"
-
-#include <algorithm>
-#include <array>
-#include <cmath>
-#include <utility>
-
-#include "almalloc.h"
-#include "core/ambdec.h"
-#include "core/filters/splitter.h"
-#include "core/mixer.h"
-#include "front_stablizer.h"
-#include "math_defs.h"
-#include "opthelpers.h"
-
-
-namespace {
-
-inline auto& GetAmbiScales(AmbDecScale scaletype) noexcept
-{
- if(scaletype == AmbDecScale::FuMa) return AmbiScale::FromFuMa();
- if(scaletype == AmbDecScale::SN3D) return AmbiScale::FromSN3D();
- return AmbiScale::FromN3D();
-}
-
-} // namespace
-
-
-BFormatDec::BFormatDec(const AmbDecConf *conf, const bool allow_2band, const size_t inchans,
- const uint srate, const uint (&chanmap)[MAX_OUTPUT_CHANNELS],
- std::unique_ptr<FrontStablizer> stablizer)
- : mStablizer{std::move(stablizer)}, mDualBand{allow_2band && (conf->FreqBands == 2)}
- , mChannelDec{inchans}
-{
- const bool periphonic{(conf->ChanMask&AmbiPeriphonicMask) != 0};
- auto&& coeff_scale = GetAmbiScales(conf->CoeffScale);
-
- if(!mDualBand)
- {
- for(size_t j{0},k{0};j < mChannelDec.size();++j)
- {
- const size_t acn{periphonic ? j : AmbiIndex::FromACN2D()[j]};
- if(!(conf->ChanMask&(1u<<acn))) continue;
- const size_t order{AmbiIndex::OrderFromChannel()[acn]};
- const float gain{conf->HFOrderGain[order] / coeff_scale[acn]};
- for(size_t i{0u};i < conf->NumSpeakers;++i)
- {
- const size_t chanidx{chanmap[i]};
- mChannelDec[j].mGains.Single[chanidx] = conf->Matrix[i][k] * gain;
- }
- ++k;
- }
- }
- else
- {
- mChannelDec[0].mXOver.init(conf->XOverFreq / static_cast<float>(srate));
- for(size_t j{1};j < mChannelDec.size();++j)
- mChannelDec[j].mXOver = mChannelDec[0].mXOver;
-
- const float ratio{std::pow(10.0f, conf->XOverRatio / 40.0f)};
- for(size_t j{0},k{0};j < mChannelDec.size();++j)
- {
- const size_t acn{periphonic ? j : AmbiIndex::FromACN2D()[j]};
- if(!(conf->ChanMask&(1u<<acn))) continue;
- const size_t order{AmbiIndex::OrderFromChannel()[acn]};
- const float hfGain{conf->HFOrderGain[order] * ratio / coeff_scale[acn]};
- const float lfGain{conf->LFOrderGain[order] / ratio / coeff_scale[acn]};
- for(size_t i{0u};i < conf->NumSpeakers;++i)
- {
- const size_t chanidx{chanmap[i]};
- mChannelDec[j].mGains.Dual[sHFBand][chanidx] = conf->HFMatrix[i][k] * hfGain;
- mChannelDec[j].mGains.Dual[sLFBand][chanidx] = conf->LFMatrix[i][k] * lfGain;
- }
- ++k;
- }
- }
-}
-
-BFormatDec::BFormatDec(const size_t inchans, const al::span<const ChannelDec> coeffs,
- const al::span<const ChannelDec> coeffslf, std::unique_ptr<FrontStablizer> stablizer)
- : mStablizer{std::move(stablizer)}, mDualBand{!coeffslf.empty()}, mChannelDec{inchans}
-{
- if(!mDualBand)
- {
- for(size_t j{0};j < mChannelDec.size();++j)
- {
- float *outcoeffs{mChannelDec[j].mGains.Single};
- for(const ChannelDec &incoeffs : coeffs)
- *(outcoeffs++) = incoeffs[j];
- }
- }
- else
- {
- for(size_t j{0};j < mChannelDec.size();++j)
- {
- float *outcoeffs{mChannelDec[j].mGains.Dual[sHFBand]};
- for(const ChannelDec &incoeffs : coeffs)
- *(outcoeffs++) = incoeffs[j];
-
- outcoeffs = mChannelDec[j].mGains.Dual[sLFBand];
- for(const ChannelDec &incoeffs : coeffslf)
- *(outcoeffs++) = incoeffs[j];
- }
- }
-}
-
-
-void BFormatDec::process(const al::span<FloatBufferLine> OutBuffer,
- const FloatBufferLine *InSamples, const size_t SamplesToDo)
-{
- ASSUME(SamplesToDo > 0);
-
- if(mDualBand)
- {
- const al::span<float> hfSamples{mSamples[sHFBand].data(), SamplesToDo};
- const al::span<float> lfSamples{mSamples[sLFBand].data(), SamplesToDo};
- for(auto &chandec : mChannelDec)
- {
- chandec.mXOver.process({InSamples->data(), SamplesToDo}, hfSamples.data(),
- lfSamples.data());
- MixSamples(hfSamples, OutBuffer, chandec.mGains.Dual[sHFBand],
- chandec.mGains.Dual[sHFBand], 0, 0);
- MixSamples(lfSamples, OutBuffer, chandec.mGains.Dual[sLFBand],
- chandec.mGains.Dual[sLFBand], 0, 0);
- ++InSamples;
- }
- }
- else
- {
- for(auto &chandec : mChannelDec)
- {
- MixSamples({InSamples->data(), SamplesToDo}, OutBuffer, chandec.mGains.Single,
- chandec.mGains.Single, 0, 0);
- ++InSamples;
- }
- }
-}
-
-void BFormatDec::processStablize(const al::span<FloatBufferLine> OutBuffer,
- const FloatBufferLine *InSamples, const size_t lidx, const size_t ridx, const size_t cidx,
- const size_t SamplesToDo)
-{
- ASSUME(SamplesToDo > 0);
-
- /* Move the existing direct L/R signal out so it doesn't get processed by
- * the stablizer. Add a delay to it so it stays aligned with the stablizer
- * delay.
- */
- float *RESTRICT mid{al::assume_aligned<16>(mStablizer->MidDirect.data())};
- float *RESTRICT side{al::assume_aligned<16>(mStablizer->Side.data())};
- for(size_t i{0};i < SamplesToDo;++i)
- {
- mid[FrontStablizer::DelayLength+i] = OutBuffer[lidx][i] + OutBuffer[ridx][i];
- side[FrontStablizer::DelayLength+i] = OutBuffer[lidx][i] - OutBuffer[ridx][i];
- }
- std::fill_n(OutBuffer[lidx].begin(), SamplesToDo, 0.0f);
- std::fill_n(OutBuffer[ridx].begin(), SamplesToDo, 0.0f);
-
- /* Decode the B-Format input to OutBuffer. */
- process(OutBuffer, InSamples, SamplesToDo);
-
- /* Apply a delay to all channels, except the front-left and front-right, so
- * they maintain correct timing.
- */
- const size_t NumChannels{OutBuffer.size()};
- for(size_t i{0u};i < NumChannels;i++)
- {
- if(i == lidx || i == ridx)
- continue;
-
- auto &DelayBuf = mStablizer->DelayBuf[i];
- auto buffer_end = OutBuffer[i].begin() + SamplesToDo;
- if LIKELY(SamplesToDo >= FrontStablizer::DelayLength)
- {
- auto delay_end = std::rotate(OutBuffer[i].begin(),
- buffer_end - FrontStablizer::DelayLength, buffer_end);
- std::swap_ranges(OutBuffer[i].begin(), delay_end, DelayBuf.begin());
- }
- else
- {
- auto delay_start = std::swap_ranges(OutBuffer[i].begin(), buffer_end,
- DelayBuf.begin());
- std::rotate(DelayBuf.begin(), delay_start, DelayBuf.end());
- }
- }
-
- /* Include the side signal for what was just decoded. */
- for(size_t i{0};i < SamplesToDo;++i)
- side[FrontStablizer::DelayLength+i] += OutBuffer[lidx][i] - OutBuffer[ridx][i];
-
- /* Combine the delayed mid signal with the decoded mid signal. Note that
- * the samples are stored and combined in reverse, so the newest samples
- * are at the front and the oldest at the back.
- */
- al::span<float> tmpbuf{mStablizer->TempBuf.data(), SamplesToDo+FrontStablizer::DelayLength};
- auto tmpiter = tmpbuf.begin() + SamplesToDo;
- std::copy(mStablizer->MidDelay.cbegin(), mStablizer->MidDelay.cend(), tmpiter);
- for(size_t i{0};i < SamplesToDo;++i)
- *--tmpiter = OutBuffer[lidx][i] + OutBuffer[ridx][i];
- /* Save the newest samples for next time. */
- std::copy_n(tmpbuf.cbegin(), mStablizer->MidDelay.size(), mStablizer->MidDelay.begin());
-
- /* Apply an all-pass on the reversed signal, then reverse the samples to
- * get the forward signal with a reversed phase shift. The future samples
- * are included with the all-pass to reduce the error in the output
- * samples (the smaller the delay, the more error is introduced).
- */
- mStablizer->MidFilter.applyAllpass(tmpbuf);
- tmpbuf = tmpbuf.subspan<FrontStablizer::DelayLength>();
- std::reverse(tmpbuf.begin(), tmpbuf.end());
-
- /* Now apply the band-splitter, combining its phase shift with the reversed
- * phase shift, restoring the original phase on the split signal.
- */
- mStablizer->MidFilter.process(tmpbuf, mStablizer->MidHF.data(), mStablizer->MidLF.data());
-
- /* This pans the separate low- and high-frequency signals between being on
- * the center channel and the left+right channels. The low-frequency signal
- * is panned 1/3rd toward center and the high-frequency signal is panned
- * 1/4th toward center. These values can be tweaked.
- */
- const float cos_lf{std::cos(1.0f/3.0f * (al::MathDefs<float>::Pi()*0.5f))};
- const float cos_hf{std::cos(1.0f/4.0f * (al::MathDefs<float>::Pi()*0.5f))};
- const float sin_lf{std::sin(1.0f/3.0f * (al::MathDefs<float>::Pi()*0.5f))};
- const float sin_hf{std::sin(1.0f/4.0f * (al::MathDefs<float>::Pi()*0.5f))};
- for(size_t i{0};i < SamplesToDo;i++)
- {
- const float m{mStablizer->MidLF[i]*cos_lf + mStablizer->MidHF[i]*cos_hf + mid[i]};
- const float c{mStablizer->MidLF[i]*sin_lf + mStablizer->MidHF[i]*sin_hf};
- const float s{side[i]};
-
- /* The generated center channel signal adds to the existing signal,
- * while the modified left and right channels replace.
- */
- OutBuffer[lidx][i] = (m + s) * 0.5f;
- OutBuffer[ridx][i] = (m - s) * 0.5f;
- OutBuffer[cidx][i] += c * 0.5f;
- }
- /* Move the delayed mid/side samples to the front for next time. */
- auto mid_end = mStablizer->MidDirect.cbegin() + SamplesToDo;
- std::copy(mid_end, mid_end+FrontStablizer::DelayLength, mStablizer->MidDirect.begin());
- auto side_end = mStablizer->Side.cbegin() + SamplesToDo;
- std::copy(side_end, side_end+FrontStablizer::DelayLength, mStablizer->Side.begin());
-}
-
-
-std::unique_ptr<BFormatDec> BFormatDec::Create(const AmbDecConf *conf, const bool allow_2band,
- const size_t inchans, const uint srate, const uint (&chanmap)[MAX_OUTPUT_CHANNELS],
- std::unique_ptr<FrontStablizer> stablizer)
-{
- return std::unique_ptr<BFormatDec>{new(FamCount(inchans))
- BFormatDec{conf, allow_2band, inchans, srate, chanmap, std::move(stablizer)}};
-}
-std::unique_ptr<BFormatDec> BFormatDec::Create(const size_t inchans,
- const al::span<const ChannelDec> coeffs, const al::span<const ChannelDec> coeffslf,
- std::unique_ptr<FrontStablizer> stablizer)
-{
- return std::unique_ptr<BFormatDec>{new(FamCount(inchans))
- BFormatDec{inchans, coeffs, coeffslf, std::move(stablizer)}};
-}
diff --git a/alc/bformatdec.h b/alc/bformatdec.h
deleted file mode 100644
index bb39f709..00000000
--- a/alc/bformatdec.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef BFORMATDEC_H
-#define BFORMATDEC_H
-
-#include <array>
-#include <cstddef>
-#include <memory>
-
-#include "almalloc.h"
-#include "alspan.h"
-#include "core/ambidefs.h"
-#include "core/bufferline.h"
-#include "core/devformat.h"
-#include "core/filters/splitter.h"
-
-struct AmbDecConf;
-struct FrontStablizer;
-
-
-using ChannelDec = std::array<float,MaxAmbiChannels>;
-
-class BFormatDec {
- static constexpr size_t sHFBand{0};
- static constexpr size_t sLFBand{1};
- static constexpr size_t sNumBands{2};
-
- struct ChannelDecoder {
- union MatrixU {
- float Dual[sNumBands][MAX_OUTPUT_CHANNELS];
- float Single[MAX_OUTPUT_CHANNELS];
- } mGains{};
-
- /* NOTE: BandSplitter filter is unused with single-band decoding. */
- BandSplitter mXOver;
- };
-
- alignas(16) std::array<FloatBufferLine,2> mSamples;
-
- const std::unique_ptr<FrontStablizer> mStablizer;
- const bool mDualBand{false};
-
- al::FlexArray<ChannelDecoder> mChannelDec;
-
-public:
- BFormatDec(const AmbDecConf *conf, const bool allow_2band, const size_t inchans,
- const uint srate, const uint (&chanmap)[MAX_OUTPUT_CHANNELS],
- std::unique_ptr<FrontStablizer> stablizer);
- BFormatDec(const size_t inchans, const al::span<const ChannelDec> coeffs,
- const al::span<const ChannelDec> coeffslf, std::unique_ptr<FrontStablizer> stablizer);
-
- bool hasStablizer() const noexcept { return mStablizer != nullptr; };
-
- /* Decodes the ambisonic input to the given output channels. */
- void process(const al::span<FloatBufferLine> OutBuffer, const FloatBufferLine *InSamples,
- const size_t SamplesToDo);
-
- /* Decodes the ambisonic input to the given output channels with stablization. */
- void processStablize(const al::span<FloatBufferLine> OutBuffer,
- const FloatBufferLine *InSamples, const size_t lidx, const size_t ridx, const size_t cidx,
- const size_t SamplesToDo);
-
- static std::unique_ptr<BFormatDec> Create(const AmbDecConf *conf, const bool allow_2band,
- const size_t inchans, const uint srate, const uint (&chanmap)[MAX_OUTPUT_CHANNELS],
- std::unique_ptr<FrontStablizer> stablizer);
- static std::unique_ptr<BFormatDec> Create(const size_t inchans,
- const al::span<const ChannelDec> coeffs, const al::span<const ChannelDec> coeffslf,
- std::unique_ptr<FrontStablizer> stablizer);
-
- DEF_FAM_NEWDEL(BFormatDec, mChannelDec)
-};
-
-#endif /* BFORMATDEC_H */
diff --git a/alc/front_stablizer.h b/alc/front_stablizer.h
deleted file mode 100644
index 0fedeb50..00000000
--- a/alc/front_stablizer.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef ALC_FRONT_STABLIZER_H
-#define ALC_FRONT_STABLIZER_H
-
-#include <array>
-#include <memory>
-
-#include "almalloc.h"
-#include "core/bufferline.h"
-#include "core/filters/splitter.h"
-
-
-struct FrontStablizer {
- static constexpr size_t DelayLength{256u};
-
- FrontStablizer(size_t numchans) : DelayBuf{numchans} { }
-
- alignas(16) std::array<float,BufferLineSize + DelayLength> Side{};
- alignas(16) std::array<float,BufferLineSize + DelayLength> MidDirect{};
- alignas(16) std::array<float,DelayLength> MidDelay{};
-
- alignas(16) std::array<float,BufferLineSize + DelayLength> TempBuf{};
-
- BandSplitter MidFilter;
- alignas(16) FloatBufferLine MidLF{};
- alignas(16) FloatBufferLine MidHF{};
-
- using DelayLine = std::array<float,DelayLength>;
- al::FlexArray<DelayLine,16> DelayBuf;
-
- static std::unique_ptr<FrontStablizer> Create(size_t numchans)
- { return std::unique_ptr<FrontStablizer>{new(FamCount(numchans)) FrontStablizer{numchans}}; }
-
- DEF_FAM_NEWDEL(FrontStablizer, DelayBuf)
-};
-
-#endif /* ALC_FRONT_STABLIZER_H */
diff --git a/alc/panning.cpp b/alc/panning.cpp
index ce6ba29c..5e263111 100644
--- a/alc/panning.cpp
+++ b/alc/panning.cpp
@@ -47,15 +47,15 @@
#include "alspan.h"
#include "alstring.h"
#include "alu.h"
-#include "bformatdec.h"
#include "core/ambdec.h"
#include "core/ambidefs.h"
+#include "core/bformatdec.h"
#include "core/bs2b.h"
#include "core/devformat.h"
+#include "core/front_stablizer.h"
#include "core/hrtf.h"
#include "core/logging.h"
#include "core/uhjfilter.h"
-#include "front_stablizer.h"
#include "math_defs.h"
#include "opthelpers.h"