summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLuo Jinghua <sunmoon1997@gmail.com>2012-11-27 14:00:15 +0800
committerLuo Jinghua <sunmoon1997@gmail.com>2012-11-27 14:20:34 +0800
commitdc69d7d189870b6e33f30846f5ec7c093f121183 (patch)
treebae4d981dd64d29c79474a4fadfcf0bbd3a03baf /src
parent2102c82899d1a64108f0d00ef4840edc14a5e388 (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.cpp86
-rw-r--r--src/device_mixer.h23
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