From 9f0159f2327b29dda47735fd69aaf5ce2da20d91 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sun, 9 Mar 2014 16:07:01 +0100 Subject: Split AlsaInput into two variants (Threaded/Direct) --- src/AlsaDabplus.cpp | 2 +- src/AlsaInput.cpp | 21 ++++++++++---- src/AlsaInput.h | 83 +++++++++++++++++++++++++++++++++++++++++------------ 3 files changed, 81 insertions(+), 25 deletions(-) diff --git a/src/AlsaDabplus.cpp b/src/AlsaDabplus.cpp index 103a4b2..9c3c759 100644 --- a/src/AlsaDabplus.cpp +++ b/src/AlsaDabplus.cpp @@ -256,7 +256,7 @@ int main(int argc, char *argv[]) { return 1; } - AlsaInput alsa_in(alsa_device, channels, sample_rate, queue); + AlsaInputThreaded alsa_in(alsa_device, channels, sample_rate, queue); if (alsa_in.prepare() != 0) { fprintf(stderr, "Alsa preparation failed\n"); diff --git a/src/AlsaInput.cpp b/src/AlsaInput.cpp index 8b6f790..14f4524 100644 --- a/src/AlsaInput.cpp +++ b/src/AlsaInput.cpp @@ -101,7 +101,7 @@ int AlsaInput::prepare() return 0; } -size_t AlsaInput::read(uint8_t* buf, snd_pcm_uframes_t length) +size_t AlsaInput::m_read(uint8_t* buf, snd_pcm_uframes_t length) { int i; int err; @@ -121,19 +121,30 @@ size_t AlsaInput::read(uint8_t* buf, snd_pcm_uframes_t length) return err; } -void AlsaInput::start() +void AlsaInputThreaded::start() { m_running = true; - m_thread = boost::thread(&AlsaInput::process, this); + m_thread = boost::thread(&AlsaInputThreaded::process, this); } -void AlsaInput::process() +void AlsaInputThreaded::process() { uint8_t samplebuf[NUM_SAMPLES_PER_CALL * BYTES_PER_SAMPLE * m_channels]; while (m_running) { - size_t n = read(samplebuf, NUM_SAMPLES_PER_CALL); + size_t n = m_read(samplebuf, NUM_SAMPLES_PER_CALL); m_queue.push(samplebuf, BYTES_PER_SAMPLE*m_channels*n); } } + +size_t AlsaInputDirect::read(uint8_t* buf, size_t length) +{ + int bytes_per_frame = m_channels * BYTES_PER_SAMPLE; + assert(length % bytes_per_frame == 0); + + size_t read = m_read(buf, length / bytes_per_frame); + + return read * bytes_per_frame; +} + diff --git a/src/AlsaInput.h b/src/AlsaInput.h index c1e3e9b..eb02ec1 100644 --- a/src/AlsaInput.h +++ b/src/AlsaInput.h @@ -40,22 +40,13 @@ class AlsaInput public: AlsaInput(const string& alsa_dev, unsigned int channels, - unsigned int rate, - SampleQueue& queue) : - m_running(false), + unsigned int rate) : m_alsa_dev(alsa_dev), m_channels(channels), m_rate(rate), - m_queue(queue), m_alsa_handle(NULL) { } - ~AlsaInput() - { - if (m_running) { - m_running = false; - m_thread.interrupt(); - m_thread.join(); - } + ~AlsaInput() { if (m_alsa_handle) { snd_pcm_abort(m_alsa_handle); @@ -63,26 +54,80 @@ class AlsaInput } } + /* Prepare the audio input */ int prepare(); - void start(); + virtual void start() = 0; + + protected: + size_t m_read(uint8_t* buf, snd_pcm_uframes_t length); + + string m_alsa_dev; + unsigned int m_channels; + unsigned int m_rate; + + snd_pcm_t *m_alsa_handle; private: - AlsaInput(const AlsaInput& other) : m_queue(other.m_queue) {} + AlsaInput(const AlsaInput& other) {} +}; + +class AlsaInputDirect : public AlsaInput +{ + public: + AlsaInputDirect(const string& alsa_dev, + unsigned int channels, + unsigned int rate) : + AlsaInput(alsa_dev, channels, rate) { } + + virtual void start() { }; + + /* Read length Bytes from from the alsa device. + * length must be a multiple of channels * bytes_per_sample. + * + * Returns the number of bytes read. + */ + size_t read(uint8_t* buf, size_t length); + + private: + AlsaInputDirect(const AlsaInputDirect& other) : + AlsaInput("", 0, 0) { } +}; + +class AlsaInputThreaded : public AlsaInput +{ + public: + AlsaInputThreaded(const string& alsa_dev, + unsigned int channels, + unsigned int rate, + SampleQueue& queue) : + AlsaInput(alsa_dev, channels, rate), + m_running(false), + m_queue(queue) { } + + ~AlsaInputThreaded() + { + if (m_running) { + m_running = false; + m_thread.interrupt(); + m_thread.join(); + } + } + + virtual void start(); + + private: + AlsaInputThreaded(const AlsaInputThreaded& other) : + AlsaInput("", 0, 0), + m_queue(other.m_queue) {} - size_t read(uint8_t* buf, snd_pcm_uframes_t length); void process(); bool m_running; boost::thread m_thread; - string m_alsa_dev; - unsigned int m_channels; - unsigned int m_rate; SampleQueue& m_queue; - snd_pcm_t *m_alsa_handle; - }; #endif -- cgit v1.2.3