From 30455ab7403a9f48b7ef6d51ee43e972c78b1018 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Wed, 19 Mar 2014 18:04:43 +0100 Subject: Improve alsa fault detection --- src/AlsaInput.cpp | 25 ++++++++++++++++++------- src/AlsaInput.h | 8 ++++++-- src/dabplus-enc-alsa-zmq.cpp | 20 +++++++++++++++----- 3 files changed, 39 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/AlsaInput.cpp b/src/AlsaInput.cpp index 14f4524..4b0da93 100644 --- a/src/AlsaInput.cpp +++ b/src/AlsaInput.cpp @@ -101,7 +101,7 @@ int AlsaInput::prepare() return 0; } -size_t AlsaInput::m_read(uint8_t* buf, snd_pcm_uframes_t length) +ssize_t AlsaInput::m_read(uint8_t* buf, snd_pcm_uframes_t length) { int i; int err; @@ -123,28 +123,39 @@ size_t AlsaInput::m_read(uint8_t* buf, snd_pcm_uframes_t length) void AlsaInputThreaded::start() { - m_running = true; - m_thread = boost::thread(&AlsaInputThreaded::process, this); + if (m_fault) { + fprintf(stderr, "Cannot start alsa input. Fault detected previsouly!\n"); + } + else { + m_running = true; + m_thread = boost::thread(&AlsaInputThreaded::process, this); + } } void AlsaInputThreaded::process() { uint8_t samplebuf[NUM_SAMPLES_PER_CALL * BYTES_PER_SAMPLE * m_channels]; while (m_running) { - size_t n = m_read(samplebuf, NUM_SAMPLES_PER_CALL); + ssize_t n = m_read(samplebuf, NUM_SAMPLES_PER_CALL); + + if (n < 0) { + m_running = false; + m_fault = true; + break; + } m_queue.push(samplebuf, BYTES_PER_SAMPLE*m_channels*n); } } -size_t AlsaInputDirect::read(uint8_t* buf, size_t length) +ssize_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); + ssize_t read = m_read(buf, length / bytes_per_frame); - return read * bytes_per_frame; + return (read > 0) ? read * bytes_per_frame : read; } diff --git a/src/AlsaInput.h b/src/AlsaInput.h index 86844d0..0d454a3 100644 --- a/src/AlsaInput.h +++ b/src/AlsaInput.h @@ -60,7 +60,7 @@ class AlsaInput virtual void start() = 0; protected: - size_t m_read(uint8_t* buf, snd_pcm_uframes_t length); + ssize_t m_read(uint8_t* buf, snd_pcm_uframes_t length); string m_alsa_dev; unsigned int m_channels; @@ -87,7 +87,7 @@ class AlsaInputDirect : public AlsaInput * * Returns the number of bytes read. */ - size_t read(uint8_t* buf, size_t length); + ssize_t read(uint8_t* buf, size_t length); private: AlsaInputDirect(const AlsaInputDirect& other) : @@ -102,6 +102,7 @@ class AlsaInputThreaded : public AlsaInput unsigned int rate, SampleQueue& queue) : AlsaInput(alsa_dev, channels, rate), + m_fault(false), m_running(false), m_queue(queue) { } @@ -116,6 +117,8 @@ class AlsaInputThreaded : public AlsaInput virtual void start(); + bool fault_detected() { return m_fault; }; + private: AlsaInputThreaded(const AlsaInputThreaded& other) : AlsaInput("", 0, 0), @@ -123,6 +126,7 @@ class AlsaInputThreaded : public AlsaInput void process(); + bool m_fault; bool m_running; boost::thread m_thread; diff --git a/src/dabplus-enc-alsa-zmq.cpp b/src/dabplus-enc-alsa-zmq.cpp index 3af667f..4739ed0 100644 --- a/src/dabplus-enc-alsa-zmq.cpp +++ b/src/dabplus-enc-alsa-zmq.cpp @@ -469,8 +469,13 @@ int main(int argc, char *argv[]) // -------------- Read Data memset(outbuf, 0x00, outbuf_size); - size_t read; + ssize_t read; if (drift_compensation) { + if (alsa_in_threaded.fault_detected()) { + fprintf(stderr, "Detected fault in alsa input!\n"); + break; + } + size_t overruns; read = queue.pop(input_buf, input_size, &overruns); // returns bytes @@ -486,7 +491,10 @@ int main(int argc, char *argv[]) } else { read = alsa_in_direct.read(input_buf, input_size); - if (read != input_size) { + if (read < 0) { + break; + } + else if (read != input_size) { fprintf(stderr, "Short alsa read !\n"); } } @@ -519,9 +527,11 @@ int main(int argc, char *argv[]) AACENC_ERROR err; if ((err = aacEncEncode(encoder, &in_buf, &out_buf, &in_args, &out_args)) != AACENC_OK) { - if (err == AACENC_ENCODE_EOF) + if (err == AACENC_ENCODE_EOF) { + fprintf(stderr, "encoder error: EOF reached\n"); break; - fprintf(stderr, "Encoding failed\n"); + } + fprintf(stderr, "Encoding failed (%d)\n", err); break; } calls++; @@ -532,7 +542,7 @@ int main(int argc, char *argv[]) // Our timing code depends on this if (! ((sample_rate == 32000 && calls == 2) || (sample_rate == 48000 && calls == 3)) ) { - fprintf(stderr, "INTERNAL ERROR! GURU MEDITATION: sample rate %d, calls %d\n", + fprintf(stderr, "INTERNAL ERROR! sample rate %d, calls %d\n", sample_rate, calls); } calls = 0; -- cgit v1.2.3