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
diff options
context:
space:
mode:
authorAlex Marsev <alex.marsev@gmail.com>2016-01-24 08:42:32 +0300
committerAlex Marsev <alex.marsev@gmail.com>2016-01-27 09:12:31 +0300
commite574fd060be9858dff383da1ad539d7ee9c6b5d8 (patch)
tree553c6724403a72a7f88ee04c2c867375f389d52c
parentad977e1db88b955eb424158fc808a5fc3f51d037 (diff)
Simplify push mode audio device path
-rw-r--r--src/AudioDevicePush.cpp180
-rw-r--r--src/AudioDevicePush.h16
2 files changed, 20 insertions, 176 deletions
diff --git a/src/AudioDevicePush.cpp b/src/AudioDevicePush.cpp
index e37d286..11518d3 100644
--- a/src/AudioDevicePush.cpp
+++ b/src/AudioDevicePush.cpp
@@ -4,20 +4,13 @@
namespace SaneAudioRenderer
{
AudioDevicePush::AudioDevicePush(std::shared_ptr<AudioDeviceBackend> backend)
- : m_woken(TRUE/*manual reset*/)
{
assert(backend);
assert(!backend->eventMode);
m_backend = backend;
- if (static_cast<HANDLE>(m_wake) == NULL ||
- static_cast<HANDLE>(m_woken) == NULL)
- {
+ if (static_cast<HANDLE>(m_wake) == NULL)
throw E_OUTOFMEMORY;
- }
-
- if (m_backend->realtime)
- m_thread = std::thread(std::bind(&AudioDevicePush::RealtimeFeed, this));
}
AudioDevicePush::~AudioDevicePush()
@@ -34,21 +27,9 @@ namespace SaneAudioRenderer
void AudioDevicePush::Push(DspChunk& chunk, CAMEvent* pFilledEvent)
{
- assert(m_eos == 0);
-
- if (m_backend->realtime)
- {
- PushToBuffer(chunk);
-
- m_wake.Set();
+ assert(!m_endOfStream);
- if (pFilledEvent && !chunk.IsEmpty())
- pFilledEvent->Set();
- }
- else
- {
- PushToDevice(chunk, pFilledEvent);
- }
+ PushChunkToDevice(chunk, pFilledEvent);
}
REFERENCE_TIME AudioDevicePush::Finish(CAMEvent* pFilledEvent)
@@ -56,9 +37,10 @@ namespace SaneAudioRenderer
if (m_error)
throw E_FAIL;
- if (m_eos == 0)
+ if (!m_endOfStream)
{
- m_eos = GetEnd();
+ m_endOfStream = true;
+ m_endOfStreamPos = GetEnd();
try
{
@@ -77,7 +59,7 @@ namespace SaneAudioRenderer
if (pFilledEvent)
pFilledEvent->Set();
- return m_eos - GetPosition();
+ return m_endOfStreamPos - GetPosition();
}
int64_t AudioDevicePush::GetPosition()
@@ -111,7 +93,7 @@ namespace SaneAudioRenderer
void AudioDevicePush::Reset()
{
- if (!m_backend->realtime && m_thread.joinable())
+ if (m_thread.joinable())
{
m_exit = true;
m_wake.Set();
@@ -119,107 +101,12 @@ namespace SaneAudioRenderer
m_exit = false;
}
- {
- CAutoLock threadBusyLock(&m_threadBusyMutex);
-
- m_backend->audioClient->Reset();
- m_pushedFrames = 0;
- m_silenceFrames = 0;
- m_eos = 0;
-
- if (m_backend->realtime)
- {
- m_woken.Reset();
+ m_backend->audioClient->Reset();
+ m_pushedFrames = 0;
+ m_silenceFrames = 0;
- CAutoLock lock(&m_bufferMutex);
- m_bufferFrameCount = 0;
- m_buffer.clear();
- }
- }
-
- if (m_backend->realtime)
- {
- m_wake.Set();
- m_woken.Wait();
- }
- }
-
- void AudioDevicePush::RealtimeFeed()
- {
- SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
- TimePeriodHelper timePeriodHelper(1);
-
- while (!m_exit)
- {
- uint32_t sleepDuration = 0;
-
- {
- CAutoLock busyLock(&m_threadBusyMutex);
-
- if (m_error)
- {
- sleepDuration = INFINITE;
- }
- else
- {
- try
- {
- DspChunk chunk;
-
- {
- CAutoLock lock(&m_bufferMutex);
-
- if (!m_buffer.empty())
- {
- chunk = std::move(m_buffer.front());
- m_buffer.pop_front();
- m_bufferFrameCount -= chunk.GetFrameCount();
- }
- }
-
- if (chunk.IsEmpty())
- {
- REFERENCE_TIME latency = GetStreamLatency() + OneMillisecond * 2;
- REFERENCE_TIME remaining = GetEnd() - GetPosition();
-
- if (remaining < latency)
- m_silenceFrames += PushSilenceToDevice(
- (UINT32)llMulDiv(m_backend->waveFormat->nSamplesPerSec,
- latency - remaining, OneSecond, 0));
-
- sleepDuration = 1;
- }
- else
- {
- PushToDevice(chunk, nullptr);
-
- if (!chunk.IsEmpty())
- {
- {
- CAutoLock lock(&m_bufferMutex);
- m_bufferFrameCount += chunk.GetFrameCount();
- m_buffer.emplace_front(std::move(chunk));
- }
-
- sleepDuration = 1;
- }
- }
- }
- catch (HRESULT)
- {
- m_error = true;
- }
- catch (std::bad_alloc&)
- {
- m_error = true;
- }
- }
-
- m_woken.Set();
- }
-
- m_wake.Wait(sleepDuration);
- }
+ m_endOfStream = false;
+ m_endOfStreamPos = 0;
}
void AudioDevicePush::SilenceFeed()
@@ -230,15 +117,7 @@ namespace SaneAudioRenderer
{
try
{
- REFERENCE_TIME remaining = GetEnd() - GetPosition();
- REFERENCE_TIME buffer = m_backend->bufferDuration * OneMillisecond;
-
- if (remaining < buffer)
- {
- m_silenceFrames += PushSilenceToDevice((UINT32)llMulDiv(m_backend->waveFormat->nSamplesPerSec,
- buffer - remaining, OneSecond, 0));
- }
-
+ m_silenceFrames += PushSilenceToDevice(m_backend->deviceBufferSize);
m_wake.Wait(m_backend->bufferDuration / 4);
}
catch (HRESULT)
@@ -248,7 +127,7 @@ namespace SaneAudioRenderer
}
}
- void AudioDevicePush::PushToDevice(DspChunk& chunk, CAMEvent* pFilledEvent)
+ void AudioDevicePush::PushChunkToDevice(DspChunk& chunk, CAMEvent* pFilledEvent)
{
// Get up-to-date information on the device buffer.
UINT32 bufferPadding;
@@ -303,33 +182,4 @@ namespace SaneAudioRenderer
return doFrames;
}
-
- void AudioDevicePush::PushToBuffer(DspChunk& chunk)
- {
- if (m_error)
- throw E_FAIL;
-
- if (chunk.IsEmpty())
- return;
-
- try
- {
- // Don't deny the allocator its right to reuse
- // IMediaSample while the chunk is hanging in the buffer.
- chunk.FreeMediaSample();
-
- CAutoLock lock(&m_bufferMutex);
-
- if (m_bufferFrameCount > m_backend->waveFormat->nSamplesPerSec / 4) // 250ms
- return;
-
- m_bufferFrameCount += chunk.GetFrameCount();
- m_buffer.emplace_back(std::move(chunk));
- }
- catch (std::bad_alloc&)
- {
- m_error = true;
- throw E_OUTOFMEMORY;
- }
- }
}
diff --git a/src/AudioDevicePush.h b/src/AudioDevicePush.h
index 12e3530..a27dc50 100644
--- a/src/AudioDevicePush.h
+++ b/src/AudioDevicePush.h
@@ -29,26 +29,20 @@ namespace SaneAudioRenderer
private:
- void RealtimeFeed();
void SilenceFeed();
- void PushToDevice(DspChunk& chunk, CAMEvent* pFilledEvent);
+ void PushChunkToDevice(DspChunk& chunk, CAMEvent* pFilledEvent);
UINT32 PushSilenceToDevice(UINT32 frames);
- void PushToBuffer(DspChunk& chunk);
- std::atomic<uint64_t> m_pushedFrames = 0;
+ bool m_endOfStream = false;
+ int64_t m_endOfStreamPos = 0;
+
+ uint64_t m_pushedFrames = 0;
std::atomic<uint64_t> m_silenceFrames = 0;
- int64_t m_eos = 0;
std::thread m_thread;
CAMEvent m_wake;
- CAMEvent m_woken;
- CCritSec m_threadBusyMutex;
std::atomic<bool> m_exit = false;
std::atomic<bool> m_error = false;
-
- std::deque<DspChunk> m_buffer;
- size_t m_bufferFrameCount = 0;
- CCritSec m_bufferMutex;
};
}