On Wed, 28 Mar 2018 10:42:50 +0200, Wischer, Timo (ADITG/ESB) wrote:
@@ -67,6 +73,12 @@ static void snd_pcm_ioplug_hw_ptr_update(snd_pcm_t *pcm) delta = wrap_point + hw - io->last_hw; } snd_pcm_mmap_hw_forward(io->data->pcm, delta);
/* stop the stream if all samples are drained */
if (io->data->state == SND_PCM_STATE_DRAINING) {
avail = snd_pcm_mmap_avail(pcm);
if (avail >= pcm->buffer_size)
snd_pcm_ioplug_drop(pcm);
} io->last_hw = (snd_pcm_uframes_t)hw; } else io->data->state = SNDRV_PCM_STATE_XRUN;
In case of draining drop has to be called because draining is done
OK, makes sense.
@@ -488,20 +500,66 @@ static int snd_pcm_ioplug_drop(snd_pcm_t *pcm) return 0; }
+static int ioplug_drain_via_poll(snd_pcm_t *pcm) +{
ioplug_priv_t *io = pcm->private_data;
int err;
/* in non-blocking mode, leave application to poll() by itself */
if (io->data->nonblock)
return -EAGAIN;
In case of nonblock snd_pcm_ioplug_hw_ptr_update() will not be called by the user Therefore the user will never detect that draining is done. I fear snd_pcm_ioplug_hw_ptr_update() has also to be called in nonblock mode here.
For the non-blocking mode, it's not supposed that drain() is called multiple times. Instead, it should do the loop of snd_pcm_wait(), and status check, as ioplug_drain_vai_poll() actually does.
Yes, it's weird, but it's the standard way for non-blocking mode, even for the kernel drivers. So, the practical recommendation for draining is to temporarily switch to blocking mode before calling snd_pcm_drain().
Will you create the patch and apply it to master or is there anything which I have to do?
I'll cook up the proper patch and submit to ML soon later. Then it'll be merged to git tree, and you can work on it.
thanks,
Takashi