From 3b3d3d3a03c3f39e758b3b9b41649b86314eb413 Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Wed, 25 Dec 2019 21:48:58 -0800
Subject: Use a span for the band-splitter input

---
 alc/alu.cpp              | 19 +++++++++----------
 alc/bformatdec.cpp       |  4 ++--
 alc/effects/reverb.cpp   |  4 ++--
 alc/filters/splitter.cpp | 22 +++++++++-------------
 alc/filters/splitter.h   |  8 +++++---
 alc/hrtf.cpp             | 21 +++++++++++----------
 alc/voice.cpp            |  6 +++---
 7 files changed, 41 insertions(+), 43 deletions(-)

(limited to 'alc')

diff --git a/alc/alu.cpp b/alc/alu.cpp
index 560903a1..da1d72b9 100644
--- a/alc/alu.cpp
+++ b/alc/alu.cpp
@@ -1712,13 +1712,13 @@ void ApplyStablizer(FrontStablizer *Stablizer, const al::span<FloatBufferLine> B
 
     ALfloat (&lsplit)[2][BUFFERSIZE] = Stablizer->LSplit;
     ALfloat (&rsplit)[2][BUFFERSIZE] = Stablizer->RSplit;
-    auto &tmpbuf = Stablizer->TempBuf;
+    const al::span<float> tmpbuf{Stablizer->TempBuf, SamplesToDo+FrontStablizer::DelayLength};
 
     /* This applies the band-splitter, preserving phase at the cost of some
      * delay. The shorter the delay, the more error seeps into the result.
      */
-    auto apply_splitter = [&tmpbuf,SamplesToDo](const FloatBufferLine &InBuf,
-        ALfloat (&DelayBuf)[FrontStablizer::DelayLength], BandSplitter &Filter,
+    auto apply_splitter = [tmpbuf,SamplesToDo](const FloatBufferLine &InBuf,
+        const al::span<float,FrontStablizer::DelayLength> DelayBuf, BandSplitter &Filter,
         ALfloat (&splitbuf)[2][BUFFERSIZE]) -> void
     {
         /* Combine the delayed samples and the input samples into the temp
@@ -1726,22 +1726,21 @@ void ApplyStablizer(FrontStablizer *Stablizer, const al::span<FloatBufferLine> B
          * buffer for next time. Note that the delay buffer's samples are
          * stored backwards here.
          */
-        auto tmpbuf_end = std::begin(tmpbuf) + SamplesToDo;
-        std::copy_n(std::begin(DelayBuf), FrontStablizer::DelayLength, tmpbuf_end);
-        std::reverse_copy(InBuf.begin(), InBuf.begin()+SamplesToDo, std::begin(tmpbuf));
-        std::copy_n(std::begin(tmpbuf), FrontStablizer::DelayLength, std::begin(DelayBuf));
+        std::copy_backward(DelayBuf.cbegin(), DelayBuf.cend(), tmpbuf.end());
+        std::reverse_copy(InBuf.begin(), InBuf.begin()+SamplesToDo, tmpbuf.begin());
+        std::copy_n(tmpbuf.cbegin(), DelayBuf.size(), DelayBuf.begin());
 
         /* Apply an all-pass on the reversed signal, then reverse the samples
          * to get the forward signal with a reversed phase shift.
          */
-        Filter.applyAllpass(tmpbuf, SamplesToDo+FrontStablizer::DelayLength);
-        std::reverse(std::begin(tmpbuf), tmpbuf_end+FrontStablizer::DelayLength);
+        Filter.applyAllpass(tmpbuf);
+        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.
          */
-        Filter.process(splitbuf[1], splitbuf[0], tmpbuf, SamplesToDo);
+        Filter.process(tmpbuf.first(SamplesToDo), splitbuf[1], splitbuf[0]);
     };
     apply_splitter(Buffer[lidx], Stablizer->DelayBuf[lidx], Stablizer->LFilter, lsplit);
     apply_splitter(Buffer[ridx], Stablizer->DelayBuf[ridx], Stablizer->RFilter, rsplit);
diff --git a/alc/bformatdec.cpp b/alc/bformatdec.cpp
index 9fbe32b8..a9510574 100644
--- a/alc/bformatdec.cpp
+++ b/alc/bformatdec.cpp
@@ -152,8 +152,8 @@ void BFormatDec::process(const al::span<FloatBufferLine> OutBuffer,
     if(mDualBand)
     {
         for(ALuint i{0};i < mNumChannels;i++)
-            mXOver[i].process(mSamplesHF[i].data(), mSamplesLF[i].data(), InSamples[i].data(),
-                SamplesToDo);
+            mXOver[i].process({InSamples[i].data(), SamplesToDo}, mSamplesHF[i].data(),
+                mSamplesLF[i].data());
 
         ALfloat (*mixmtx)[sNumBands][MAX_AMBI_CHANNELS]{mMatrix.Dual};
         ALuint enabled{mEnabled};
diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp
index c8ebba68..727c8352 100644
--- a/alc/effects/reverb.cpp
+++ b/alc/effects/reverb.cpp
@@ -448,7 +448,7 @@ struct ReverbState final : public EffectState {
              * higher-order output.
              */
             const ALfloat hfscale{(c==0) ? mOrderScales[0] : mOrderScales[1]};
-            mAmbiSplitter[0][c].applyHfScale(tmpspan.data(), hfscale, todo);
+            mAmbiSplitter[0][c].applyHfScale(tmpspan, hfscale);
 
             MixSamples(tmpspan, samplesOut, mEarly.CurrentGain[c], mEarly.PanGain[c], counter,
                 offset);
@@ -460,7 +460,7 @@ struct ReverbState final : public EffectState {
                 mLateSamples[0].size());
 
             const ALfloat hfscale{(c==0) ? mOrderScales[0] : mOrderScales[1]};
-            mAmbiSplitter[1][c].applyHfScale(tmpspan.data(), hfscale, todo);
+            mAmbiSplitter[1][c].applyHfScale(tmpspan, hfscale);
 
             MixSamples(tmpspan, samplesOut, mLate.CurrentGain[c], mLate.PanGain[c], counter,
                 offset);
diff --git a/alc/filters/splitter.cpp b/alc/filters/splitter.cpp
index c6218e70..e8e01802 100644
--- a/alc/filters/splitter.cpp
+++ b/alc/filters/splitter.cpp
@@ -27,10 +27,8 @@ void BandSplitterR<Real>::init(Real f0norm)
 }
 
 template<typename Real>
-void BandSplitterR<Real>::process(Real *hpout, Real *lpout, const Real *input, const size_t count)
+void BandSplitterR<Real>::process(const al::span<const Real> input, Real *hpout, Real *lpout)
 {
-    ASSUME(count > 0);
-
     const Real ap_coeff{mCoeff};
     const Real lp_coeff{mCoeff*0.5f + 0.5f};
     Real lp_z1{mLpZ1};
@@ -56,17 +54,15 @@ void BandSplitterR<Real>::process(Real *hpout, Real *lpout, const Real *input, c
         /* High-pass generated from removing low-passed output. */
         return ap_y - lp_y;
     };
-    std::transform(input, input+count, hpout, proc_sample);
+    std::transform(input.cbegin(), input.cend(), hpout, proc_sample);
     mLpZ1 = lp_z1;
     mLpZ2 = lp_z2;
     mApZ1 = ap_z1;
 }
 
 template<typename Real>
-void BandSplitterR<Real>::applyHfScale(Real *samples, const Real hfscale, const size_t count)
+void BandSplitterR<Real>::applyHfScale(const al::span<Real> samples, const Real hfscale)
 {
-    ASSUME(count > 0);
-
     const Real ap_coeff{mCoeff};
     const Real lp_coeff{mCoeff*0.5f + 0.5f};
     Real lp_z1{mLpZ1};
@@ -87,20 +83,20 @@ void BandSplitterR<Real>::applyHfScale(Real *samples, const Real hfscale, const
         Real ap_y{in*ap_coeff + ap_z1};
         ap_z1 = in - ap_y*ap_coeff;
 
-        /* High-pass generated from removing low-passed output. */
+        /* High-pass generated by removing the low-passed signal, which is then
+         * scaled and added back to the low-passed signal.
+         */
         return (ap_y-lp_y)*hfscale + lp_y;
     };
-    std::transform(samples, samples+count, samples, proc_sample);
+    std::transform(samples.begin(), samples.end(), samples.begin(), proc_sample);
     mLpZ1 = lp_z1;
     mLpZ2 = lp_z2;
     mApZ1 = ap_z1;
 }
 
 template<typename Real>
-void BandSplitterR<Real>::applyAllpass(Real *samples, const size_t count) const
+void BandSplitterR<Real>::applyAllpass(const al::span<Real> samples) const
 {
-    ASSUME(count > 0);
-
     const Real coeff{mCoeff};
     Real z1{0.0f};
     auto proc_sample = [coeff,&z1](const Real in) noexcept -> Real
@@ -109,7 +105,7 @@ void BandSplitterR<Real>::applyAllpass(Real *samples, const size_t count) const
         z1 = in - out*coeff;
         return out;
     };
-    std::transform(samples, samples+count, samples, proc_sample);
+    std::transform(samples.begin(), samples.end(), samples.begin(), proc_sample);
 }
 
 
diff --git a/alc/filters/splitter.h b/alc/filters/splitter.h
index 5117a244..d88ef182 100644
--- a/alc/filters/splitter.h
+++ b/alc/filters/splitter.h
@@ -3,6 +3,8 @@
 
 #include <cstddef>
 
+#include "alspan.h"
+
 
 /* Band splitter. Splits a signal into two phase-matching frequency bands. */
 template<typename Real>
@@ -19,15 +21,15 @@ public:
 
     void init(Real f0norm);
     void clear() noexcept { mLpZ1 = mLpZ2 = mApZ1 = 0.0f; }
-    void process(Real *hpout, Real *lpout, const Real *input, const size_t count);
+    void process(const al::span<const Real> input, Real *hpout, Real *lpout);
 
-    void applyHfScale(Real *samples, const Real hfscale, const size_t count);
+    void applyHfScale(const al::span<Real> samples, const Real hfscale);
 
     /* The all-pass portion of the band splitter. Applies the same phase shift
      * without splitting the signal. Note that each use of this method is
      * indepedent, it does not track history between calls.
      */
-    void applyAllpass(Real *samples, const size_t count) const;
+    void applyAllpass(const al::span<Real> samples) const;
 };
 using BandSplitter = BandSplitterR<float>;
 
diff --git a/alc/hrtf.cpp b/alc/hrtf.cpp
index 83df4b37..179938e0 100644
--- a/alc/hrtf.cpp
+++ b/alc/hrtf.cpp
@@ -372,6 +372,7 @@ void BuildBFormatHrtf(const HrtfStore *Hrtf, DirectHrtfState *state,
 
     auto tmpres = al::vector<std::array<double2,HRIR_LENGTH>>(state->Coeffs.size());
     auto tmpflt = al::vector<std::array<double,HRIR_LENGTH*4>>(3);
+    const al::span<double,HRIR_LENGTH*4> tempir{tmpflt[2].data(), tmpflt[2].size()};
     for(size_t c{0u};c < AmbiPoints.size();++c)
     {
         const al::span<const double2,HRIR_LENGTH> hrir{impres[c].hrir};
@@ -402,23 +403,23 @@ void BuildBFormatHrtf(const HrtfStore *Hrtf, DirectHrtfState *state,
          */
 
         /* Load the (left) HRIR backwards, into a temp buffer with padding. */
-        std::fill(tmpflt[2].begin(), tmpflt[2].end(), 0.0);
-        std::transform(hrir.cbegin(), hrir.cend(), tmpflt[2].rbegin() + HRIR_LENGTH*3,
+        std::fill(tempir.begin(), tempir.end(), 0.0);
+        std::transform(hrir.cbegin(), hrir.cend(), tempir.rbegin() + HRIR_LENGTH*3,
             [](const double2 &ir) noexcept -> double { return ir[0]; });
 
         /* Apply the all-pass on the reversed signal and reverse the resulting
          * sample array. This produces the forward response with a backwards
          * phase-shift (+n degrees becomes -n degrees).
          */
-        splitter.applyAllpass(tmpflt[2].data(), tmpflt[2].size());
-        std::reverse(tmpflt[2].begin(), tmpflt[2].end());
+        splitter.applyAllpass(tempir);
+        std::reverse(tempir.begin(), tempir.end());
 
         /* Now apply the band-splitter. This applies the normal phase-shift,
          * which cancels out with the backwards phase-shift to get the original
          * phase on the split signal.
          */
         splitter.clear();
-        splitter.process(tmpflt[0].data(), tmpflt[1].data(), tmpflt[2].data(), tmpflt[2].size());
+        splitter.process(tempir, tmpflt[0].data(), tmpflt[1].data());
 
         /* Apply left ear response with delay and HF scale. */
         for(size_t i{0u};i < state->Coeffs.size();++i)
@@ -431,15 +432,15 @@ void BuildBFormatHrtf(const HrtfStore *Hrtf, DirectHrtfState *state,
         }
 
         /* Now run the same process on the right HRIR. */
-        std::fill(tmpflt[2].begin(), tmpflt[2].end(), 0.0);
-        std::transform(hrir.cbegin(), hrir.cend(), tmpflt[2].rbegin() + HRIR_LENGTH*3,
+        std::fill(tempir.begin(), tempir.end(), 0.0);
+        std::transform(hrir.cbegin(), hrir.cend(), tempir.rbegin() + HRIR_LENGTH*3,
             [](const double2 &ir) noexcept -> double { return ir[1]; });
 
-        splitter.applyAllpass(tmpflt[2].data(), tmpflt[2].size());
-        std::reverse(tmpflt[2].begin(), tmpflt[2].end());
+        splitter.applyAllpass(tempir);
+        std::reverse(tempir.begin(), tempir.end());
 
         splitter.clear();
-        splitter.process(tmpflt[0].data(), tmpflt[1].data(), tmpflt[2].data(), tmpflt[2].size());
+        splitter.process(tempir, tmpflt[0].data(), tmpflt[1].data());
 
         for(size_t i{0u};i < state->Coeffs.size();++i)
         {
diff --git a/alc/voice.cpp b/alc/voice.cpp
index 4697cc56..ef26b630 100644
--- a/alc/voice.cpp
+++ b/alc/voice.cpp
@@ -678,15 +678,15 @@ void ALvoice::mix(const State vstate, ALCcontext *Context, const ALuint SamplesT
                 {Device->ResampledData, DstBufferSize})};
             if((mFlags&VOICE_IS_AMBISONIC))
             {
-                const ALfloat hfscale{chandata.mAmbiScale};
+                const float hfscale{chandata.mAmbiScale};
                 /* Beware the evil const_cast. It's safe since it's pointing to
                  * either SourceData or ResampledData (both non-const), but the
                  * resample method takes the source as const float* and may
                  * return it without copying to output, making it currently
                  * unavoidable.
                  */
-                chandata.mAmbiSplitter.applyHfScale(const_cast<ALfloat*>(ResampledData), hfscale,
-                    DstBufferSize);
+                const al::span<float> samples{const_cast<float*>(ResampledData), DstBufferSize};
+                chandata.mAmbiSplitter.applyHfScale(samples, hfscale);
             }
 
             /* Now filter and mix to the appropriate outputs. */
-- 
cgit v1.2.3