From ed8105083ab72f9afac9d18b7563fbc3d6c1c925 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 17 Feb 2010 02:44:04 +0100 Subject: make things more robust against weird drivers --- dbmeasure.c | 75 ++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 21 deletions(-) diff --git a/dbmeasure.c b/dbmeasure.c index 2c40e9d..16ef8b8 100644 --- a/dbmeasure.c +++ b/dbmeasure.c @@ -26,12 +26,13 @@ static float *generate_silence(unsigned n_samples) { return r; } -static snd_pcm_t *open_device(const char *name, snd_pcm_stream_t stream, unsigned rate) { - snd_pcm_t *d; +static snd_pcm_t *open_device(const char *name, snd_pcm_stream_t stream, unsigned *rate) { + snd_pcm_t *d = NULL; int r; snd_pcm_hw_params_t *hw; - snd_pcm_uframes_t t; snd_output_t *output = NULL; + int dir = 0; + snd_pcm_uframes_t t; snd_pcm_hw_params_alloca(&hw); @@ -55,7 +56,7 @@ static snd_pcm_t *open_device(const char *name, snd_pcm_stream_t stream, unsigne goto finish; } - if ((r = snd_pcm_hw_params_set_rate(d, hw, rate, 0)) < 0) { + if ((r = snd_pcm_hw_params_set_rate_near(d, hw, rate, &dir)) < 0) { fprintf(stderr, "Cannot set sample rate: %s\n", snd_strerror(r)); goto finish; } @@ -65,7 +66,7 @@ static snd_pcm_t *open_device(const char *name, snd_pcm_stream_t stream, unsigne goto finish; } - t = rate; + t = *rate; if ((r = snd_pcm_hw_params_set_buffer_size_near(d, hw, &t)) < 0) { fprintf(stderr, "Cannot set buffer size: %s\n", snd_strerror(r)); goto finish; @@ -133,19 +134,19 @@ int main(int argc, char *argv[]) { int ret = 1; float *signal = NULL, *silence = NULL, *buffer = NULL, *sum = NULL, *current = NULL; snd_pcm_t *input = NULL, *output = NULL; - unsigned rate = 44100; + unsigned rate = 48000; unsigned rindex = 0, windex = 0; - double frequency = 440.0, amplitude = 0.5, noise_level_dB = -80.0, initial_level_max = 0.97, initial_level_min = 0.8, reference_level; + double frequency = 440.0, amplitude = 0.5, noise_level_dB = -58.0, initial_level_max = 0.97, initial_level_min = 0.8, reference_level; unsigned iteration = 0; int icount, ocount; struct pollfd *pollfd; int e; unsigned needed_iterations = 0; int skip = 1; - FILE *log; + FILE *log = NULL; int level_count = 0; - if (argc < 3) { + if (argc != 3) { fprintf(stderr, "Need to specify device and output log file.\n"); goto finish; } @@ -155,10 +156,10 @@ int main(int argc, char *argv[]) { goto finish; } - if (!(output = open_device(argv[1], SND_PCM_STREAM_PLAYBACK, rate))) + if (!(output = open_device(argv[1], SND_PCM_STREAM_PLAYBACK, &rate))) goto finish; - if (!(input = open_device(argv[1], SND_PCM_STREAM_CAPTURE, rate))) + if (!(input = open_device(argv[1], SND_PCM_STREAM_CAPTURE, &rate))) goto finish; if (!(silence = generate_silence(rate))) { @@ -230,14 +231,34 @@ int main(int argc, char *argv[]) { goto finish; } + /* printf("%u out %i in\n", orevents, irevents); */ + if (orevents) { if ((n = snd_pcm_writei(output, current + windex, rate - windex)) < 0) { - if (snd_pcm_recover(output, n, 1) < 0) { + fprintf(stderr, "Got %s while writing.\n", snd_strerror(n)); + + if (snd_pcm_recover(output, n, 0) >= 0) { + fprintf(stderr, "recovered\n"); + continue; + } + + if (snd_pcm_prepare(output) >= 0) { + fprintf(stderr, "prepared\n"); + continue; + } + + if (snd_pcm_start(output) >= 0) { + fprintf(stderr, "restarted\n"); + continue; + } + + if (n != -EAGAIN) { fprintf(stderr, "Cannot write samples: %s\n", snd_strerror(n)); goto finish; - } else - continue; + } + + n = 0; } windex += n; @@ -245,21 +266,33 @@ int main(int argc, char *argv[]) { windex = 0; } - if (irevents) { if ((n = snd_pcm_readi(input, buffer + rindex, rate - rindex)) < 0) { - if (snd_pcm_recover(input, n, 1) < 0) { - fprintf(stderr, "Cannot read samples: %s\n", snd_strerror(n)); - goto finish; + fprintf(stderr, "Got %s while reading.\n", snd_strerror(n)); + + if (snd_pcm_start(input) >= 0) { + fprintf(stderr, "restarted\n"); + continue; } - if ((e = snd_pcm_start(input)) < 0) { - fprintf(stderr, "snd_pcm_start() failed: %s\n", snd_strerror(e)); + if (snd_pcm_recover(input, n, 0) >= 0) { + fprintf(stderr, "recovered\n"); + snd_pcm_start(input); + continue; + } + + if (snd_pcm_prepare(input) >= 0) { + fprintf(stderr, "prepared\n"); + continue; + } + + if (n != -EAGAIN) { + fprintf(stderr, "Cannot read samples: %s\n", snd_strerror(n)); goto finish; } - continue; + n = 0; } rindex += n; -- cgit