aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--alc/bformatdec.cpp80
-rw-r--r--alc/bformatdec.h16
2 files changed, 31 insertions, 65 deletions
diff --git a/alc/bformatdec.cpp b/alc/bformatdec.cpp
index 0272139d..3001bfb4 100644
--- a/alc/bformatdec.cpp
+++ b/alc/bformatdec.cpp
@@ -53,35 +53,21 @@ BFormatDec::BFormatDec(const AmbDecConf *conf, const bool allow_2band, const ALu
const ALuint srate, const ALuint (&chanmap)[MAX_OUTPUT_CHANNELS])
{
mDualBand = allow_2band && (conf->FreqBands == 2);
- if(!mDualBand)
- mSamples.resize(2);
- else
- {
- ASSUME(inchans > 0);
- 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 ALuint &chan) noexcept -> ALuint
- { return mask | (1 << chan); });
-
const bool periphonic{(conf->ChanMask&AMBI_PERIPHONIC_MASK) != 0};
const std::array<float,MAX_AMBI_CHANNELS> &coeff_scale = GetAmbiScales(conf->CoeffScale);
- const size_t coeff_count{periphonic ? MAX_AMBI_CHANNELS : MAX_AMBI2D_CHANNELS};
if(!mDualBand)
{
for(size_t i{0u};i < conf->Speakers.size();i++)
{
- ALfloat (&mtx)[MAX_AMBI_CHANNELS] = mMatrix.Single[chanmap[i]];
- for(size_t j{0},k{0};j < coeff_count;j++)
+ const size_t chanidx{chanmap[i]};
+ for(size_t j{0},k{0};j < mNumChannels;j++)
{
const size_t acn{periphonic ? j : AmbiIndex::From2D[j]};
if(!(conf->ChanMask&(1u<<acn))) continue;
- mtx[j] = conf->HFMatrix[i][k] / coeff_scale[acn] *
+ mMatrix.Single[j][chanidx] = conf->HFMatrix[i][k] / coeff_scale[acn] *
conf->HFOrderGain[AmbiIndex::OrderFromChannel[acn]];
++k;
}
@@ -95,14 +81,14 @@ BFormatDec::BFormatDec(const AmbDecConf *conf, const bool allow_2band, const ALu
const float ratio{std::pow(10.0f, conf->XOverRatio / 40.0f)};
for(size_t i{0u};i < conf->Speakers.size();i++)
{
- ALfloat (&mtx)[sNumBands][MAX_AMBI_CHANNELS] = mMatrix.Dual[chanmap[i]];
- for(size_t j{0},k{0};j < coeff_count;j++)
+ const size_t chanidx{chanmap[i]};
+ for(size_t j{0},k{0};j < mNumChannels;j++)
{
const size_t acn{periphonic ? j : AmbiIndex::From2D[j]};
if(!(conf->ChanMask&(1u<<acn))) continue;
- mtx[sHFBand][j] = conf->HFMatrix[i][k] / coeff_scale[acn] *
+ mMatrix.Dual[j][sHFBand][chanidx] = conf->HFMatrix[i][k] / coeff_scale[acn] *
conf->HFOrderGain[AmbiIndex::OrderFromChannel[acn]] * ratio;
- mtx[sLFBand][j] = conf->LFMatrix[i][k] / coeff_scale[acn] *
+ mMatrix.Dual[j][sLFBand][chanidx] = conf->LFMatrix[i][k] / coeff_scale[acn] *
conf->LFOrderGain[AmbiIndex::OrderFromChannel[acn]] / ratio;
++k;
}
@@ -113,21 +99,16 @@ BFormatDec::BFormatDec(const AmbDecConf *conf, const bool allow_2band, const ALu
BFormatDec::BFormatDec(const ALuint inchans, const ChannelDec (&chancoeffs)[MAX_OUTPUT_CHANNELS],
const al::span<const ALuint> chanmap)
{
- mSamples.resize(2);
mNumChannels = inchans;
- mEnabled = std::accumulate(chanmap.begin(), chanmap.end(), 0u,
- [](ALuint mask, const ALuint &chan) noexcept -> ALuint
- { return mask | (1 << chan); });
-
const ChannelDec *incoeffs{chancoeffs};
auto set_coeffs = [this,inchans,&incoeffs](const ALuint chanidx) noexcept -> void
{
- ALfloat (&mtx)[MAX_AMBI_CHANNELS] = mMatrix.Single[chanidx];
- const ALfloat (&coeffs)[MAX_AMBI_CHANNELS] = *(incoeffs++);
+ const float (&coeffs)[MAX_AMBI_CHANNELS] = *(incoeffs++);
ASSUME(inchans > 0);
- std::copy_n(std::begin(coeffs), inchans, std::begin(mtx));
+ for(size_t j{0};j < inchans;++j)
+ mMatrix.Single[j][chanidx] = coeffs[j];
};
std::for_each(chanmap.begin(), chanmap.end(), set_coeffs);
}
@@ -140,38 +121,25 @@ void BFormatDec::process(const al::span<FloatBufferLine> OutBuffer,
if(mDualBand)
{
- for(ALuint i{0};i < mNumChannels;i++)
- mXOver[i].process({InSamples[i].data(), SamplesToDo}, mSamplesHF[i].data(),
- mSamplesLF[i].data());
-
- ALfloat (*mixmtx)[sNumBands][MAX_AMBI_CHANNELS]{mMatrix.Dual};
- ALuint enabled{mEnabled};
- for(FloatBufferLine &outbuf : OutBuffer)
+ const al::span<const float> hfSamples{mSamples[sHFBand].data(), SamplesToDo};
+ const al::span<const float> lfSamples{mSamples[sLFBand].data(), SamplesToDo};
+ const size_t numchans{mNumChannels};
+ for(size_t i{0};i < numchans;i++)
{
- if LIKELY(enabled&1)
- {
- const al::span<float> outspan{outbuf.data(), SamplesToDo};
- MixRowSamples(outspan, {(*mixmtx)[sHFBand], mNumChannels}, mSamplesHF->data(),
- mSamplesHF->size());
- MixRowSamples(outspan, {(*mixmtx)[sLFBand], mNumChannels}, mSamplesLF->data(),
- mSamplesLF->size());
- }
- ++mixmtx;
- enabled >>= 1;
+ mXOver[i].process({InSamples[i].data(), SamplesToDo}, mSamples[sHFBand].data(),
+ mSamples[sLFBand].data());
+ MixSamples(hfSamples, OutBuffer, mMatrix.Dual[i][sHFBand], mMatrix.Dual[i][sHFBand],
+ 0, 0);
+ MixSamples(lfSamples, OutBuffer, mMatrix.Dual[i][sLFBand], mMatrix.Dual[i][sLFBand],
+ 0, 0);
}
}
else
{
- ALfloat (*mixmtx)[MAX_AMBI_CHANNELS]{mMatrix.Single};
- ALuint enabled{mEnabled};
- for(FloatBufferLine &outbuf : OutBuffer)
- {
- if LIKELY(enabled&1)
- MixRowSamples({outbuf.data(), SamplesToDo}, {*mixmtx, mNumChannels},
- InSamples->data(), InSamples->size());
- ++mixmtx;
- enabled >>= 1;
- }
+ const size_t numchans{mNumChannels};
+ for(size_t i{0};i < numchans;i++)
+ MixSamples({InSamples[i].data(), SamplesToDo}, OutBuffer, mMatrix.Single[i],
+ mMatrix.Single[i], 0, 0);
}
}
diff --git a/alc/bformatdec.h b/alc/bformatdec.h
index bf48a05f..fe4b8263 100644
--- a/alc/bformatdec.h
+++ b/alc/bformatdec.h
@@ -17,7 +17,7 @@
struct AmbDecConf;
-using ChannelDec = ALfloat[MAX_AMBI_CHANNELS];
+using ChannelDec = float[MAX_AMBI_CHANNELS];
class BFormatDec {
static constexpr size_t sHFBand{0};
@@ -25,21 +25,19 @@ class BFormatDec {
static constexpr size_t sNumBands{2};
bool mDualBand{false};
- ALuint mEnabled{0u}; /* Bitfield of enabled channels. */
ALuint mNumChannels{0u};
union MatrixU {
- ALfloat Dual[MAX_OUTPUT_CHANNELS][sNumBands][MAX_AMBI_CHANNELS];
- ALfloat Single[MAX_OUTPUT_CHANNELS][MAX_AMBI_CHANNELS];
+ float Dual[MAX_AMBI_CHANNELS][sNumBands][MAX_OUTPUT_CHANNELS];
+ float Single[MAX_AMBI_CHANNELS][MAX_OUTPUT_CHANNELS];
} mMatrix{};
- /* NOTE: BandSplitter filters are unused with single-band decoding */
+ /* NOTE: BandSplitter filters and temp samples are unused with single-band
+ * decoding.
+ */
BandSplitter mXOver[MAX_AMBI_CHANNELS];
- al::vector<FloatBufferLine, 16> mSamples;
- /* These two alias into Samples */
- FloatBufferLine *mSamplesHF{nullptr};
- FloatBufferLine *mSamplesLF{nullptr};
+ alignas(16) std::array<FloatBufferLine,2> mSamples;
public:
BFormatDec(const AmbDecConf *conf, const bool allow_2band, const ALuint inchans,