From: Timo Wischer twischer@de.adit-jv.com
This function can be called without calling snd_pcm_avail_update().
The call to snd_pcm_avail_update() can take some time. Therefore some developers would not like to call it from a real-time context (e.g. from JACK client context).
Signed-off-by: Timo Wischer twischer@de.adit-jv.com
diff --git a/include/pcm_ioplug.h b/include/pcm_ioplug.h index e75f973..c1310e3 100644 --- a/include/pcm_ioplug.h +++ b/include/pcm_ioplug.h @@ -234,6 +234,11 @@ int snd_pcm_ioplug_set_param_list(snd_pcm_ioplug_t *io, int type, unsigned int n /* change PCM status */ int snd_pcm_ioplug_set_state(snd_pcm_ioplug_t *ioplug, snd_pcm_state_t state);
+/* calucalte the available frames */ +snd_pcm_uframes_t snd_pcm_ioplug_hw_avail(const snd_pcm_ioplug_t * const ioplug, + const snd_pcm_uframes_t hw_ptr, + const snd_pcm_uframes_t appl_ptr); + /** } */
#endif /* __ALSA_PCM_IOPLUG_H */ diff --git a/src/pcm/pcm_ioplug.c b/src/pcm/pcm_ioplug.c index 9970646..af223a1 100644 --- a/src/pcm/pcm_ioplug.c +++ b/src/pcm/pcm_ioplug.c @@ -1148,3 +1148,29 @@ int snd_pcm_ioplug_set_state(snd_pcm_ioplug_t *ioplug, snd_pcm_state_t state) ioplug->state = state; return 0; } + +/** + * \brief Get the available frames. This function can be used to calculate the + * the available frames before calling #snd_pcm_avail_update() + * \param ioplug the ioplug handle + * \param hw_ptr hardware pointer in frames + * \param appl_ptr application pointer in frames + * \return available frames for the hardware + */ +snd_pcm_uframes_t snd_pcm_ioplug_hw_avail(const snd_pcm_ioplug_t * const ioplug, + const snd_pcm_uframes_t hw_ptr, + const snd_pcm_uframes_t appl_ptr) +{ + /* available data/space which can be transferred by the user + * application + */ + const snd_pcm_uframes_t user_avail = __snd_pcm_avail(ioplug->pcm, + hw_ptr, appl_ptr); + + if (user_avail > ioplug->pcm->buffer_size) { + /* there was an Xrun */ + return 0; + } + /* available data/space which can be transferred by the DMA */ + return ioplug->pcm->buffer_size - user_avail; +} diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index 3d95e17..d52229d 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -467,10 +467,12 @@ static inline int snd_pcm_check_error(snd_pcm_t *pcm, int err) return err; }
-static inline snd_pcm_uframes_t snd_pcm_mmap_playback_avail(snd_pcm_t *pcm) +static inline snd_pcm_uframes_t __snd_pcm_playback_avail(snd_pcm_t *pcm, + const snd_pcm_uframes_t hw_ptr, + const snd_pcm_uframes_t appl_ptr) { snd_pcm_sframes_t avail; - avail = *pcm->hw.ptr + pcm->buffer_size - *pcm->appl.ptr; + avail = hw_ptr + pcm->buffer_size - appl_ptr; if (avail < 0) avail += pcm->boundary; else if ((snd_pcm_uframes_t) avail >= pcm->boundary) @@ -478,21 +480,40 @@ static inline snd_pcm_uframes_t snd_pcm_mmap_playback_avail(snd_pcm_t *pcm) return avail; }
-static inline snd_pcm_uframes_t snd_pcm_mmap_capture_avail(snd_pcm_t *pcm) +static inline snd_pcm_uframes_t snd_pcm_mmap_playback_avail(snd_pcm_t *pcm) +{ + return __snd_pcm_playback_avail(pcm, *pcm->hw.ptr, *pcm->appl.ptr); +} + +static inline snd_pcm_uframes_t __snd_pcm_capture_avail(snd_pcm_t *pcm, + const snd_pcm_uframes_t hw_ptr, + const snd_pcm_uframes_t appl_ptr) { snd_pcm_sframes_t avail; - avail = *pcm->hw.ptr - *pcm->appl.ptr; + avail = hw_ptr - appl_ptr; if (avail < 0) avail += pcm->boundary; return avail; }
-static inline snd_pcm_uframes_t snd_pcm_mmap_avail(snd_pcm_t *pcm) +static inline snd_pcm_uframes_t snd_pcm_mmap_capture_avail(snd_pcm_t *pcm) +{ + return __snd_pcm_capture_avail(pcm, *pcm->hw.ptr, *pcm->appl.ptr); +} + +static inline snd_pcm_uframes_t __snd_pcm_avail(snd_pcm_t *pcm, + const snd_pcm_uframes_t hw_ptr, + const snd_pcm_uframes_t appl_ptr) { if (pcm->stream == SND_PCM_STREAM_PLAYBACK) - return snd_pcm_mmap_playback_avail(pcm); + return __snd_pcm_playback_avail(pcm, hw_ptr, appl_ptr); else - return snd_pcm_mmap_capture_avail(pcm); + return __snd_pcm_capture_avail(pcm, hw_ptr, appl_ptr); +} + +static inline snd_pcm_uframes_t snd_pcm_mmap_avail(snd_pcm_t *pcm) +{ + return __snd_pcm_avail(pcm, *pcm->hw.ptr, *pcm->appl.ptr); }
static inline snd_pcm_sframes_t snd_pcm_mmap_playback_hw_avail(snd_pcm_t *pcm)