aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2021-11-28 05:21:33 -0800
committerChris Robinson <[email protected]>2021-11-28 05:39:35 -0800
commita73b64ce3c7bffa8a9a97f517bcce7b7604f44a3 (patch)
tree2a442f8585516809614bc035df63095d577783d2
parentbd254c5426748a1a0d64944bc91ab1956241dd1b (diff)
Slight update to the UHJ coefficients
The extended precision of the encoder's 0.6512*X term was guesswork, with no real basis for it. Switch back to the original value until something better actually comes up. Also updates the decoder to account for the change in the encoder.
-rw-r--r--core/uhjfilter.cpp24
-rw-r--r--utils/uhjdecoder.cpp66
-rw-r--r--utils/uhjencoder.cpp2
3 files changed, 46 insertions, 46 deletions
diff --git a/core/uhjfilter.cpp b/core/uhjfilter.cpp
index 0875211c..282ed2b3 100644
--- a/core/uhjfilter.cpp
+++ b/core/uhjfilter.cpp
@@ -28,7 +28,7 @@ const PhaseShifterT<UhjFilterBase::sFilterDelay*2> PShift{};
*
* Left = (S + D)/2.0
* Right = (S - D)/2.0
- * T = j(-0.1432*W + 0.6511746*X) - 0.7071068*Y
+ * T = j(-0.1432*W + 0.6512*X) - 0.7071068*Y
* Q = 0.9772*Z
*
* where j is a wide-band +90 degree phase shift. 3-channel UHJ excludes Q,
@@ -95,9 +95,9 @@ void UhjEncoder::encode(float *LeftOut, float *RightOut, const FloatBufferLine *
* S = Left + Right
* D = Left - Right
*
- * W = 0.981530*S + 0.197484*j(0.828347*D + 0.767835*T)
- * X = 0.418504*S - j(0.828347*D + 0.767835*T)
- * Y = 0.795954*D - 0.676406*T + j(0.186626*S)
+ * W = 0.981532*S + 0.197484*j(0.828331*D + 0.767820*T)
+ * X = 0.418496*S - j(0.828331*D + 0.767820*T)
+ * Y = 0.795968*D - 0.676392*T + j(0.186633*S)
* Z = 1.023332*Q
*
* where j is a +90 degree phase shift. 3-channel UHJ excludes Q, while 2-
@@ -130,19 +130,19 @@ void UhjDecoder::decode(const al::span<BufferLine> samples, const size_t offset,
float *RESTRICT xoutput{samples[1].data() + offset};
float *RESTRICT youtput{samples[2].data() + offset};
- /* Precompute j(0.828347*D + 0.767835*T) and store in xoutput. */
+ /* Precompute j(0.828331*D + 0.767820*T) and store in xoutput. */
auto tmpiter = std::copy(mDTHistory.cbegin(), mDTHistory.cend(), mTemp.begin());
std::transform(mD.cbegin(), mD.cbegin()+samplesToDo+sFilterDelay, mT.cbegin(), tmpiter,
- [](const float d, const float t) noexcept { return 0.828347f*d + 0.767835f*t; });
+ [](const float d, const float t) noexcept { return 0.828331f*d + 0.767820f*t; });
std::copy_n(mTemp.cbegin()+forwardSamples, mDTHistory.size(), mDTHistory.begin());
PShift.process({xoutput, samplesToDo}, mTemp.data());
- /* W = 0.981530*S + 0.197484*j(0.828347*D + 0.767835*T) */
+ /* W = 0.981532*S + 0.197484*j(0.828331*D + 0.767820*T) */
for(size_t i{0};i < samplesToDo;++i)
- woutput[i] = 0.981530f*mS[i] + 0.197484f*xoutput[i];
- /* X = 0.418504*S - j(0.828347*D + 0.767835*T) */
+ woutput[i] = 0.981532f*mS[i] + 0.197484f*xoutput[i];
+ /* X = 0.418496*S - j(0.828331*D + 0.767820*T) */
for(size_t i{0};i < samplesToDo;++i)
- xoutput[i] = 0.418504f*mS[i] - xoutput[i];
+ xoutput[i] = 0.418496f*mS[i] - xoutput[i];
/* Precompute j*S and store in youtput. */
tmpiter = std::copy(mSHistory.cbegin(), mSHistory.cend(), mTemp.begin());
@@ -150,9 +150,9 @@ void UhjDecoder::decode(const al::span<BufferLine> samples, const size_t offset,
std::copy_n(mTemp.cbegin()+forwardSamples, mSHistory.size(), mSHistory.begin());
PShift.process({youtput, samplesToDo}, mTemp.data());
- /* Y = 0.795954*D - 0.676406*T + j(0.186626*S) */
+ /* Y = 0.795968*D - 0.676392*T + j(0.186633*S) */
for(size_t i{0};i < samplesToDo;++i)
- youtput[i] = 0.795954f*mD[i] - 0.676406f*mT[i] + 0.186626f*youtput[i];
+ youtput[i] = 0.795968f*mD[i] - 0.676392f*mT[i] + 0.186633f*youtput[i];
if(samples.size() > 3)
{
diff --git a/utils/uhjdecoder.cpp b/utils/uhjdecoder.cpp
index 4c45afd7..7bb1a51a 100644
--- a/utils/uhjdecoder.cpp
+++ b/utils/uhjdecoder.cpp
@@ -141,9 +141,9 @@ const PhaseShifterT<UhjDecoder::sFilterDelay*2> PShift{};
* S = Left + Right
* D = Left - Right
*
- * W = 0.981530*S + 0.197484*j(0.828347*D + 0.767835*T)
- * X = 0.418504*S - j(0.828347*D + 0.767835*T)
- * Y = 0.795954*D - 0.676406*T + j(0.186626*S)
+ * W = 0.981532*S + 0.197484*j(0.828331*D + 0.767820*T)
+ * X = 0.418496*S - j(0.828331*D + 0.767820*T)
+ * Y = 0.795968*D - 0.676392*T + j(0.186633*S)
* Z = 1.023332*Q
*
* where j is a +90 degree phase shift. 3-channel UHJ excludes Q, while 2-
@@ -162,49 +162,49 @@ const PhaseShifterT<UhjDecoder::sFilterDelay*2> PShift{};
* Gerzon's original paper for deriving Sigma (S) or Delta (D) from the L and R
* signals. As proof, taking Y for example:
*
- * Y = 0.795954*D - 0.676406*T + j(0.186626*S)
+ * Y = 0.795968*D - 0.676392*T + j(0.186633*S)
*
* * Plug in the encoding parameters, using ? as a placeholder for whether S
* and D should receive an extra 0.5 factor
- * Y = 0.795954*(j(-0.3420201*W + 0.5098604*X) + 0.6554516*Y)*? -
- * 0.676406*(j(-0.1432*W + 0.6511746*X) - 0.7071068*Y) +
- * 0.186626*j(0.9396926*W + 0.1855740*X)*?
+ * Y = 0.795968*(j(-0.3420201*W + 0.5098604*X) + 0.6554516*Y)*? -
+ * 0.676392*(j(-0.1432*W + 0.6512*X) - 0.7071068*Y) +
+ * 0.186633*j(0.9396926*W + 0.1855740*X)*?
*
* * Move common factors in
- * Y = (j(-0.3420201*0.795954*?*W + 0.5098604*0.795954*?*X) + 0.6554516*0.795954*?*Y) -
- * (j(-0.1432*0.676406*W + 0.6511746*0.676406*X) - 0.7071068*0.676406*Y) +
- * j(0.9396926*0.186626*?*W + 0.1855740*0.186626*?*X)
+ * Y = (j(-0.3420201*0.795968*?*W + 0.5098604*0.795968*?*X) + 0.6554516*0.795968*?*Y) -
+ * (j(-0.1432*0.676392*W + 0.6512*0.676392*X) - 0.7071068*0.676392*Y) +
+ * j(0.9396926*0.186633*?*W + 0.1855740*0.186633*?*X)
*
* * Clean up extraneous groupings
- * Y = j(-0.3420201*0.795954*?*W + 0.5098604*0.795954*?*X) + 0.6554516*0.795954*?*Y -
- * j(-0.1432*0.676406*W + 0.6511746*0.676406*X) + 0.7071068*0.676406*Y +
- * j*(0.9396926*0.186626*?*W + 0.1855740*0.186626*?*X)
+ * Y = j(-0.3420201*0.795968*?*W + 0.5098604*0.795968*?*X) + 0.6554516*0.795968*?*Y -
+ * j(-0.1432*0.676392*W + 0.6512*0.676392*X) + 0.7071068*0.676392*Y +
+ * j*(0.9396926*0.186633*?*W + 0.1855740*0.186633*?*X)
*
* * Move phase shifts together and combine them
- * Y = j(-0.3420201*0.795954*?*W + 0.5098604*0.795954*?*X - -0.1432*0.676406*W -
- * 0.6511746*0.676406*X + 0.9396926*0.186626*?*W + 0.1855740*0.186626*?*X) +
- * 0.6554516*0.795954*?*Y + 0.7071068*0.676406*Y
+ * Y = j(-0.3420201*0.795968*?*W + 0.5098604*0.795968*?*X - -0.1432*0.676392*W -
+ * 0.6512*0.676392*X + 0.9396926*0.186633*?*W + 0.1855740*0.186633*?*X) +
+ * 0.6554516*0.795968*?*Y + 0.7071068*0.676392*Y
*
* * Reorder terms
- * Y = j(-0.3420201*0.795954*?*W + 0.1432*0.676406*W + 0.9396926*0.186626*?*W +
- * 0.5098604*0.795954*?*X + -0.6511746*0.676406*X + 0.1855740*0.186626*?*X) +
- * 0.7071068*0.676406*Y + 0.6554516*0.795954*?*Y
+ * Y = j(-0.3420201*0.795968*?*W + 0.1432*0.676392*W + 0.9396926*0.186633*?*W +
+ * 0.5098604*0.795968*?*X + -0.6512*0.676392*X + 0.1855740*0.186633*?*X) +
+ * 0.7071068*0.676392*Y + 0.6554516*0.795968*?*Y
*
* * Move common factors out
- * Y = j((-0.3420201*0.795954*? + 0.1432*0.676406 + 0.9396926*0.186626*?)*W +
- * ( 0.5098604*0.795954*? + -0.6511746*0.676406 + 0.1855740*0.186626*?)*X) +
- * (0.7071068*0.676406 + 0.6554516*0.795954*?)*Y
+ * Y = j((-0.3420201*0.795968*? + 0.1432*0.676392 + 0.9396926*0.186633*?)*W +
+ * ( 0.5098604*0.795968*? + -0.6512*0.676392 + 0.1855740*0.186633*?)*X) +
+ * (0.7071068*0.676392 + 0.6554516*0.795968*?)*Y
*
* * Result w/ 0.5 factor:
- * -0.3420201*0.795954*0.5 + 0.1432*0.676406 + 0.9396926*0.186626*0.5 = 0.04843*W
- * 0.5098604*0.795954*0.5 + -0.6511746*0.676406 + 0.1855740*0.186626*0.5 = -0.22023*X
- * 0.7071068*0.676406 + 0.6554516*0.795954*0.5 = 0.73915*Y
- * -> Y = j(0.04843*W + -0.22023*X) + 0.73915*Y
+ * -0.3420201*0.795968*0.5 + 0.1432*0.676392 + 0.9396926*0.186633*0.5 = 0.04843*W
+ * 0.5098604*0.795968*0.5 + -0.6512*0.676392 + 0.1855740*0.186633*0.5 = -0.22023*X
+ * 0.7071068*0.676392 + 0.6554516*0.795968*0.5 = 0.73914*Y
+ * -> Y = j(0.04843*W + -0.22023*X) + 0.73914*Y
*
* * Result w/o 0.5 factor:
- * -0.3420201*0.795954 + 0.1432*0.676406 + 0.9396926*0.186626 = 0.00000*W
- * 0.5098604*0.795954 + -0.6511746*0.676406 + 0.1855740*0.186626 = 0.00000*X
- * 0.7071068*0.676406 + 0.6554516*0.795954 = 1.00000*Y
+ * -0.3420201*0.795968 + 0.1432*0.676392 + 0.9396926*0.186633 = 0.00000*W
+ * 0.5098604*0.795968 + -0.6512*0.676392 + 0.1855740*0.186633 = 0.00000*X
+ * 0.7071068*0.676392 + 0.6554516*0.795968 = 1.00000*Y
* -> Y = j(0.00000*W + 0.00000*X) + 1.00000*Y
*
* Not halving produces a result matching the original input.
@@ -252,8 +252,8 @@ void UhjDecoder::decode(const float *RESTRICT InSamples, const size_t InChannels
for(size_t i{0};i < SamplesToDo;++i)
{
- /* W = 0.981530*S + 0.197484*j(0.828347*D + 0.767835*T) */
- woutput[i] = 0.981530f*mS[i] + 0.197484f*xoutput[i];
+ /* W = 0.981532*S + 0.197484*j(0.828347*D + 0.767835*T) */
+ woutput[i] = 0.981532f*mS[i] + 0.197484f*xoutput[i];
/* X = 0.418504*S - j(0.828347*D + 0.767835*T) */
xoutput[i] = 0.418504f*mS[i] - xoutput[i];
}
@@ -266,8 +266,8 @@ void UhjDecoder::decode(const float *RESTRICT InSamples, const size_t InChannels
for(size_t i{0};i < SamplesToDo;++i)
{
- /* Y = 0.795954*D - 0.676406*T + j(0.186626*S) */
- youtput[i] = 0.795954f*mD[i] - 0.676406f*mT[i] + 0.186626f*youtput[i];
+ /* Y = 0.795968*D - 0.676392*T + j(0.186633*S) */
+ youtput[i] = 0.795968f*mD[i] - 0.676392f*mT[i] + 0.186633f*youtput[i];
}
if(OutSamples.size() > 3)
diff --git a/utils/uhjencoder.cpp b/utils/uhjencoder.cpp
index 73e21479..700d1b17 100644
--- a/utils/uhjencoder.cpp
+++ b/utils/uhjencoder.cpp
@@ -89,7 +89,7 @@ const PhaseShifterT<UhjEncoder::sFilterDelay*2> PShift{};
*
* Left = (S + D)/2.0
* Right = (S - D)/2.0
- * T = j(-0.1432*W + 0.6511746*X) - 0.7071068*Y
+ * T = j(-0.1432*W + 0.6512*X) - 0.7071068*Y
* Q = 0.9772*Z
*
* where j is a wide-band +90 degree phase shift. T is excluded from 2-channel