summaryrefslogtreecommitdiffstats
path: root/src/sources
diff options
context:
space:
mode:
authorUwe Klotz <uklotz@mixxx.org>2021-06-20 01:55:12 +0200
committerUwe Klotz <uklotz@mixxx.org>2021-06-20 01:55:12 +0200
commit0c6ee5176aa83092174e190d6f7d930df0e60a17 (patch)
tree498262d115153e483b100ef6ac4427474080e556 /src/sources
parentbcee35040ef55f1e9c091a15fcf172a9ecf53ad1 (diff)
parent3902e90c6a30f2d552f9c520e9b4e0539c06fd4f (diff)
Merge branch '2.3' of git@github.com:mixxxdj/mixxx.git
# Conflicts: # src/util/sandbox.cpp
Diffstat (limited to 'src/sources')
-rw-r--r--src/sources/soundsourceflac.cpp24
1 files changed, 17 insertions, 7 deletions
diff --git a/src/sources/soundsourceflac.cpp b/src/sources/soundsourceflac.cpp
index a6624a7e82..4e97e15f0a 100644
--- a/src/sources/soundsourceflac.cpp
+++ b/src/sources/soundsourceflac.cpp
@@ -399,16 +399,26 @@ namespace {
// https://bugs.launchpad.net/mixxx/+bug/1769717
// https://hydrogenaud.io/index.php/topic,61792.msg559045.html#msg559045
-// We will shift decoded samples left by (32 - m_bitsPerSample) to
-// get rid of the garbage in the most significant bits before scaling
-// to the range [-CSAMPLE_PEAK, CSAMPLE_PEAK - epsilon] with
-// epsilon = 1 / 2 ^ bitsPerSample.
-constexpr CSAMPLE kSampleScaleFactor = CSAMPLE_PEAK /
+// We multiply the decoded samples by 2 ^ (32 - m_bitsPerSample) to
+// get rid of the garbage in the most significant bits which get shifted
+// out to the left. The resulting, upscaled integer value is then scaled
+// down to the floating point range [-CSAMPLE_PEAK, CSAMPLE_PEAK - epsilon]
+// with epsilon = 1 / 2 ^ bitsPerSample.
+//
+// We have to negate the nominator to compensate for the negative denominator!
+// Otherwise the phase would be inverted: https://bugs.launchpad.net/mixxx/+bug/1933001
+constexpr CSAMPLE kSampleScaleFactor = -CSAMPLE_PEAK /
(static_cast<FLAC__int32>(1) << std::numeric_limits<FLAC__int32>::digits);
inline CSAMPLE convertDecodedSample(FLAC__int32 decodedSample, int bitsPerSample) {
- DEBUG_ASSERT(std::numeric_limits<FLAC__int32>::is_signed);
- return (decodedSample << ((std::numeric_limits<FLAC__int32>::digits + 1) - bitsPerSample)) * kSampleScaleFactor;
+ static_assert(std::numeric_limits<FLAC__int32>::is_signed);
+ static_assert(kSampleScaleFactor > CSAMPLE_ZERO, "preserve phase of decoded signal");
+ // Multiples by 2 ^ (32 - bitsPerSample)
+ const auto upscaleShift = (std::numeric_limits<FLAC__int32>::digits + 1) - bitsPerSample;
+ const auto upscaledSample = decodedSample << upscaleShift;
+ // upscaledSample is now a 32-bit signed integer that needs to scaled
+ // to the range [-CSAMPLE_PEAK, CSAMPLE_PEAK - epsilon]
+ return upscaledSample * kSampleScaleFactor;
}
} // anonymous namespace