From: Timo Wischer twischer@de.adit-jv.com
Without this commit the JACK thread will be stopped before the ALSA buffer was completely forwarded to the JACK daemon.
Signed-off-by: Timo Wischer twischer@de.adit-jv.com
diff --git a/jack/pcm_jack.c b/jack/pcm_jack.c index e3df4d2..5c4d0fc 100644 --- a/jack/pcm_jack.c +++ b/jack/pcm_jack.c @@ -85,7 +85,12 @@ static int pcm_poll_unblock_check(snd_pcm_ioplug_t *io) snd_pcm_jack_t *jack = io->private_data;
avail = snd_pcm_avail_update(io->pcm); - if (avail < 0 || avail >= jack->min_avail) { + /* In draining state poll_fd is used to wait till all pending frames are + * played. Therefore it has to be guarantee that a poll event is also + * generated if the buffer contains less than min_avail frames. + */ + if (avail < 0 || avail >= jack->min_avail || + io->state == SND_PCM_STATE_DRAINING) { write(jack->fd, &buf, 1); return 1; } @@ -161,7 +166,8 @@ snd_pcm_jack_process_cb(jack_nframes_t nframes, snd_pcm_ioplug_t *io) jack->areas[channel].step = jack->sample_bits; }
- if (io->state == SND_PCM_STATE_RUNNING) { + if (io->state == SND_PCM_STATE_RUNNING || + io->state == SND_PCM_STATE_DRAINING) { snd_pcm_uframes_t hw_ptr = jack->hw_ptr; const snd_pcm_uframes_t hw_avail = snd_pcm_ioplug_hw_avail(io, hw_ptr, io->appl_ptr); @@ -307,6 +313,29 @@ static int snd_pcm_jack_start(snd_pcm_ioplug_t *io) return 0; }
+static int snd_pcm_jack_drain(snd_pcm_ioplug_t *io) +{ + snd_pcm_jack_t *jack = io->private_data; + + /* Immediately stop on capture device. + * snd_pcm_jack_stop() will be automatically called + * by snd_pcm_ioplug_drain() + */ + if (io->stream == SND_PCM_STREAM_CAPTURE) + return 0; + + if (snd_pcm_ioplug_hw_avail(io, jack->hw_ptr, io->appl_ptr) <= 0) { + /* No data pending. Nothing to drain. */ + return 0; + } + + /* start device if not yet done */ + if (!jack->activated) + snd_pcm_jack_start(io); + + return -EAGAIN; +} + static int snd_pcm_jack_stop(snd_pcm_ioplug_t *io) { snd_pcm_jack_t *jack = io->private_data; @@ -333,6 +362,7 @@ static snd_pcm_ioplug_callback_t jack_pcm_callback = { .stop = snd_pcm_jack_stop, .pointer = snd_pcm_jack_pointer, .prepare = snd_pcm_jack_prepare, + .drain = snd_pcm_jack_drain, .poll_revents = snd_pcm_jack_poll_revents, };