Simplify UHJ delay handling

This commit is contained in:
Chris Robinson
2020-05-26 12:19:19 -07:00
parent 8d77c59da4
commit 7b642330c5
2 changed files with 17 additions and 29 deletions
+14 -26
View File
@@ -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];
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];
/* 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());
/* 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_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());
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());
+3 -3
View File
@@ -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.