aboutsummaryrefslogtreecommitdiff
path: root/src/audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio.c')
-rw-r--r--src/audio.c44
1 files changed, 32 insertions, 12 deletions
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;