aboutsummaryrefslogtreecommitdiffstats
path: root/alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2020-05-26 12:19:19 -0700
committerChris Robinson <[email protected]>2020-05-26 12:19:19 -0700
commit7b642330c5266682451a19caba1f7d19c1828a71 (patch)
tree254340fe1cba47ac67313f92f79077fcc662bd8e /alc
parent8d77c59da45b1d4fe206ef8b6c5667fffb7c9d1b (diff)
Simplify UHJ delay handling
Diffstat (limited to 'alc')
-rw-r--r--alc/uhjfilter.cpp40
-rw-r--r--alc/uhjfilter.h6
2 files changed, 17 insertions, 29 deletions
diff --git a/alc/uhjfilter.cpp b/alc/uhjfilter.cpp
index e0469bf9..f141d148 100644
--- a/alc/uhjfilter.cpp
+++ b/alc/uhjfilter.cpp
@@ -172,42 +172,30 @@ void Uhj2Encoder::encode(FloatBufferLine &LeftOut, FloatBufferLine &RightOut,
const float *RESTRICT xinput{al::assume_aligned<16>(InSamples[1].data())};
const float *RESTRICT yinput{al::assume_aligned<16>(InSamples[2].data())};
+ /* Combine the previously delayed mid/side signal with the input. */
+
/* S = 0.9396926*W + 0.1855740*X */
- std::transform(winput, winput+SamplesToDo, xinput, mMid.begin(),
+ auto miditer = std::copy(mMidDelay.cbegin(), mMidDelay.cend(), mMid.begin());
+ std::transform(winput, winput+SamplesToDo, xinput, miditer,
[](const float w, const float x) noexcept -> float
{ return 0.9396926f*w + 0.1855740f*x; });
/* D = 0.6554516*Y */
- std::transform(yinput, yinput+SamplesToDo, mSide.begin(),
+ auto sideiter = std::copy(mSideDelay.cbegin(), mSideDelay.cend(), mSide.begin());
+ std::transform(yinput, yinput+SamplesToDo, sideiter,
[](const float y) noexcept -> float { return 0.6554516f*y; });
/* Include any existing direct signal in the mid/side buffers. */
- for(size_t i{0};i < SamplesToDo;++i)
- mMid[i] += left[i] + right[i];
- for(size_t i{0};i < SamplesToDo;++i)
- mSide[i] += left[i] - right[i];
-
- /* Apply a delay to the non-filtered signal to align with the filter delay. */
- if LIKELY(SamplesToDo >= sFilterSize)
- {
- auto buffer_end = mMid.begin() + SamplesToDo;
- auto delay_end = std::rotate(mMid.begin(), buffer_end - sFilterSize, buffer_end);
- std::swap_ranges(mMid.begin(), delay_end, mMidDelay.begin());
+ for(size_t i{0};i < SamplesToDo;++i,++miditer)
+ *miditer += left[i] + right[i];
+ for(size_t i{0};i < SamplesToDo;++i,++sideiter)
+ *sideiter += left[i] - right[i];
- buffer_end = mSide.begin() + SamplesToDo;
- delay_end = std::rotate(mSide.begin(), buffer_end - sFilterSize, buffer_end);
- std::swap_ranges(mSide.begin(), delay_end, mSideDelay.begin());
- }
- else
- {
- auto buffer_end = mMid.begin() + SamplesToDo;
- auto delay_start = std::swap_ranges(mMid.begin(), buffer_end, mMidDelay.begin());
- std::rotate(mMidDelay.begin(), delay_start, mMidDelay.end());
+ /* Copy the future samples back to the delay buffers for next time. */
+ std::copy_n(mMid.cbegin()+SamplesToDo, mMidDelay.size(), mMidDelay.begin());
+ std::copy_n(mSide.cbegin()+SamplesToDo, mSideDelay.size(), mSideDelay.begin());
- buffer_end = mSide.begin() + SamplesToDo;
- delay_start = std::swap_ranges(mSide.begin(), buffer_end, mSideDelay.begin());
- std::rotate(mSideDelay.begin(), delay_start, mSideDelay.end());
- }
+ /* Now add the all-passed signal into the side signal. */
/* D += j(-0.3420201*W + 0.5098604*X) */
auto tmpiter = std::copy(mSideHistory.cbegin(), mSideHistory.cend(), mTemp.begin());
diff --git a/alc/uhjfilter.h b/alc/uhjfilter.h
index 362196a4..17a01d20 100644
--- a/alc/uhjfilter.h
+++ b/alc/uhjfilter.h
@@ -32,14 +32,14 @@ struct Uhj2Encoder {
alignas(16) std::array<float,sFilterSize> mMidDelay{};
alignas(16) std::array<float,sFilterSize> mSideDelay{};
+ alignas(16) std::array<float,BUFFERSIZE+sFilterSize> mMid{};
+ alignas(16) std::array<float,BUFFERSIZE+sFilterSize> mSide{};
+
/* History for the FIR filter. */
alignas(16) std::array<float,sFilterSize*2 - 1> mSideHistory{};
alignas(16) std::array<float,BUFFERSIZE + sFilterSize*2> mTemp{};
- alignas(16) std::array<float,BUFFERSIZE> mMid{};
- alignas(16) std::array<float,BUFFERSIZE> mSide{};
-
/**
* Encodes a 2-channel UHJ (stereo-compatible) signal from a B-Format input
* signal. The input must use FuMa channel ordering and scaling.