diff options
author | Chris Robinson <[email protected]> | 2021-03-20 03:03:47 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2021-03-20 03:14:10 -0700 |
commit | 7c697b9178b2f7bff6fec4fa9cbbf5390f13d2e5 (patch) | |
tree | e05fc701e07494da6974988e776ed33a92a38656 /core | |
parent | 063da94bd8f4e2dc0369c283a7fa0f124764eb1c (diff) |
Fix the UHJ all-pass delay
For real this time. The non-all-passed signal needs a one-sample delay over the
all-passed signal. Because of the way the all-pass FIR filter is structured,
it wouldn't otherwise use the last buffered sample, allowing it to be shifted
forward in time by one sample.
Also, remove a couple unnecessary buffers.
Diffstat (limited to 'core')
-rw-r--r-- | core/uhjfilter.cpp | 12 | ||||
-rw-r--r-- | core/uhjfilter.h | 7 |
2 files changed, 8 insertions, 11 deletions
diff --git a/core/uhjfilter.cpp b/core/uhjfilter.cpp index 2dd41d15..3fbec3b3 100644 --- a/core/uhjfilter.cpp +++ b/core/uhjfilter.cpp @@ -244,13 +244,13 @@ void Uhj2Encoder::encode(const FloatBufferSpan LeftOut, const FloatBufferSpan Ri /* Combine the previously delayed mid/side signal with the input. */ /* S = 0.9396926*W + 0.1855740*X */ - auto miditer = std::copy(mMidDelay.cbegin(), mMidDelay.cend(), mMid.begin()); + auto miditer = mMid.begin() + sFilterSize; 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 */ - auto sideiter = std::copy(mSideDelay.cbegin(), mSideDelay.cend(), mSide.begin()); + auto sideiter = mSide.begin() + sFilterSize; std::transform(yinput, yinput+SamplesToDo, sideiter, [](const float y) noexcept -> float { return 0.6554516f*y; }); @@ -260,10 +260,6 @@ void Uhj2Encoder::encode(const FloatBufferSpan LeftOut, const FloatBufferSpan Ri for(size_t i{0};i < SamplesToDo;++i,++sideiter) *sideiter += left[i] - right[i]; - /* 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()); - /* Now add the all-passed signal into the side signal. */ /* D += j(-0.3420201*W + 0.5098604*X) */ @@ -280,4 +276,8 @@ void Uhj2Encoder::encode(const FloatBufferSpan LeftOut, const FloatBufferSpan Ri /* Right = (S - D)/2.0 */ for(size_t i{0};i < SamplesToDo;i++) right[i] = (mMid[i] - mSide[i]) * 0.5f; + + /* Copy the future samples to the front for next time. */ + std::copy(mMid.cbegin()+SamplesToDo, mMid.cbegin()+SamplesToDo+sFilterSize, mMid.begin()); + std::copy(mSide.cbegin()+SamplesToDo, mSide.cbegin()+SamplesToDo+sFilterSize, mSide.begin()); } diff --git a/core/uhjfilter.h b/core/uhjfilter.h index 7609533b..ff794355 100644 --- a/core/uhjfilter.h +++ b/core/uhjfilter.h @@ -14,15 +14,12 @@ struct Uhj2Encoder { */ constexpr static size_t sFilterSize{128}; - /* Delays for the unfiltered signal. */ - alignas(16) std::array<float,sFilterSize> mMidDelay{}; - alignas(16) std::array<float,sFilterSize> mSideDelay{}; - + /* Delays and processing storage for the unfiltered signal. */ alignas(16) std::array<float,BufferLineSize+sFilterSize> mMid{}; alignas(16) std::array<float,BufferLineSize+sFilterSize> mSide{}; /* History for the FIR filter. */ - alignas(16) std::array<float,sFilterSize*2> mSideHistory{}; + alignas(16) std::array<float,sFilterSize*2 - 1> mSideHistory{}; alignas(16) std::array<float,BufferLineSize + sFilterSize*2> mTemp{}; |