From d0edf1adfe67bc11af7aee849004a1acafd0ed4a Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 20 Jul 2009 00:12:10 +0100 Subject: Some fixes --- src/audio.c | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) (limited to 'src/audio.c') diff --git a/src/audio.c b/src/audio.c index 5120f5b..d425384 100644 --- a/src/audio.c +++ b/src/audio.c @@ -62,9 +62,14 @@ void audio_trigger_moo() if ( a == NULL ) return; } + /* Prevent another moo, until we're done */ + a->mootex = 1; + printf("Moo!\n"); + + /* Switch from "setup" to "prepare" mode, reading for writing data */ snd_pcm_prepare(a->alsa_handle); - a->mootex = 1; + /* Start the moo */ a->moo_pos = 0; } @@ -76,14 +81,22 @@ static void *audio_alsa_work(void *data) while ( !a->finished ) { int ret; + snd_pcm_uframes_t tp; if ( a->moo_pos >= a->moo_len ) { usleep(1000); continue; } - ret = snd_pcm_writei(a->alsa_handle, a->moo_buf+a->moo_pos, - a->alsa_frames); + /* Play the full number of frames, or the number of frames + * remaining to be played - whichever is the lowest */ + if ( a->moo_len - a->moo_pos > a->alsa_frames ) { + tp = a->alsa_frames; + } else { + tp = a->moo_len - a->moo_pos; + } + + ret = snd_pcm_writei(a->alsa_handle, a->moo_buf+a->moo_pos, tp); if (ret == -EPIPE) { fprintf(stderr, "ALSA buffer underrun\n"); @@ -91,20 +104,28 @@ static void *audio_alsa_work(void *data) } else if (ret < 0) { fprintf(stderr, "ALSA write error: %s\n", snd_strerror(ret)); - } else if (ret != (int)a->alsa_frames) { - fprintf(stderr, "ALSA short write, %d frames\n", - ret); + } else if (ret != (int)tp) { + fprintf(stderr, "ALSA short write, %d frames\n", ret); } else { /* Successful write */ a->moo_pos += ret; - if ( a->moo_pos > a->moo_len ) { - while ( snd_pcm_avail(a->alsa_handle) >= 0 ) { - usleep(1000); - } + if ( a->moo_pos == a->moo_len ) { + + /* We have finished writing. Now sleep + * until the hardware has caught up. */ + snd_pcm_hwsync(a->alsa_handle); + //while ( snd_pcm_avail(a->alsa_handle) >= 0 ) { + // usleep(1000); + //} + + /* Drop back to "setup" state */ + snd_pcm_drop(a->alsa_handle); + + /* Not it's safe to moo again */ a->mootex = 0; - printf("Done.\n"); + } } @@ -153,7 +174,6 @@ static int audio_open_alsa(AudioContext *a) /* Get the actual period size */ snd_pcm_hw_params_get_period_size(params, &frames, &dir); a->alsa_frames = frames; - printf("%i frames per period\n", frames); a->alsa_handle = handle; a->finished = 0; -- cgit v1.2.3