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
path: root/src
diff options
context:
space:
mode:
authorAlex Marsev <alex.marsev@gmail.com>2015-10-18 08:56:17 +0300
committerAlex Marsev <alex.marsev@gmail.com>2015-10-18 09:13:50 +0300
commitd2ba13602b0c4508cb81b0cdb4d69c63cbcdb2ca (patch)
treeda3866ac17a9a165931139568faf8d9ef01b5fa0 /src
parent5c40df8c3731956f97b1f65a0aafff93213ed6aa (diff)
Initial implementation of guided reclock
Untested.
Diffstat (limited to 'src')
-rw-r--r--src/MyClock.cpp84
-rw-r--r--src/MyClock.h14
2 files changed, 95 insertions, 3 deletions
diff --git a/src/MyClock.cpp b/src/MyClock.cpp
index c9365ac..4c67f32 100644
--- a/src/MyClock.cpp
+++ b/src/MyClock.cpp
@@ -14,6 +14,9 @@ namespace SaneAudioRenderer
STDMETHODIMP MyClock::NonDelegatingQueryInterface(REFIID riid, void** ppv)
{
+ if (riid == __uuidof(IGuidedReclock))
+ return GetInterface(static_cast<IGuidedReclock*>(this), ppv);
+
return CBaseReferenceClock::NonDelegatingQueryInterface(riid, ppv);
}
@@ -21,6 +24,33 @@ namespace SaneAudioRenderer
{
CAutoLock lock(this);
+ if (m_guidedReclockSlaving)
+ {
+ auto getGuidedReclockTime = [this](int64_t counterTime)
+ {
+ int64_t progress = (int64_t)((counterTime - m_guidedReclockStartTime) * m_guidedReclockMultiplier);
+ return m_guidedReclockStartClock + progress;
+ };
+
+ REFERENCE_TIME audioClockTime, counterTime, clockTime;
+ if (SUCCEEDED(GetAudioClockTime(&audioClockTime, &counterTime)))
+ {
+ clockTime = getGuidedReclockTime(counterTime);
+ int64_t diff = clockTime - audioClockTime;
+ m_audioOffset += diff;
+ m_renderer->TakeGuidedReclock(diff);
+ }
+ else
+ {
+ counterTime = GetCounterTime();
+ clockTime = getGuidedReclockTime(counterTime);
+ }
+
+ m_counterOffset = clockTime - counterTime;
+
+ return clockTime;
+ }
+
REFERENCE_TIME audioClockTime, audioClockCounterTime;
if (SUCCEEDED(GetAudioClockTime(&audioClockTime, &audioClockCounterTime)))
{
@@ -28,7 +58,7 @@ namespace SaneAudioRenderer
return audioClockTime;
}
- return m_counterOffset + llMulDiv(GetPerformanceCounter(), OneSecond, m_performanceFrequency, 0);
+ return m_counterOffset + GetCounterTime();
}
void MyClock::SlaveClockToAudio(IAudioClock* pAudioClock, int64_t audioStart)
@@ -38,6 +68,7 @@ namespace SaneAudioRenderer
m_audioClock = pAudioClock;
m_audioStart = audioStart;
m_audioOffset = 0;
+ m_counterOffset = audioStart - GetCounterTime();
}
void MyClock::UnslaveClockFromAudio()
@@ -66,9 +97,9 @@ namespace SaneAudioRenderer
if (SUCCEEDED(m_audioClock->GetFrequency(&audioFrequency)) &&
SUCCEEDED(m_audioClock->GetPosition(&audioPosition, &audioTime)))
{
- int64_t counterTime = llMulDiv(GetPerformanceCounter(), OneSecond, m_performanceFrequency, 0);
+ int64_t counterTime = GetCounterTime();
int64_t clockTime = llMulDiv(audioPosition, OneSecond, audioFrequency, 0) +
- m_audioStart + (audioPosition > 0 ? m_audioOffset + counterTime - audioTime : 0);
+ m_audioStart + m_audioOffset + (audioPosition > 0 ? counterTime - audioTime : 0);
*pAudioTime = clockTime;
@@ -96,4 +127,51 @@ namespace SaneAudioRenderer
return E_FAIL;
}
+
+ STDMETHODIMP MyClock::SlaveClock(DOUBLE multiplier)
+ {
+ CAutoLock lock(this);
+
+ int64_t time;
+ ReturnIfFailed(GetTime(&time));
+
+ m_guidedReclockSlaving = true;
+ m_guidedReclockMultiplier = multiplier;
+ m_guidedReclockStartTime = GetCounterTime();
+ m_guidedReclockStartClock = time;
+
+ return S_OK;
+ }
+
+ STDMETHODIMP MyClock::UnslaveClock()
+ {
+ CAutoLock lock(this);
+
+ GetPrivateTime();
+ m_guidedReclockSlaving = false;
+
+ return S_OK;
+ }
+
+ STDMETHODIMP MyClock::OffsetClock(LONGLONG offset)
+ {
+ CAutoLock lock(this);
+
+ m_audioOffset += offset;
+ m_counterOffset += offset;
+ m_guidedReclockStartClock += offset;
+
+ m_renderer->TakeGuidedReclock(offset);
+
+ return S_OK;
+ }
+
+ STDMETHODIMP MyClock::GetImmediateTime(LONGLONG* pTime)
+ {
+ CheckPointer(pTime, E_POINTER);
+
+ *pTime = GetPrivateTime();
+
+ return S_OK;
+ }
}
diff --git a/src/MyClock.h b/src/MyClock.h
index 17cb742..8adba99 100644
--- a/src/MyClock.h
+++ b/src/MyClock.h
@@ -8,6 +8,7 @@ namespace SaneAudioRenderer
class MyClock final
: public CBaseReferenceClock
+ , public IGuidedReclock
{
public:
@@ -27,14 +28,27 @@ namespace SaneAudioRenderer
HRESULT GetAudioClockTime(REFERENCE_TIME* pAudioTime, REFERENCE_TIME* pCounterTime);
HRESULT GetAudioClockStartTime(REFERENCE_TIME* pStartTime);
+ STDMETHODIMP SlaveClock(DOUBLE multiplier) override;
+ STDMETHODIMP UnslaveClock() override;
+ STDMETHODIMP OffsetClock(LONGLONG offset) override;
+ STDMETHODIMP GetImmediateTime(LONGLONG* pTime) override;
+
private:
+ int64_t GetCounterTime() { return llMulDiv(GetPerformanceCounter(), OneSecond, m_performanceFrequency, 0); }
+
const std::unique_ptr<AudioRenderer>& m_renderer;
const int64_t m_performanceFrequency;
+
IAudioClockPtr m_audioClock;
int64_t m_audioStart = 0;
int64_t m_audioOffset = 0;
int64_t m_counterOffset = 0;
+
+ bool m_guidedReclockSlaving = false;
+ double m_guidedReclockMultiplier = 1.0;
+ int64_t m_guidedReclockStartTime = 0;
+ int64_t m_guidedReclockStartClock = 0;
};
}