]> git.alsa-project.org Git - alsa-lib.git/commitdiff
pcm: ioplug: Provide hw_avail helper function for plugins
authorTimo Wischer <twischer@de.adit-jv.com>
Tue, 13 Mar 2018 08:34:42 +0000 (09:34 +0100)
committerTakashi Iwai <tiwai@suse.de>
Tue, 13 Mar 2018 21:12:02 +0000 (22:12 +0100)
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>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/pcm_ioplug.h
src/pcm/pcm_ioplug.c
src/pcm/pcm_local.h

index e75f973e7631666f0fd20cfbb504a3ca995383cc..c1310e3b968dcf1cc49ab633ca161ce128ab964a 100644 (file)
@@ -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 */
index 9970646fdeb307f587c8c49d2d5bd6c890a42239..af223a13f47397f007c2a6b46b8578b66656c13e 100644 (file)
@@ -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;
+}
index 3d95e174916962ec52755815ef524ba4d8af006a..d52229d8ddeae320291a7dc1e4bdb75bd3e72d40 100644 (file)
@@ -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)