[PATCH 1/2] pq_alsa.c: handle output buffer underrun

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.

Vadim Yanitskiy axilirator at gmail.com
Sat Sep 2 14:30:09 UTC 2017


On some systems the ALSA output buffer is pretty big, and
if the audio samples are not being passed into the buffer
quickly enough, it becomes starved for data, resulting
in an error called underrun.

Previously, when it happenned, GAPK used to stop processing
with the following message (where X is a random number):

[+] PQ: Adding ALSA output (dev='default', blk_len=320)
[!] pq_execute(): abort, item returned -1
[+] Processed X frames

According to the ALSA documentation, the pcm_handle
changes its state when the problem happens, and should
be recovered using the snd_pcm_prepare() call. This change
actually does that.
---
 src/pq_alsa.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/pq_alsa.c b/src/pq_alsa.c
index 9cee426..a3435dd 100644
--- a/src/pq_alsa.c
+++ b/src/pq_alsa.c
@@ -57,7 +57,15 @@ pq_cb_alsa_output(void *_state, uint8_t *out, const uint8_t *in, unsigned int in
 	struct pq_state_alsa *state = _state;
 	unsigned int num_samples = in_len/2;
 	int rv;
+
 	rv = snd_pcm_writei(state->pcm_handle, in, num_samples);
+	if (rv == -EPIPE) {
+		/* Recover from buffer underrun */
+		snd_pcm_prepare(state->pcm_handle);
+		/* Send a new sample again */
+		rv = snd_pcm_writei(state->pcm_handle, in, num_samples);
+	}
+
 	return rv == num_samples ? 0 : -1;
 }
 
-- 
2.14.1


>From 8f1b0a9bf966cd561b10d2d33c6a47dd02e17dcf Mon Sep 17 00:00:00 2001
From: Vadim Yanitskiy <axilirator at gmail.com>
Date: Sat, 2 Sep 2017 18:02:45 +0700
Subject: [PATCH 2/2] pq_alsa.c: print error message if device init fails
To: openbsc at lists.osmocom.org
Cc: 246tnt at gmail.com,
    laforge at gnumonks.org,
    axilirator at gmail.com

---
 src/pq_alsa.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/pq_alsa.c b/src/pq_alsa.c
index a3435dd..cad76ca 100644
--- a/src/pq_alsa.c
+++ b/src/pq_alsa.c
@@ -85,13 +85,16 @@ pq_queue_alsa_op(struct pq *pq, const char *alsa_dev, unsigned int blk_len, int
 	int rc = -1;
 
 	state = calloc(1, sizeof(struct pq_state_alsa));
-	if (!state)
-		return -ENOMEM;
+	if (!state) {
+		rc = -ENOMEM;
+		goto out_print;
+	}
 
 	rc = snd_pcm_open(&state->pcm_handle, alsa_dev,
 			  in_out_n ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, 0);
 	if (rc < 0)
-		return rc;
+		goto out_print;
+
 	state->blk_len = blk_len;
 
 	rc = snd_pcm_hw_params_malloc(&hw_params);
@@ -143,6 +146,9 @@ out_free_par:
 out_close:
 	snd_pcm_close(state->pcm_handle);
 	free(state);
+out_print:
+	fprintf(stderr, "[!] Couldn't init ALSA device '%s': %s\n",
+		alsa_dev, snd_strerror(rc));
 	return rc;
 }
 
-- 
2.14.1




More information about the OpenBSC mailing list