summaryrefslogtreecommitdiffstats
path: root/src/sources
diff options
context:
space:
mode:
authorUwe Klotz <uklotz@mixxx.org>2021-06-19 17:37:12 +0200
committerUwe Klotz <uklotz@mixxx.org>2021-06-19 17:39:43 +0200
commitb0cb80b82724a0bc2277bdf148dd65ffdb7ba72d (patch)
tree3369f3669c80bcd5da509e12efc0a4eef77887a3 /src/sources
parentb49f33b6daa86c2a88b4e096eedd18815ef25245 (diff)
lp1933001: Preserve phase of decoded FLAC samples
Diffstat (limited to 'src/sources')
-rw-r--r--src/sources/soundsourceflac.cpp12
1 files changed, 9 insertions, 3 deletions
diff --git a/src/sources/soundsourceflac.cpp b/src/sources/soundsourceflac.cpp
index a6624a7e82..9c0ba7a5c3 100644
--- a/src/sources/soundsourceflac.cpp
+++ b/src/sources/soundsourceflac.cpp
@@ -403,12 +403,18 @@ namespace {
// 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 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 kSampleUnshiftFactor = -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(kSampleUnshiftFactor > CSAMPLE_ZERO, "preserve phase of decoded signal");
+ const auto leftShift = (std::numeric_limits<FLAC__int32>::digits + 1) - bitsPerSample;
+ const auto shiftedSample = decodedSample << leftShift;
+ return shiftedSample * kSampleUnshiftFactor;
}
} // anonymous namespace