Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/sanear.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Marsev <alex.marsev@gmail.com>2015-08-01 16:04:22 +0300
committerAlex Marsev <alex.marsev@gmail.com>2015-08-02 20:21:32 +0300
commit9f3776d2506a512ea24774c4e7d3bee273cf90b6 (patch)
tree0802291a93cea87c004536b8acab42d3efc32510
parentd9c9e286678a9d17654ffe5ccc29d0547ff82ca1 (diff)
Fix DspDither
It's used in ->PCM16 downsampling. Error feedback coefficients were wrong and it was causing audible noise. Also switch to TPDF dither while at it.
-rwxr-xr-x[-rw-r--r--]src/DspDither.cpp23
-rwxr-xr-x[-rw-r--r--]src/DspDither.h6
2 files changed, 18 insertions, 11 deletions
diff --git a/src/DspDither.cpp b/src/DspDither.cpp
index c0c91a5..c8682b0 100644..100755
--- a/src/DspDither.cpp
+++ b/src/DspDither.cpp
@@ -6,8 +6,13 @@ namespace SaneAudioRenderer
void DspDither::Initialize(DspFormat outputFormat)
{
m_active = (outputFormat == DspFormat::Pcm16);
- m_error1 = {};
- m_error2 = {};
+
+ for (size_t i = 0; i < 18; i++)
+ {
+ m_previous[i] = 0.0f;
+ m_generator[i].seed((uint32_t)(GetPerformanceCounter() + i));
+ m_distributor[i] = std::uniform_real_distribution<float>(0, 1.0f);
+ }
}
bool DspDither::Active()
@@ -32,12 +37,14 @@ namespace SaneAudioRenderer
{
for (size_t channel = 0; channel < channels; channel++)
{
- // Rectangular dither with simple second-order noise shaping.
- float inputSample = inputData[frame * channels + channel] * (INT16_MAX - 4);
- float noise = (float)m_rand() / m_rand.max() + 0.5f * m_error1[channel] - m_error2[channel];
- float outputSample = round(inputSample + noise);
- m_error2[channel] = m_error1[channel];
- m_error1[channel] = outputSample - inputSample;
+ float inputSample = inputData[frame * channels + channel] * (INT16_MAX - 1);
+
+ // High-pass TPDF, 2 LSB amplitude.
+ float r = m_distributor[channel](m_generator[channel]);
+ float noise = r - m_previous[channel];
+ m_previous[channel] = r;
+
+ float outputSample = std::round(inputSample + noise);
assert(outputSample >= INT16_MIN && outputSample <= INT16_MAX);
outputData[frame * channels + channel] = (int16_t)outputSample;
}
diff --git a/src/DspDither.h b/src/DspDither.h
index b41c37e..6fe5422 100644..100755
--- a/src/DspDither.h
+++ b/src/DspDither.h
@@ -25,8 +25,8 @@ namespace SaneAudioRenderer
private:
bool m_active = false;
- std::array<float, 18> m_error1;
- std::array<float, 18> m_error2;
- std::minstd_rand m_rand;
+ std::array<float, 18> m_previous;
+ std::array<std::minstd_rand, 18> m_generator;
+ std::array<std::uniform_real_distribution<float>, 18> m_distributor;
};
}