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-17 09:32:06 +0300
committerAlex Marsev <alex.marsev@gmail.com>2015-10-18 04:04:54 +0300
commit0d7f5f74140f6be0c480775c92c5e4c49028bcea (patch)
treeb08029bf88a33477f5db7a46bb840f3803e4d752 /src
parent44686e41058059e008eb949b1c842198b0f43fc1 (diff)
Push silence when re-creating audio device
Should minimize re-slaving clock jitter.
Diffstat (limited to 'src')
-rw-r--r--src/AudioRenderer.cpp41
-rw-r--r--src/AudioRenderer.h2
2 files changed, 43 insertions, 0 deletions
diff --git a/src/AudioRenderer.cpp b/src/AudioRenderer.cpp
index b0bdd3f..ed3518f 100644
--- a/src/AudioRenderer.cpp
+++ b/src/AudioRenderer.cpp
@@ -238,6 +238,7 @@ namespace SaneAudioRenderer
m_sampleCorrection.NewDeviceBuffer();
InitializeProcessors();
m_startClockOffset = m_sampleCorrection.GetLastFrameEnd();
+ MinimizeReslavingJitter();
StartDevice();
}
else
@@ -485,7 +486,10 @@ namespace SaneAudioRenderer
m_startClockOffset = m_sampleCorrection.GetLastFrameEnd();
if (m_state == State_Running)
+ {
+ MinimizeReslavingJitter();
StartDevice();
+ }
}
}
@@ -501,6 +505,43 @@ namespace SaneAudioRenderer
}
}
+ void AudioRenderer::MinimizeReslavingJitter()
+ {
+ assert(m_device);
+ assert(m_state == State_Running);
+ assert(m_device->GetEnd() == 0);
+
+ if (m_device->IsBitstream())
+ return;
+
+ // Try to keep inevitable clock jerking to a minimum after re-slaving.
+
+ REFERENCE_TIME silence = m_startClockOffset - (m_myClock.GetPrivateTime() - m_startTime);
+
+ if (!m_device->IsExclusive())
+ silence -= m_device->GetStreamLatency();
+
+ if (silence > 0)
+ {
+ silence = std::min(silence, llMulDiv(m_device->GetBufferDuration(), OneSecond, 1000, 0));
+
+ uint32_t rate = m_device->GetWaveFormat()->nSamplesPerSec;
+ DspChunk chunk(m_device->GetDspFormat(), m_device->GetWaveFormat()->nChannels,
+ (size_t)llMulDiv(silence, rate, OneSecond, 0), rate);
+
+ if (!chunk.IsEmpty())
+ {
+ m_startClockOffset -= llMulDiv(chunk.GetFrameCount(), OneSecond, rate, 0);
+
+ DebugOut("AudioRenderer insert", chunk.GetFrameCount() * 1000. / rate,
+ "ms of silence to minimize re-slaving jitter");
+
+ ZeroMemory(chunk.GetData(), chunk.GetSize());
+ PushToDevice(chunk, nullptr);
+ }
+ }
+ }
+
void AudioRenderer::ApplyClockCorrection()
{
CAutoLock objectLock(this);
diff --git a/src/AudioRenderer.h b/src/AudioRenderer.h
index a09de1b..d90a4f7 100644
--- a/src/AudioRenderer.h
+++ b/src/AudioRenderer.h
@@ -65,6 +65,8 @@ namespace SaneAudioRenderer
void CreateDevice();
void ClearDevice();
+ void MinimizeReslavingJitter();
+
void ApplyClockCorrection();
void ApplyRateCorrection(DspChunk& chunk);