mirror of
https://github.com/dguglielmi/sunny-overlay.git
synced 2025-12-06 13:52:40 +01:00
media-sound/mixxx: update pre-2.1.1 patches #3
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
From 901b65b785f6c55e7b484350fea02b6d328e8094 Mon Sep 17 00:00:00 2001
|
||||
From: Uwe Klotz <uklotz@mixxx.org>
|
||||
Date: Wed, 25 Apr 2018 11:17:00 +0200
|
||||
Subject: [PATCH 1/2] Windows MF: Fix rounding errors when seeking and reading
|
||||
|
||||
---
|
||||
.../soundsourcemediafoundation.h | 37 ++++++++++++----------
|
||||
1 file changed, 21 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/plugins/soundsourcemediafoundation/soundsourcemediafoundation.h b/plugins/soundsourcemediafoundation/soundsourcemediafoundation.h
|
||||
index 7e1abf4da5..e9a8d608f1 100755
|
||||
--- a/plugins/soundsourcemediafoundation/soundsourcemediafoundation.h
|
||||
+++ b/plugins/soundsourcemediafoundation/soundsourcemediafoundation.h
|
||||
@@ -17,37 +17,42 @@ class StreamUnitConverter final {
|
||||
public:
|
||||
StreamUnitConverter()
|
||||
: m_pAudioSource(nullptr),
|
||||
- m_streamUnitsPerFrame(0.0),
|
||||
- m_toFrameIndexBias(0) {
|
||||
+ m_fromSampleFramesToStreamUnits(0),
|
||||
+ m_fromStreamUnitsToSampleFrames(0) {
|
||||
}
|
||||
explicit StreamUnitConverter(const AudioSource* pAudioSource)
|
||||
: m_pAudioSource(pAudioSource),
|
||||
- m_streamUnitsPerFrame(double(kStreamUnitsPerSecond) / double(pAudioSource->sampleRate())),
|
||||
- m_toFrameIndexBias(kStreamUnitsPerSecond / pAudioSource->sampleRate() / 2) {
|
||||
- // The stream units should actually be much shorter
|
||||
- // than the frames to minimize jitter. Even a frame
|
||||
- // at 192 kHz has a length of about 5000 ns >> 100 ns.
|
||||
- DEBUG_ASSERT(m_streamUnitsPerFrame >= 50);
|
||||
- DEBUG_ASSERT(m_toFrameIndexBias > 0);
|
||||
+ m_fromSampleFramesToStreamUnits(double(kStreamUnitsPerSecond) / double(pAudioSource->sampleRate())),
|
||||
+ m_fromStreamUnitsToSampleFrames(double(pAudioSource->sampleRate()) / double(kStreamUnitsPerSecond)){
|
||||
+ // The stream units should actually be much shorter than
|
||||
+ // sample frames to minimize jitter and rounding. Even a
|
||||
+ // frame at 192 kHz has a length of about 5000 ns >> 100 ns.
|
||||
+ DEBUG_ASSERT(m_fromStreamUnitsToSampleFrames >= 50);
|
||||
}
|
||||
|
||||
LONGLONG fromFrameIndex(SINT frameIndex) const {
|
||||
+ DEBUG_ASSERT(m_fromSampleFramesToStreamUnits > 0);
|
||||
// Used for seeking, so we need to round down to hit the
|
||||
// corresponding stream unit where the given stream unit
|
||||
- // starts
|
||||
- return floor((frameIndex - m_pAudioSource->frameIndexMin()) * m_streamUnitsPerFrame);
|
||||
+ // starts. The reader will skip samples until it reaches
|
||||
+ // the actual target position for reading.
|
||||
+ const SINT frameIndexOffset = frameIndex - m_pAudioSource->frameIndexMin();
|
||||
+ return static_cast<LONGLONG>(floor(frameIndexOffset * m_fromSampleFramesToStreamUnits));
|
||||
}
|
||||
|
||||
SINT toFrameIndex(LONGLONG streamPos) const {
|
||||
- // NOTE(uklotzde): Add m_toFrameIndexBias to account for rounding errors
|
||||
- return m_pAudioSource->frameIndexMin() +
|
||||
- static_cast<SINT>(floor((streamPos + m_toFrameIndexBias) / m_streamUnitsPerFrame));
|
||||
+ DEBUG_ASSERT(m_fromStreamUnitsToSampleFrames > 0);
|
||||
+ // The stream reports positions in units of 100ns. We have
|
||||
+ // to round(!) this value to obtain the actual position in
|
||||
+ // sample frames.
|
||||
+ const SINT frameIndexOffset = static_cast<SINT>(round(streamPos * m_fromStreamUnitsToSampleFrames));
|
||||
+ return m_pAudioSource->frameIndexMin() + frameIndexOffset;
|
||||
}
|
||||
|
||||
private:
|
||||
const AudioSource* m_pAudioSource;
|
||||
- double m_streamUnitsPerFrame;
|
||||
- SINT m_toFrameIndexBias;
|
||||
+ double m_fromSampleFramesToStreamUnits;
|
||||
+ double m_fromStreamUnitsToSampleFrames;
|
||||
};
|
||||
|
||||
class SoundSourceMediaFoundation: public mixxx::SoundSourcePlugin {
|
||||
|
||||
From e9474dcdf752d51fc3390ff6851c02f8e249fb4d Mon Sep 17 00:00:00 2001
|
||||
From: Uwe Klotz <uklotz@mixxx.org>
|
||||
Date: Wed, 25 Apr 2018 16:24:35 +0200
|
||||
Subject: [PATCH 2/2] Windows MF: Validate the current position while reading
|
||||
|
||||
...and avoid to update if not necessary to prevent rounding errors.
|
||||
Just log any suspicious values.
|
||||
---
|
||||
.../soundsourcemediafoundation.cpp | 29 +++++++++++++++++++---
|
||||
1 file changed, 25 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/plugins/soundsourcemediafoundation/soundsourcemediafoundation.cpp b/plugins/soundsourcemediafoundation/soundsourcemediafoundation.cpp
|
||||
index 3ed0d3b5e8..8eac78220d 100755
|
||||
--- a/plugins/soundsourcemediafoundation/soundsourcemediafoundation.cpp
|
||||
+++ b/plugins/soundsourcemediafoundation/soundsourcemediafoundation.cpp
|
||||
@@ -351,10 +351,31 @@ ReadableSampleFrames SoundSourceMediaFoundation::readSampleFramesClamped(
|
||||
}
|
||||
DEBUG_ASSERT(pSample != nullptr);
|
||||
SINT readerFrameIndex = m_streamUnitConverter.toFrameIndex(streamPos);
|
||||
- DEBUG_ASSERT(
|
||||
- (m_currentFrameIndex == kUnknownFrameIndex) || // unknown position after seeking
|
||||
- (m_currentFrameIndex == readerFrameIndex));
|
||||
- m_currentFrameIndex = readerFrameIndex;
|
||||
+ if (m_currentFrameIndex == kUnknownFrameIndex) {
|
||||
+ // Unknown position after seeking
|
||||
+ m_currentFrameIndex = readerFrameIndex;
|
||||
+ /*
|
||||
+ kLogger.debug()
|
||||
+ << "Stream position (in sample frames) after seeking:"
|
||||
+ << "target =" << writableSampleFrames.frameIndexRange().end()
|
||||
+ << "current =" << readerFrameIndex;
|
||||
+ */
|
||||
+ } else {
|
||||
+ // Both positions should match, otherwise readerFrameIndex
|
||||
+ // is inaccurate due to rounding errors after conversion from
|
||||
+ // stream units to frames! But if this ever happens we better
|
||||
+ // trust m_currentFrameIndex that is continuously updated while
|
||||
+ // reading in forward direction.
|
||||
+ VERIFY_OR_DEBUG_ASSERT(m_currentFrameIndex == readerFrameIndex) {
|
||||
+ kLogger.debug()
|
||||
+ << "streamPos [100 ns] =" << streamPos
|
||||
+ << ", sampleRate [Hz] =" << sampleRate();
|
||||
+ kLogger.warning()
|
||||
+ << "Stream position (in sample frames) while reading is inaccurate:"
|
||||
+ << "expected =" << m_currentFrameIndex
|
||||
+ << "actual =" << readerFrameIndex;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
DWORD dwSampleBufferCount = 0;
|
||||
HRESULT hrGetBufferCount =
|
||||
@@ -0,0 +1,164 @@
|
||||
From 901cacb96a0c3898b7b7af3cddd87e0d02f67235 Mon Sep 17 00:00:00 2001
|
||||
From: Uwe Klotz <uklotz@mixxx.org>
|
||||
Date: Sat, 12 May 2018 00:20:59 +0200
|
||||
Subject: [PATCH] Fix CachingReader compiler warnings about non-trivial types
|
||||
|
||||
---
|
||||
src/engine/cachingreader.cpp | 8 ++++----
|
||||
src/engine/cachingreaderworker.cpp | 17 +++++++++++------
|
||||
src/engine/cachingreaderworker.h | 36 ++++++++++++++++++++++--------------
|
||||
3 files changed, 37 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/src/engine/cachingreader.cpp b/src/engine/cachingreader.cpp
|
||||
index 2764e5c96c..2440b3a8f8 100644
|
||||
--- a/src/engine/cachingreader.cpp
|
||||
+++ b/src/engine/cachingreader.cpp
|
||||
@@ -204,7 +204,7 @@ void CachingReader::process() {
|
||||
} else if (status.status == TRACK_LOADED) {
|
||||
m_readerStatus = status.status;
|
||||
// Reset the max. readable frame index
|
||||
- m_readableFrameIndexRange = status.readableFrameIndexRange;
|
||||
+ m_readableFrameIndexRange = status.readableFrameIndexRange();
|
||||
// Free all chunks with sample data from a previous track
|
||||
freeAllChunks();
|
||||
}
|
||||
@@ -212,7 +212,7 @@ void CachingReader::process() {
|
||||
// Adjust the readable frame index range after loading or reading
|
||||
m_readableFrameIndexRange = intersect(
|
||||
m_readableFrameIndexRange,
|
||||
- status.readableFrameIndexRange);
|
||||
+ status.readableFrameIndexRange());
|
||||
} else {
|
||||
// Reset the readable frame index range
|
||||
m_readableFrameIndexRange = mixxx::IndexRange();
|
||||
@@ -467,8 +467,8 @@ void CachingReader::hintAndMaybeWake(const HintVector& hintList) {
|
||||
}
|
||||
// Do not insert the allocated chunk into the MRU/LRU list,
|
||||
// because it will be handed over to the worker immediately
|
||||
- CachingReaderChunkReadRequest request(pChunk);
|
||||
- pChunk->giveToWorker();
|
||||
+ CachingReaderChunkReadRequest request;
|
||||
+ request.giveToWorker(pChunk);
|
||||
// kLogger.debug() << "Requesting read of chunk" << current << "into" << pChunk;
|
||||
// kLogger.debug() << "Requesting read into " << request.chunk->data;
|
||||
if (m_chunkReadRequestFIFO.write(&request, 1) != 1) {
|
||||
diff --git a/src/engine/cachingreaderworker.cpp b/src/engine/cachingreaderworker.cpp
|
||||
index 600389f86f..34f9a9ac83 100644
|
||||
--- a/src/engine/cachingreaderworker.cpp
|
||||
+++ b/src/engine/cachingreaderworker.cpp
|
||||
@@ -42,7 +42,9 @@ ReaderStatusUpdate CachingReaderWorker::processReadRequest(
|
||||
// actually available.
|
||||
const auto chunkFrameIndexRange = pChunk->frameIndexRange(m_pAudioSource);
|
||||
if (intersect(chunkFrameIndexRange, m_readableFrameIndexRange).empty()) {
|
||||
- return ReaderStatusUpdate(CHUNK_READ_INVALID, pChunk, m_readableFrameIndexRange);
|
||||
+ ReaderStatusUpdate result;
|
||||
+ result.init(CHUNK_READ_INVALID, pChunk, m_readableFrameIndexRange);
|
||||
+ return result;
|
||||
}
|
||||
|
||||
// Try to read the data required for the chunk from the audio source
|
||||
@@ -77,7 +79,9 @@ ReaderStatusUpdate CachingReaderWorker::processReadRequest(
|
||||
<< "from originally"
|
||||
<< m_pAudioSource->frameIndexRange();
|
||||
}
|
||||
- return ReaderStatusUpdate(status, pChunk, m_readableFrameIndexRange);
|
||||
+ ReaderStatusUpdate result;
|
||||
+ result.init(status, pChunk, m_readableFrameIndexRange);
|
||||
+ return result;
|
||||
}
|
||||
|
||||
// WARNING: Always called from a different thread (GUI)
|
||||
@@ -91,10 +95,10 @@ void CachingReaderWorker::run() {
|
||||
unsigned static id = 0; //the id of this thread, for debugging purposes
|
||||
QThread::currentThread()->setObjectName(QString("CachingReaderWorker %1").arg(++id));
|
||||
|
||||
- CachingReaderChunkReadRequest request;
|
||||
-
|
||||
Event::start(m_tag);
|
||||
while (!load_atomic(m_stop)) {
|
||||
+ // Request is initialized by reading from FIFO
|
||||
+ CachingReaderChunkReadRequest request;
|
||||
if (m_newTrackAvailable) {
|
||||
TrackPointer pLoadTrack;
|
||||
{ // locking scope
|
||||
@@ -130,7 +134,7 @@ mixxx::AudioSourcePointer openAudioSourceForReading(const TrackPointer& pTrack,
|
||||
|
||||
void CachingReaderWorker::loadTrack(const TrackPointer& pTrack) {
|
||||
ReaderStatusUpdate status;
|
||||
- status.status = TRACK_NOT_LOADED;
|
||||
+ status.init(TRACK_NOT_LOADED);
|
||||
|
||||
if (!pTrack) {
|
||||
// Unload track
|
||||
@@ -179,8 +183,9 @@ void CachingReaderWorker::loadTrack(const TrackPointer& pTrack) {
|
||||
// be decreased to avoid repeated reading of corrupt audio data.
|
||||
m_readableFrameIndexRange = m_pAudioSource->frameIndexRange();
|
||||
|
||||
- status.readableFrameIndexRange = m_readableFrameIndexRange;
|
||||
status.status = TRACK_LOADED;
|
||||
+ status.readableFrameIndexRangeStart = m_readableFrameIndexRange.start();
|
||||
+ status.readableFrameIndexRangeEnd = m_readableFrameIndexRange.end();
|
||||
m_pReaderStatusFIFO->writeBlocking(&status, 1);
|
||||
|
||||
// Clear the chunks to read list.
|
||||
diff --git a/src/engine/cachingreaderworker.h b/src/engine/cachingreaderworker.h
|
||||
index 4d60e7c3ed..54c5a4c77e 100644
|
||||
--- a/src/engine/cachingreaderworker.h
|
||||
+++ b/src/engine/cachingreaderworker.h
|
||||
@@ -14,12 +14,14 @@
|
||||
#include "util/fifo.h"
|
||||
|
||||
|
||||
+// POD with trivial ctor/dtor/copy for passing through FIFO
|
||||
typedef struct CachingReaderChunkReadRequest {
|
||||
CachingReaderChunk* chunk;
|
||||
|
||||
- explicit CachingReaderChunkReadRequest(
|
||||
- CachingReaderChunk* chunkArg = nullptr)
|
||||
- : chunk(chunkArg) {
|
||||
+ void giveToWorker(CachingReaderChunkForOwner* chunkForOwner) {
|
||||
+ DEBUG_ASSERT(chunkForOwner);
|
||||
+ chunk = chunkForOwner;
|
||||
+ chunkForOwner->giveToWorker();
|
||||
}
|
||||
} CachingReaderChunkReadRequest;
|
||||
|
||||
@@ -32,21 +34,27 @@ enum ReaderStatus {
|
||||
CHUNK_READ_INVALID
|
||||
};
|
||||
|
||||
+// POD with trivial ctor/dtor/copy for passing through FIFO
|
||||
typedef struct ReaderStatusUpdate {
|
||||
ReaderStatus status;
|
||||
CachingReaderChunk* chunk;
|
||||
- mixxx::IndexRange readableFrameIndexRange;
|
||||
- ReaderStatusUpdate()
|
||||
- : status(INVALID)
|
||||
- , chunk(nullptr) {
|
||||
+ SINT readableFrameIndexRangeStart;
|
||||
+ SINT readableFrameIndexRangeEnd;
|
||||
+
|
||||
+ void init(
|
||||
+ ReaderStatus statusArg = INVALID,
|
||||
+ CachingReaderChunk* chunkArg = nullptr,
|
||||
+ const mixxx::IndexRange& readableFrameIndexRangeArg = mixxx::IndexRange()) {
|
||||
+ status = statusArg;
|
||||
+ chunk = chunkArg;
|
||||
+ readableFrameIndexRangeStart = readableFrameIndexRangeArg.start();
|
||||
+ readableFrameIndexRangeEnd = readableFrameIndexRangeArg.end();
|
||||
}
|
||||
- ReaderStatusUpdate(
|
||||
- ReaderStatus statusArg,
|
||||
- CachingReaderChunk* chunkArg,
|
||||
- const mixxx::IndexRange& readableFrameIndexRangeArg)
|
||||
- : status(statusArg)
|
||||
- , chunk(chunkArg)
|
||||
- , readableFrameIndexRange(readableFrameIndexRangeArg) {
|
||||
+
|
||||
+ mixxx::IndexRange readableFrameIndexRange() const {
|
||||
+ return mixxx::IndexRange::between(
|
||||
+ readableFrameIndexRangeStart,
|
||||
+ readableFrameIndexRangeEnd);
|
||||
}
|
||||
} ReaderStatusUpdate;
|
||||
|
||||
208
media-sound/mixxx/files/mixxx-2.1.0-optimize-flac-decoding.patch
Normal file
208
media-sound/mixxx/files/mixxx-2.1.0-optimize-flac-decoding.patch
Normal file
@@ -0,0 +1,208 @@
|
||||
From 497e9672dfd1079e28cadc9a413a0b8be00ed59d Mon Sep 17 00:00:00 2001
|
||||
From: Uwe Klotz <uklotz@mixxx.org>
|
||||
Date: Wed, 9 May 2018 12:08:59 +0200
|
||||
Subject: [PATCH 1/4] Optimize FLAC decoding
|
||||
|
||||
---
|
||||
src/sources/soundsourceflac.cpp | 51 ++++++++++++++++++++---------------------
|
||||
src/sources/soundsourceflac.h | 2 --
|
||||
2 files changed, 25 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/src/sources/soundsourceflac.cpp b/src/sources/soundsourceflac.cpp
|
||||
index 3d68e05ce7..50cb0955e6 100644
|
||||
--- a/src/sources/soundsourceflac.cpp
|
||||
+++ b/src/sources/soundsourceflac.cpp
|
||||
@@ -71,7 +71,6 @@ SoundSourceFLAC::SoundSourceFLAC(const QUrl& url)
|
||||
m_decoder(nullptr),
|
||||
m_maxBlocksize(0),
|
||||
m_bitsPerSample(kBitsPerSampleDefault),
|
||||
- m_sampleScaleFactor(CSAMPLE_ZERO),
|
||||
m_curFrameIndex(0) {
|
||||
}
|
||||
|
||||
@@ -345,25 +344,30 @@ FLAC__bool SoundSourceFLAC::flacEOF() {
|
||||
return m_file.atEnd();
|
||||
}
|
||||
|
||||
+namespace {
|
||||
+
|
||||
+// Workaround for improperly encoded FLAC files that may contain
|
||||
+// garbage in the most significant, unused bits of decoded samples.
|
||||
+// Required at least for libFLAC 1.3.2. This workaround might become
|
||||
+// obsolete once libFLAC is taking care of these issues internally.
|
||||
+// 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.
|
||||
+// The range of decoded integer sample values then becomes
|
||||
+// [-2 ^ 31, 2 ^ 31 - 1]. Afterwards this integer range needs to be
|
||||
+// scaled to [-CSAMPLE_PEAK, CSAMPLE_PEAK).
|
||||
+
|
||||
+const CSAMPLE kSampleScaleFactor = CSAMPLE_PEAK / (static_cast<FLAC__int32>(1) << 31);
|
||||
+
|
||||
inline
|
||||
-FLAC__int32 adjustDecodedSample(FLAC__int32 decodedSample, SINT bitsPerSample) {
|
||||
- // Workaround for improperly encoded FLAC files that may contain
|
||||
- // garbage in the most significant, unused bits of decoded samples.
|
||||
- // Required at least for libFLAC 1.3.2. This workaround might become
|
||||
- // obsolete once libFLAC is taking care of these issues internally.
|
||||
- // https://bugs.launchpad.net/mixxx/+bug/1769717
|
||||
- // https://hydrogenaud.io/index.php/topic,61792.msg559045.html#msg559045
|
||||
- FLAC__int32 signBit = static_cast<FLAC__int32>(1) << (bitsPerSample - 1);
|
||||
- FLAC__int32 bitMask = (static_cast<FLAC__int32>(1) << bitsPerSample) - 1; // == (signBit << 1) - 1
|
||||
- FLAC__int32 maskedSample = decodedSample & bitMask;
|
||||
- if (maskedSample & signBit) {
|
||||
- // Sign extension for negative values
|
||||
- return maskedSample | ~bitMask;
|
||||
- } else {
|
||||
- return maskedSample;
|
||||
- }
|
||||
+CSAMPLE convertDecodedSample(FLAC__int32 decodedSample, int bitsPerSample) {
|
||||
+ return (decodedSample << (32 - bitsPerSample)) * kSampleScaleFactor;
|
||||
}
|
||||
|
||||
+} // anonymous namespace
|
||||
+
|
||||
FLAC__StreamDecoderWriteStatus SoundSourceFLAC::flacWrite(
|
||||
const FLAC__Frame* frame, const FLAC__int32* const buffer[]) {
|
||||
const SINT numChannels = frame->header.channels;
|
||||
@@ -410,15 +414,15 @@ FLAC__StreamDecoderWriteStatus SoundSourceFLAC::flacWrite(
|
||||
case 1: {
|
||||
// optimized code for 1 channel (mono)
|
||||
for (SINT i = 0; i < numWritableFrames; ++i) {
|
||||
- *pSampleBuffer++ = adjustDecodedSample(buffer[0][i], m_bitsPerSample) * m_sampleScaleFactor;
|
||||
+ *pSampleBuffer++ = convertDecodedSample(buffer[0][i], m_bitsPerSample);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
// optimized code for 2 channels (stereo)
|
||||
for (SINT i = 0; i < numWritableFrames; ++i) {
|
||||
- *pSampleBuffer++ = adjustDecodedSample(buffer[0][i], m_bitsPerSample) * m_sampleScaleFactor;
|
||||
- *pSampleBuffer++ = adjustDecodedSample(buffer[1][i], m_bitsPerSample) * m_sampleScaleFactor;
|
||||
+ *pSampleBuffer++ = convertDecodedSample(buffer[0][i], m_bitsPerSample);
|
||||
+ *pSampleBuffer++ = convertDecodedSample(buffer[1][i], m_bitsPerSample);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -426,7 +430,7 @@ FLAC__StreamDecoderWriteStatus SoundSourceFLAC::flacWrite(
|
||||
// generic code for multiple channels
|
||||
for (SINT i = 0; i < numWritableFrames; ++i) {
|
||||
for (SINT j = 0; j < channelCount(); ++j) {
|
||||
- *pSampleBuffer++ = adjustDecodedSample(buffer[j][i], m_bitsPerSample) * m_sampleScaleFactor;
|
||||
+ *pSampleBuffer++ = convertDecodedSample(buffer[j][i], m_bitsPerSample);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -456,11 +460,6 @@ void SoundSourceFLAC::flacMetadata(const FLAC__StreamMetadata* metadata) {
|
||||
// not set before
|
||||
if ((bitsPerSample >= 4) && (bitsPerSample <= 32)) {
|
||||
m_bitsPerSample = bitsPerSample;
|
||||
- // Range of signed) sample values: [-2 ^ (bitsPerSample - 1), 2 ^ (bitsPerSample - 1) - 1]
|
||||
- const uint32_t absSamplePeak = 1u << (bitsPerSample - 1);
|
||||
- DEBUG_ASSERT(absSamplePeak > 0);
|
||||
- // Scaled range of samples values: [-CSAMPLE_PEAK, CSAMPLE_PEAK)
|
||||
- m_sampleScaleFactor = CSAMPLE_PEAK / absSamplePeak;
|
||||
} else {
|
||||
kLogger.warning()
|
||||
<< "Invalid bits per sample:"
|
||||
diff --git a/src/sources/soundsourceflac.h b/src/sources/soundsourceflac.h
|
||||
index 05c74f7b5e..f4b3c1cb3c 100644
|
||||
--- a/src/sources/soundsourceflac.h
|
||||
+++ b/src/sources/soundsourceflac.h
|
||||
@@ -49,8 +49,6 @@ class SoundSourceFLAC: public SoundSource {
|
||||
SINT m_maxBlocksize; // in time samples (audio samples = time samples * chanCount)
|
||||
SINT m_bitsPerSample;
|
||||
|
||||
- CSAMPLE m_sampleScaleFactor;
|
||||
-
|
||||
ReadAheadSampleBuffer m_sampleBuffer;
|
||||
|
||||
void invalidateCurFrameIndex() {
|
||||
|
||||
From 24c206f60278b8e9576ae661643162512ff1d19b Mon Sep 17 00:00:00 2001
|
||||
From: Uwe Klotz <uklotz@mixxx.org>
|
||||
Date: Wed, 9 May 2018 12:14:31 +0200
|
||||
Subject: [PATCH 2/4] Add an assertion (just in case)
|
||||
|
||||
---
|
||||
src/sources/soundsourceflac.cpp | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/sources/soundsourceflac.cpp b/src/sources/soundsourceflac.cpp
|
||||
index 50cb0955e6..c01ab8455d 100644
|
||||
--- a/src/sources/soundsourceflac.cpp
|
||||
+++ b/src/sources/soundsourceflac.cpp
|
||||
@@ -363,6 +363,7 @@ const CSAMPLE kSampleScaleFactor = CSAMPLE_PEAK / (static_cast<FLAC__int32>(1) <
|
||||
|
||||
inline
|
||||
CSAMPLE convertDecodedSample(FLAC__int32 decodedSample, int bitsPerSample) {
|
||||
+ DEBUG_ASSERT(sizeof(FLAC__int32) == 32); // exactly 32-bits required!
|
||||
return (decodedSample << (32 - bitsPerSample)) * kSampleScaleFactor;
|
||||
}
|
||||
|
||||
|
||||
From 6dc1d5f1a7e291c36d5828fdaecc82a62845b758 Mon Sep 17 00:00:00 2001
|
||||
From: Uwe Klotz <uklotz@mixxx.org>
|
||||
Date: Wed, 9 May 2018 12:25:00 +0200
|
||||
Subject: [PATCH 3/4] Get rid of (most) implicit assumptions
|
||||
|
||||
---
|
||||
src/sources/soundsourceflac.cpp | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/sources/soundsourceflac.cpp b/src/sources/soundsourceflac.cpp
|
||||
index c01ab8455d..478bac870e 100644
|
||||
--- a/src/sources/soundsourceflac.cpp
|
||||
+++ b/src/sources/soundsourceflac.cpp
|
||||
@@ -359,12 +359,12 @@ namespace {
|
||||
// [-2 ^ 31, 2 ^ 31 - 1]. Afterwards this integer range needs to be
|
||||
// scaled to [-CSAMPLE_PEAK, CSAMPLE_PEAK).
|
||||
|
||||
-const CSAMPLE kSampleScaleFactor = CSAMPLE_PEAK / (static_cast<FLAC__int32>(1) << 31);
|
||||
+const 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(sizeof(FLAC__int32) == 32); // exactly 32-bits required!
|
||||
- return (decodedSample << (32 - bitsPerSample)) * kSampleScaleFactor;
|
||||
+ DEBUG_ASSERT(std::numeric_limits<FLAC__int32>::is_signed);
|
||||
+ return (decodedSample << ((std::numeric_limits<FLAC__int32>::digits + 1) - bitsPerSample)) * kSampleScaleFactor;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
From a0430875f6c4ad89c0fb09300ed19a64c60bbfb4 Mon Sep 17 00:00:00 2001
|
||||
From: Uwe Klotz <uklotz@mixxx.org>
|
||||
Date: Wed, 9 May 2018 15:16:58 +0200
|
||||
Subject: [PATCH 4/4] Use constexpr and reword comments
|
||||
|
||||
---
|
||||
src/sources/soundsourceflac.cpp | 12 +++++-------
|
||||
1 file changed, 5 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/sources/soundsourceflac.cpp b/src/sources/soundsourceflac.cpp
|
||||
index 478bac870e..1a95ac168c 100644
|
||||
--- a/src/sources/soundsourceflac.cpp
|
||||
+++ b/src/sources/soundsourceflac.cpp
|
||||
@@ -352,14 +352,12 @@ namespace {
|
||||
// obsolete once libFLAC is taking care of these issues internally.
|
||||
// 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.
|
||||
-// The range of decoded integer sample values then becomes
|
||||
-// [-2 ^ 31, 2 ^ 31 - 1]. Afterwards this integer range needs to be
|
||||
-// scaled to [-CSAMPLE_PEAK, CSAMPLE_PEAK).
|
||||
|
||||
-const CSAMPLE kSampleScaleFactor = CSAMPLE_PEAK / (static_cast<FLAC__int32>(1) << std::numeric_limits<FLAC__int32>::digits);
|
||||
+// 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 / (static_cast<FLAC__int32>(1) << std::numeric_limits<FLAC__int32>::digits);
|
||||
|
||||
inline
|
||||
CSAMPLE convertDecodedSample(FLAC__int32 decodedSample, int bitsPerSample) {
|
||||
Reference in New Issue
Block a user