unsigned int id32[4];
} snd_pcm_sync_id_t;
+/** Infinite wait for snd_pcm_wait() */
+#define SND_PCM_WAIT_INFINITE (-1)
+/** Wait for next i/o in snd_pcm_wait() */
+#define SND_PCM_WAIT_IO (-10001)
+/** Wait for drain in snd_pcm_wait() */
+#define SND_PCM_WAIT_DRAIN (-10002)
+
/** #SND_PCM_TYPE_METER scope handle */
typedef struct _snd_pcm_scope snd_pcm_scope_t;
* \brief Wait for a PCM to become ready
* \param pcm PCM handle
* \param timeout maximum time in milliseconds to wait,
- * a negative value means infinity
+ * a -1 value means infinity (SND_PCM_WAIT_INFINITE),
+ * see also SND_PCM_WAIT_IO and SND_PCM_WAIT_DRAIN
* \return a positive value on success otherwise a negative error code
* (-EPIPE for the xrun and -ESTRPIPE for the suspended status,
* others for general errors)
return snd_pcm_wait_nocheck(pcm, timeout);
}
+static int __snd_pcm_wait_io_timeout(snd_pcm_t *pcm)
+{
+ int timeout;
+
+ /* period size is the time boundary */
+ timeout = (pcm->period_size * 1000ULL) / pcm->rate;
+ /* should not happen */
+ if (timeout < 0)
+ timeout = 0;
+ /* add extra time of 200 milliseconds */
+ timeout += 200;
+ return timeout;
+}
+
+static int __snd_pcm_wait_drain_timeout(snd_pcm_t *pcm)
+{
+ int timeout;
+
+ /* for capture, there's no reason to wait, just one iteration */
+ if (snd_pcm_stream(pcm) == SND_PCM_STREAM_CAPTURE)
+ return 0;
+ /* result is in milliseconds */
+ timeout = (snd_pcm_mmap_playback_delay(pcm) * 1000LL) / pcm->rate;
+ /* should not happen */
+ if (timeout < 0)
+ timeout = 0;
+ /* add extra time of 200 milliseconds */
+ timeout += 200;
+ return timeout;
+}
+
/*
* like snd_pcm_wait() but doesn't check mmap_avail before calling poll()
*
SNDMSG("invalid poll descriptors %d\n", err);
return -EIO;
}
+ if (timeout == SND_PCM_WAIT_IO)
+ timeout = __snd_pcm_wait_io_timeout(pcm);
+ else if (timeout == SND_PCM_WAIT_DRAIN)
+ timeout = __snd_pcm_wait_drain_timeout(pcm);
+ else if (timeout < -1)
+ SNDMSG("invalid snd_pcm_wait timeout argument %d\n", timeout);
do {
__snd_pcm_unlock(pcm->fast_op_arg);
err_poll = poll(pfd, npfds, timeout);
goto _end;
}
- err = __snd_pcm_wait_in_lock(pcm, -1);
+ err = __snd_pcm_wait_in_lock(pcm, SND_PCM_WAIT_IO);
if (err < 0)
break;
goto _again;
goto _end;
}
- err = snd_pcm_wait_nocheck(pcm, -1);
+ err = snd_pcm_wait_nocheck(pcm, SND_PCM_WAIT_IO);
if (err < 0)
break;
goto _again;