mirror of
https://github.com/dguglielmi/sunny-overlay.git
synced 2025-12-06 13:52:40 +01:00
125 lines
6.2 KiB
Diff
125 lines
6.2 KiB
Diff
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 =
|