aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/filters/splitter.cpp35
-rw-r--r--core/filters/splitter.h2
-rw-r--r--core/mixer/hrtfbase.h13
3 files changed, 44 insertions, 6 deletions
diff --git a/core/filters/splitter.cpp b/core/filters/splitter.cpp
index 5ffe51e1..19f7646a 100644
--- a/core/filters/splitter.cpp
+++ b/core/filters/splitter.cpp
@@ -61,6 +61,41 @@ void BandSplitterR<Real>::process(const al::span<const Real> input, Real *hpout,
}
template<typename Real>
+void BandSplitterR<Real>::processHfScale(const al::span<const Real> input, Real *RESTRICT output,
+ const Real hfscale)
+{
+ const Real ap_coeff{mCoeff};
+ const Real lp_coeff{mCoeff*0.5f + 0.5f};
+ Real lp_z1{mLpZ1};
+ Real lp_z2{mLpZ2};
+ Real ap_z1{mApZ1};
+ auto proc_sample = [hfscale,ap_coeff,lp_coeff,&lp_z1,&lp_z2,&ap_z1](const Real in) noexcept -> Real
+ {
+ /* Low-pass sample processing. */
+ Real d{(in - lp_z1) * lp_coeff};
+ Real lp_y{lp_z1 + d};
+ lp_z1 = lp_y + d;
+
+ d = (lp_y - lp_z2) * lp_coeff;
+ lp_y = lp_z2 + d;
+ lp_z2 = lp_y + d;
+
+ /* All-pass sample processing. */
+ Real ap_y{in*ap_coeff + ap_z1};
+ ap_z1 = in - ap_y*ap_coeff;
+
+ /* 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(input.begin(), input.end(), output, proc_sample);
+ mLpZ1 = lp_z1;
+ mLpZ2 = lp_z2;
+ mApZ1 = ap_z1;
+}
+
+template<typename Real>
void BandSplitterR<Real>::processHfScale(const al::span<Real> samples, const Real hfscale)
{
const Real ap_coeff{mCoeff};
diff --git a/core/filters/splitter.h b/core/filters/splitter.h
index e428418f..41805c70 100644
--- a/core/filters/splitter.h
+++ b/core/filters/splitter.h
@@ -24,6 +24,8 @@ public:
void clear() noexcept { mLpZ1 = mLpZ2 = mApZ1 = 0.0f; }
void process(const al::span<const Real> input, Real *hpout, Real *lpout);
+ void processHfScale(const al::span<const Real> input, Real *output, const Real hfscale);
+
void processHfScale(const al::span<Real> samples, const Real hfscale);
void processScale(const al::span<Real> samples, const Real hfscale, const Real lfscale);
diff --git a/core/mixer/hrtfbase.h b/core/mixer/hrtfbase.h
index ade6f693..606f9d4e 100644
--- a/core/mixer/hrtfbase.h
+++ b/core/mixer/hrtfbase.h
@@ -96,12 +96,11 @@ inline void MixDirectHrtfBase(const FloatBufferSpan LeftOut, const FloatBufferSp
* the high frequency response. The band-splitter applies this scaling
* with a consistent phase shift regardless of the scale amount.
*/
- al::span<float> tempbuf{al::assume_aligned<16>(TempBuf), BufferSize};
- std::copy(input.begin(), input.begin()+BufferSize, tempbuf.begin());
-
- ChanState->mSplitter.processHfScale(tempbuf, ChanState->mHfScale);
+ ChanState->mSplitter.processHfScale({input.data(), BufferSize}, TempBuf,
+ ChanState->mHfScale);
/* Now apply the HRIR coefficients to this channel. */
+ const float *RESTRICT tempbuf{al::assume_aligned<16>(TempBuf)};
const ConstHrirSpan Coeffs{ChanState->mCoeffs};
for(size_t i{0u};i < BufferSize;++i)
{
@@ -113,10 +112,12 @@ inline void MixDirectHrtfBase(const FloatBufferSpan LeftOut, const FloatBufferSp
}
/* Add the HRTF signal to the existing "direct" signal. */
+ float *RESTRICT left{al::assume_aligned<16>(LeftOut.data())};
+ float *RESTRICT right{al::assume_aligned<16>(RightOut.data())};
for(size_t i{0u};i < BufferSize;++i)
- LeftOut[i] += AccumSamples[i][0];
+ left[i] += AccumSamples[i][0];
for(size_t i{0u};i < BufferSize;++i)
- RightOut[i] += AccumSamples[i][1];
+ right[i] += AccumSamples[i][1];
/* Copy the new in-progress accumulation values to the front and clear the
* following samples for the next mix.