--- alsa-plugins-1.0.14.lennart/pulse/pcm_pulse.c 2007-09-24 01:43:01.000000000 +0200 +++ alsa-plugins-1.0.14/pulse/pcm_pulse.c 2007-10-01 21:36:53.000000000 +0200 @@ -36,6 +36,7 @@ /* Since ALSA expects a ring buffer we must do some voodoo. */ size_t last_size; size_t ptr; + int underrun; size_t offset; @@ -90,7 +91,9 @@ if (err < 0) { err = -EIO; goto finish; - } + } else + pcm->underrun = 0; + finish: pa_threaded_mainloop_unlock(pcm->p->mainloop); @@ -200,6 +203,9 @@ err = snd_pcm_bytes_to_frames(io->pcm, pcm->ptr); + if (pcm->underrun) + err = -EPIPE; + finish: pa_threaded_mainloop_unlock(pcm->p->mainloop); @@ -231,6 +237,10 @@ *delayp = snd_pcm_bytes_to_frames(io->pcm, pa_usec_to_bytes(lat, &pcm->ss)); + /* Yes, this is evil, and we're not supposed to do this. */ + if (pcm->underrun && pcm->io.state == SND_PCM_STATE_RUNNING) + pcm->io.state = SND_PCM_STATE_XRUN; + finish: pa_threaded_mainloop_unlock(pcm->p->mainloop); @@ -273,6 +283,7 @@ pulse_poll_deactivate(pcm->p); err = size; + pcm->underrun = 0; finish: pa_threaded_mainloop_unlock(pcm->p->mainloop); @@ -354,6 +365,15 @@ pulse_poll_activate(pcm->p); } +static void stream_underrun_cb(pa_stream *p, void *userdata) { + snd_pcm_pulse_t *pcm = userdata; + + assert(pcm); + assert(pcm->p); + + pcm->underrun = 1; +} + static int pulse_pcm_poll_descriptors_count(snd_pcm_ioplug_t *io) { snd_pcm_pulse_t *pcm = io->private_data; @@ -461,6 +481,7 @@ if (io->stream == SND_PCM_STREAM_PLAYBACK) { pa_stream_set_write_callback(pcm->stream, stream_request_cb, pcm); + pa_stream_set_underflow_callback(pcm->stream, stream_underrun_cb, pcm); pa_stream_connect_playback(pcm->stream, pcm->device, &pcm->buffer_attr, PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_INTERPOLATE_TIMING, NULL, NULL); } else { @@ -480,6 +501,7 @@ pcm->last_size = 0; pcm->ptr = 0; pcm->offset = 0; + pcm->underrun = 0; finish: pa_threaded_mainloop_unlock(pcm->p->mainloop);