summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2014-03-19 18:04:43 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2014-03-19 18:04:43 +0100
commit30455ab7403a9f48b7ef6d51ee43e972c78b1018 (patch)
tree7a9e8fe643c5cc3d5928aae13a101a150d3bb75b /src
parentecc1a7dd8e9bc7818bf101e192ae075ecc104d77 (diff)
downloadODR-AudioEnc-30455ab7403a9f48b7ef6d51ee43e972c78b1018.tar.gz
ODR-AudioEnc-30455ab7403a9f48b7ef6d51ee43e972c78b1018.tar.bz2
ODR-AudioEnc-30455ab7403a9f48b7ef6d51ee43e972c78b1018.zip
Improve alsa fault detection
Diffstat (limited to 'src')
-rw-r--r--src/AlsaInput.cpp25
-rw-r--r--src/AlsaInput.h8
-rw-r--r--src/dabplus-enc-alsa-zmq.cpp20
3 files changed, 39 insertions, 14 deletions
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<uint8_t>& 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;