summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2009-08-09 16:08:07 -0700
committerKeith Packard <keithp@keithp.com>2009-08-09 16:08:07 -0700
commitcd5456f18e4b39ad76d5549df91a0e0cfb18a2e9 (patch)
tree9ac8fc28819ffa6250a119e11fd1b4ee155fed84
parent3056cb8eef5aee0dcd342488386355d8b8f574c8 (diff)
Handle partial ALSA PCM writes
The ALSA spec says that snd_pcm_writei will not return a partial write, but at least on the OLPC, that's not true. Deal with this. Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--aoview/aoview_flite.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/aoview/aoview_flite.c b/aoview/aoview_flite.c
index 0ada4e14..e1b75898 100644
--- a/aoview/aoview_flite.c
+++ b/aoview/aoview_flite.c
@@ -37,6 +37,8 @@ aoview_flite_task(gpointer data)
int rate;
int channels;
int err;
+ char *samples;
+ int num_samples;
err = snd_pcm_open(&alsa_handle, "default",
SND_PCM_STREAM_PLAYBACK, 0);
@@ -73,12 +75,19 @@ aoview_flite_task(gpointer data)
if (err < 0)
fprintf(stderr, "alsa pcm_prepare error %s\n",
strerror(-err));
- err = snd_pcm_writei(alsa_handle,
- wave->samples,
- wave->num_samples);
- if (err < 0)
- fprintf(stderr, "alsa write error %s\n",
- strerror(-err));
+ samples = (char *) wave->samples;
+ num_samples = wave->num_samples;
+ while (num_samples > 0) {
+ err = snd_pcm_writei(alsa_handle,
+ samples, num_samples);
+ if (err <= 0) {
+ fprintf(stderr, "alsa write error %s\n",
+ strerror(-err));
+ break;
+ }
+ num_samples -= err;
+ samples += err * 2 * channels;
+ }
snd_pcm_drain(alsa_handle);
delete_wave(wave);
}