diff options
author | Luo Jinghua <sunmoon1997@gmail.com> | 2012-11-27 14:00:15 +0800 |
---|---|---|
committer | Luo Jinghua <sunmoon1997@gmail.com> | 2012-11-27 14:20:34 +0800 |
commit | dc69d7d189870b6e33f30846f5ec7c093f121183 (patch) | |
tree | bae4d981dd64d29c79474a4fadfcf0bbd3a03baf /src | |
parent | 2102c82899d1a64108f0d00ef4840edc14a5e388 (diff) |
Add another mixer thread which spawn a dedicate thread to send audio data to output device
Diffstat (limited to 'src')
-rw-r--r-- | src/device_mixer.cpp | 86 | ||||
-rw-r--r-- | src/device_mixer.h | 23 |
2 files changed, 109 insertions, 0 deletions
diff --git a/src/device_mixer.cpp b/src/device_mixer.cpp index 1529c78..47b5fed 100644 --- a/src/device_mixer.cpp +++ b/src/device_mixer.cpp @@ -394,4 +394,90 @@ namespace audiere { m_shutdown = true; m_cond.notify(); } + + ThreadedMixerDevice::ThreadedMixerDevice(int rate, int block_size, int queue_len) + : MixerDevice(rate) { + m_thread_should_die = false; + m_thread_exists = false; + m_queue = new AudioQueue(block_size, queue_len); + } + + + ThreadedMixerDevice::~ThreadedMixerDevice() { + ADR_GUARD("ThreadedMixerDevice::~ThreadedMixerDevice"); + shutdown(); + + delete m_queue; + } + + void + ThreadedMixerDevice::start() { + ADR_GUARD("ThreadedMixerDevice::start"); + m_thread_should_die = false; + m_thread_exists = false; + AI_CreateThread(outputThreadRoutine, this); + } + + void + ThreadedMixerDevice::shutdown() { + ADR_GUARD("ThreadedMixerDevice::shutdown"); + m_thread_should_die = true; + m_queue->shutdown(); + + while (m_thread_exists) + AI_Sleep(10); + } + + + void + ThreadedMixerDevice::outputThreadRoutine(void* arg) { + ADR_GUARD("ThreadedDevice::outputThreadRoutine"); + if (arg) { + ADR_LOG("arg is valid"); + } else { + ADR_LOG("arg is not valid"); + } + + ThreadedMixerDevice* This = (ThreadedMixerDevice*)arg; + This->output(); + } + + + void + ThreadedMixerDevice::output() { + ADR_GUARD("ThreadedMixerDevice::output"); + m_thread_exists = true; + while (!m_thread_should_die) { + AudioBuffer* buffer = m_queue->pop(); + if (!buffer) + continue; + + outputBuffer(buffer->m_buf, buffer->m_size); + m_queue->put_buffer(buffer); + } + m_thread_exists = false; + } + + + void ADR_CALL + ThreadedMixerDevice::update() { + AudioBuffer* buffer = m_queue->get_buffer(); + if (!buffer) { + AI_Sleep(5); + return; + } + + int sample_len; + size_t sample_left; + char* sample_buf; + + sample_buf = buffer->m_buf; + sample_len = buffer->m_size / 4; + + sample_left = read(sample_len, sample_buf); + (void)sample_left; + if (!m_queue->push(buffer)) + m_queue->put_buffer(buffer); + } + } diff --git a/src/device_mixer.h b/src/device_mixer.h index eb2ece0..a87ec95 100644 --- a/src/device_mixer.h +++ b/src/device_mixer.h @@ -139,6 +139,29 @@ namespace audiere { bool m_shutdown; }; + /// Always produce 16-bit, stereo audio at the specified rate. + class ThreadedMixerDevice : public MixerDevice { + public: + ThreadedMixerDevice(int rate, int block_size = 4096, int queue_len = 8); + ~ThreadedMixerDevice(); + + public: + virtual void ADR_CALL update(); + + protected: + virtual void outputBuffer(const char* buf, int buf_len) = 0; + virtual void start(); + virtual void shutdown(); + + private: + static void outputThreadRoutine(void* opaque); + void output(); + + AudioQueue* m_queue; + bool m_thread_should_die; + bool m_thread_exists; + }; + } #endif |