diff options
author | Chris Robinson <[email protected]> | 2020-05-26 12:19:19 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2020-05-26 12:19:19 -0700 |
commit | 7b642330c5266682451a19caba1f7d19c1828a71 (patch) | |
tree | 254340fe1cba47ac67313f92f79077fcc662bd8e /alc | |
parent | 8d77c59da45b1d4fe206ef8b6c5667fffb7c9d1b (diff) |
Simplify UHJ delay handling
Diffstat (limited to 'alc')
-rw-r--r-- | alc/uhjfilter.cpp | 40 | ||||
-rw-r--r-- | alc/uhjfilter.h | 6 |
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. |