]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Impemented snd_pcm_htimestamp() function.
authorJaroslav Kysela <perex@perex.cz>
Wed, 9 Jan 2008 12:50:45 +0000 (13:50 +0100)
committerJaroslav Kysela <perex@perex.cz>
Wed, 9 Jan 2008 12:50:45 +0000 (13:50 +0100)
19 files changed:
include/pcm.h
src/pcm/pcm.c
src/pcm/pcm_dmix.c
src/pcm/pcm_dshare.c
src/pcm/pcm_dsnoop.c
src/pcm/pcm_generic.c
src/pcm/pcm_generic.h
src/pcm/pcm_hooks.c
src/pcm/pcm_hw.c
src/pcm/pcm_ioplug.c
src/pcm/pcm_local.h
src/pcm/pcm_meter.c
src/pcm/pcm_mmap_emul.c
src/pcm/pcm_multi.c
src/pcm/pcm_null.c
src/pcm/pcm_plugin.c
src/pcm/pcm_rate.c
src/pcm/pcm_share.c
src/pcm/pcm_shm.c

index ff0c7e22a590f4870f3c2af7c1ded6aab6b79a56..6f4d0ebc666baf9929b37af61e7cb009430fbf17 100644 (file)
@@ -427,6 +427,7 @@ snd_pcm_state_t snd_pcm_state(snd_pcm_t *pcm);
 int snd_pcm_hwsync(snd_pcm_t *pcm);
 int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
 int snd_pcm_resume(snd_pcm_t *pcm);
+int snd_pcm_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail, snd_htimestamp_t *tstamp);
 snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm);
 snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
 snd_pcm_sframes_t snd_pcm_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
index e6d0e3eec1105c5cb56a62f7e2670e6af25eee9b..100cafd16f4e0dfc2e685d6da31637e62a31ec1c 100644 (file)
@@ -343,7 +343,8 @@ is equal or greater than this value, then application will be activated.
 The timestamp mode specifies, if timestamps are activated. Currently, only
 #SND_PCM_TSTAMP_NONE and #SND_PCM_TSTAMP_MMAP
 modes are known. The mmap mode means that timestamp is taken
-on every period time boundary.
+on every period time boundary. Corresponding position in the ring buffer
+assigned to timestamp can be obtained using #snd_pcm_htimestamp() function.
 
 \par Transfer align
 
@@ -383,7 +384,7 @@ The stream status is stored in #snd_pcm_status_t structure.
 These parameters can be obtained: the current stream state -
 #snd_pcm_status_get_state(), timestamp of trigger -
 #snd_pcm_status_get_trigger_tstamp(), timestamp of last
-update #snd_pcm_status_get_tstamp(), delay in samples -
+pointer update #snd_pcm_status_get_tstamp(), delay in samples -
 #snd_pcm_status_get_delay(), available count in samples -
 #snd_pcm_status_get_avail(), maximum available samples -
 #snd_pcm_status_get_avail_max(), ADC over-range count in
@@ -979,6 +980,26 @@ int snd_pcm_resume(snd_pcm_t *pcm)
        return pcm->fast_ops->resume(pcm->fast_op_arg);
 }
 
+/**
+ * \brief Obtain last position update hi-res timestamp
+ * \param pcm PCM handle
+ * \param avail Number of available frames when timestamp was grabbed
+ * \param tstamp Hi-res timestamp
+ * \return 0 on success otherwise a negative error code
+ *
+ * Note this function does not update the actual r/w pointer
+ * for applications.
+ */
+int snd_pcm_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail, snd_htimestamp_t *tstamp)
+{
+       assert(pcm);
+       if (CHECK_SANITY(! pcm->setup)) {
+               SNDMSG("PCM not set up");
+               return -EIO;
+       }
+       return pcm->fast_ops->htimestamp(pcm->fast_op_arg, avail, tstamp);
+}
+
 /**
  * \brief Prepare PCM for use
  * \param pcm PCM handle
index 9ea6e87974f9ca225c849fb22842f5a7ae2ce1dc..2e70b6c91ff7126e4b6139ff4c6054094193d70e 100644 (file)
@@ -382,10 +382,7 @@ static int snd_pcm_dmix_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
        memset(status, 0, sizeof(*status));
        status->state = snd_pcm_dmix_state(pcm);
        status->trigger_tstamp = dmix->trigger_tstamp;
-       if (pcm->tstamp_mode == SND_PCM_TSTAMP_MMAP)
-               status->tstamp = snd_pcm_hw_fast_tstamp(dmix->spcm);
-       else
-               gettimestamp(&status->tstamp, pcm->monotonic);
+       gettimestamp(&status->tstamp, pcm->monotonic);
        status->avail = snd_pcm_mmap_playback_avail(pcm);
        status->avail_max = status->avail > dmix->avail_max ? status->avail : dmix->avail_max;
        dmix->avail_max = 0;
@@ -671,6 +668,27 @@ static snd_pcm_sframes_t snd_pcm_dmix_avail_update(snd_pcm_t *pcm)
        return snd_pcm_mmap_playback_avail(pcm);
 }
 
+static int snd_pcm_dmix_htimestamp(snd_pcm_t *pcm,
+                                  snd_pcm_uframes_t *avail,
+                                  snd_htimestamp_t *tstamp)
+{
+       snd_pcm_direct_t *dmix = pcm->private_data;
+       snd_pcm_uframes_t avail1;
+       int ok = 0;
+       
+       while (1) {
+               if (dmix->state == SND_PCM_STATE_RUNNING ||
+                   dmix->state == SND_PCM_STATE_DRAINING)
+                       snd_pcm_dmix_sync_ptr(pcm);
+               avail1 = snd_pcm_mmap_playback_avail(pcm);
+               if (ok && *avail == avail1)
+                       break;
+               *avail = avail1;
+               *tstamp = snd_pcm_hw_fast_tstamp(pcm);
+       }
+       return 0;
+}
+
 static int snd_pcm_dmix_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
 {
        snd_pcm_direct_t *dmix = pcm->private_data;
@@ -731,6 +749,7 @@ static snd_pcm_fast_ops_t snd_pcm_dmix_fast_ops = {
        .readn = snd_pcm_dmix_readn,
        .avail_update = snd_pcm_dmix_avail_update,
        .mmap_commit = snd_pcm_dmix_mmap_commit,
+       .htimestamp = snd_pcm_dmix_htimestamp,
        .poll_descriptors = NULL,
        .poll_descriptors_count = NULL,
        .poll_revents = snd_pcm_dmix_poll_revents,
index 301bc0304b421dcd77f004b9be61b756cbb261a1..b7afa3c72e9e1399605f0478426379bed8bb44d2 100644 (file)
@@ -226,10 +226,7 @@ static int snd_pcm_dshare_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
        memset(status, 0, sizeof(*status));
        status->state = snd_pcm_state(dshare->spcm);
        status->trigger_tstamp = dshare->trigger_tstamp;
-       if (pcm->tstamp_mode == SND_PCM_TSTAMP_MMAP)
-               status->tstamp = snd_pcm_hw_fast_tstamp(dshare->spcm);
-       else
-               gettimestamp(&status->tstamp, pcm->monotonic);
+       gettimestamp(&status->tstamp, pcm->monotonic);
        status->avail = snd_pcm_mmap_playback_avail(pcm);
        status->avail_max = status->avail > dshare->avail_max ? status->avail : dshare->avail_max;
        dshare->avail_max = 0;
@@ -517,6 +514,27 @@ static snd_pcm_sframes_t snd_pcm_dshare_avail_update(snd_pcm_t *pcm)
        return snd_pcm_mmap_playback_avail(pcm);
 }
 
+static int snd_pcm_dshare_htimestamp(snd_pcm_t *pcm,
+                                    snd_pcm_uframes_t *avail,
+                                    snd_htimestamp_t *tstamp)
+{
+       snd_pcm_direct_t *dshare = pcm->private_data;
+       snd_pcm_uframes_t avail1;
+       int ok = 0;
+       
+       while (1) {
+               if (dshare->state == SND_PCM_STATE_RUNNING ||
+                   dshare->state == SND_PCM_STATE_DRAINING)
+                       snd_pcm_dshare_sync_ptr(pcm);
+               avail1 = snd_pcm_mmap_playback_avail(pcm);
+               if (ok && *avail == avail1)
+                       break;
+               *avail = avail1;
+               *tstamp = snd_pcm_hw_fast_tstamp(pcm);
+       }
+       return 0;
+}
+
 static void snd_pcm_dshare_dump(snd_pcm_t *pcm, snd_output_t *out)
 {
        snd_pcm_direct_t *dshare = pcm->private_data;
@@ -568,6 +586,7 @@ static snd_pcm_fast_ops_t snd_pcm_dshare_fast_ops = {
        .readn = snd_pcm_dshare_readn,
        .avail_update = snd_pcm_dshare_avail_update,
        .mmap_commit = snd_pcm_dshare_mmap_commit,
+       .htimestamp = snd_pcm_dshare_htimestamp,
        .poll_descriptors = NULL,
        .poll_descriptors_count = NULL,
        .poll_revents = snd_pcm_direct_poll_revents,
index 6add13209554a61caf77a297b3c821e5bc81a10a..5eaca3f57d3f1756d744e14d991a1836a5b19b45 100644 (file)
@@ -172,10 +172,7 @@ static int snd_pcm_dsnoop_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
        state = snd_pcm_state(dsnoop->spcm);
        status->state = state == SND_PCM_STATE_RUNNING ? dsnoop->state : state;
        status->trigger_tstamp = dsnoop->trigger_tstamp;
-       if (pcm->tstamp_mode == SND_PCM_TSTAMP_MMAP)
-               status->tstamp = snd_pcm_hw_fast_tstamp(dsnoop->spcm);
-       else
-               gettimestamp(&status->tstamp, pcm->monotonic);
+       gettimestamp(&status->tstamp, pcm->monotonic);
        status->avail = snd_pcm_mmap_capture_avail(pcm);
        status->avail_max = status->avail > dsnoop->avail_max ? status->avail : dsnoop->avail_max;
        dsnoop->avail_max = 0;
@@ -407,6 +404,27 @@ static snd_pcm_sframes_t snd_pcm_dsnoop_avail_update(snd_pcm_t *pcm)
        return snd_pcm_mmap_capture_avail(pcm);
 }
 
+static int snd_pcm_dsnoop_htimestamp(snd_pcm_t *pcm,
+                                    snd_pcm_uframes_t *avail,
+                                    snd_htimestamp_t *tstamp)
+{
+       snd_pcm_direct_t *dsnoop = pcm->private_data;
+       snd_pcm_uframes_t avail1;
+       int ok = 0;
+       
+       while (1) {
+               if (dsnoop->state == SND_PCM_STATE_RUNNING ||
+                   dsnoop->state == SND_PCM_STATE_DRAINING)
+                       snd_pcm_dsnoop_sync_ptr(pcm);
+               avail1 = snd_pcm_mmap_capture_avail(pcm);
+               if (ok && *avail == avail1)
+                       break;
+               *avail = avail1;
+               *tstamp = snd_pcm_hw_fast_tstamp(pcm);
+       }
+       return 0;
+}
+
 static void snd_pcm_dsnoop_dump(snd_pcm_t *pcm, snd_output_t *out)
 {
        snd_pcm_direct_t *dsnoop = pcm->private_data;
@@ -458,6 +476,7 @@ static snd_pcm_fast_ops_t snd_pcm_dsnoop_fast_ops = {
        .readn = snd_pcm_mmap_readn,
        .avail_update = snd_pcm_dsnoop_avail_update,
        .mmap_commit = snd_pcm_dsnoop_mmap_commit,
+       .htimestamp = snd_pcm_dsnoop_htimestamp,
        .poll_descriptors = NULL,
        .poll_descriptors_count = NULL,
        .poll_revents = snd_pcm_direct_poll_revents,
index bfb3cfc27cf11c51c8203edefe704bea996c5e45..fd4b2bd4376b509a190245af8fd546f93b91b3be 100644 (file)
@@ -259,6 +259,13 @@ snd_pcm_sframes_t snd_pcm_generic_avail_update(snd_pcm_t *pcm)
        return snd_pcm_avail_update(generic->slave);
 }
 
+int snd_pcm_generic_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail,
+                              snd_htimestamp_t *tstamp)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_htimestamp(generic->slave, avail, tstamp);
+}
+
 int snd_pcm_generic_mmap(snd_pcm_t *pcm)
 {
        if (pcm->mmap_shadow) {
index 47376c519df6fa9feccef5d235c1af1a902f0f04..a77a5b78e4d5890bb7979d869f837482ed18e16f 100644 (file)
@@ -137,5 +137,7 @@ snd_pcm_sframes_t snd_pcm_generic_mmap_commit(snd_pcm_t *pcm,
                                              snd_pcm_uframes_t offset,
                                              snd_pcm_uframes_t size);
 snd_pcm_sframes_t snd_pcm_generic_avail_update(snd_pcm_t *pcm);
+int snd_pcm_generic_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail,
+                              snd_htimestamp_t *timestamp);
 int snd_pcm_generic_mmap(snd_pcm_t *pcm);
 int snd_pcm_generic_munmap(snd_pcm_t *pcm);
index 99b3248336e89f43c3b3c8abd9a73efa8809ab57..edfed72a51975f13c0ec4a6721a3af889b5df8b7 100644 (file)
@@ -159,6 +159,7 @@ static snd_pcm_fast_ops_t snd_pcm_hooks_fast_ops = {
        .readn = snd_pcm_generic_readn,
        .avail_update = snd_pcm_generic_avail_update,
        .mmap_commit = snd_pcm_generic_mmap_commit,
+       .htimestamp = snd_pcm_generic_htimestamp,
        .poll_descriptors_count = snd_pcm_generic_poll_descriptors_count,
        .poll_descriptors = snd_pcm_generic_poll_descriptors,
        .poll_revents = snd_pcm_generic_poll_revents,
index bcbdfd51527ae9ecff55ff09c6c2cdf339771d36..a5a8ea816af9fe342dd4246267d9c52861f51a4d 100644 (file)
@@ -846,6 +846,26 @@ static snd_pcm_sframes_t snd_pcm_hw_avail_update(snd_pcm_t *pcm)
        return avail;
 }
 
+static int snd_pcm_hw_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail,
+                                snd_htimestamp_t *tstamp)
+{
+       snd_pcm_sframes_t avail1;
+       int ok = 0;
+
+       /* unfortunately, loop is necessary to ensure valid timestamp */
+       while (1) {
+               avail1 = snd_pcm_hw_avail_update(pcm);
+               if (avail1 < 0)
+                       return avail1;
+               if (ok && (snd_pcm_uframes_t)avail1 == *avail)
+                       break;
+               *avail = avail1;
+               *tstamp = snd_pcm_hw_fast_tstamp(pcm);
+               ok = 1;
+       }
+       return 0;
+}
+
 static void snd_pcm_hw_dump(snd_pcm_t *pcm, snd_output_t *out)
 {
        snd_pcm_hw_t *hw = pcm->private_data;
@@ -902,6 +922,7 @@ static snd_pcm_fast_ops_t snd_pcm_hw_fast_ops = {
        .readn = snd_pcm_hw_readn,
        .avail_update = snd_pcm_hw_avail_update,
        .mmap_commit = snd_pcm_hw_mmap_commit,
+       .htimestamp = snd_pcm_hw_htimestamp,
        .poll_descriptors = NULL,
        .poll_descriptors_count = NULL,
        .poll_revents = NULL,
index 19b97d1b17cd66734e1e5c1d4864ddf9f90b03ed..2d08742e53d1918b3101a2f6c0eab6d53dd95a5f 100644 (file)
@@ -636,6 +636,13 @@ static snd_pcm_sframes_t snd_pcm_ioplug_avail_update(snd_pcm_t *pcm)
        return (snd_pcm_sframes_t)avail;
 }
 
+static int snd_pcm_ioplug_htimestamp(snd_pcm_t *pcm ATTRIBUTE_UNUSED,
+                                    snd_pcm_uframes_t *avail ATTRIBUTE_UNUSED,
+                                    snd_htimestamp_t *tstamp ATTRIBUTE_UNUSED)
+{
+       return -EIO;    /* not implemented yet */
+}
+
 static int snd_pcm_ioplug_nonblock(snd_pcm_t *pcm, int nonblock)
 {
        ioplug_priv_t *io = pcm->private_data;
@@ -774,6 +781,7 @@ static snd_pcm_fast_ops_t snd_pcm_ioplug_fast_ops = {
        .readn = snd_pcm_ioplug_readn,
        .avail_update = snd_pcm_ioplug_avail_update,
        .mmap_commit = snd_pcm_ioplug_mmap_commit,
+       .htimestamp = snd_pcm_ioplug_htimestamp,
        .poll_descriptors_count = snd_pcm_ioplug_poll_descriptors_count,
        .poll_descriptors = snd_pcm_ioplug_poll_descriptors,
        .poll_revents = snd_pcm_ioplug_poll_revents,
index 0954aee7f55f1df0360a946bc36712614e916e56..8d4ae40039ceb9f4d2281cdfd1498cd9f963e717 100644 (file)
@@ -163,6 +163,7 @@ typedef struct {
        snd_pcm_sframes_t (*readn)(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
        snd_pcm_sframes_t (*avail_update)(snd_pcm_t *pcm);
        snd_pcm_sframes_t (*mmap_commit)(snd_pcm_t *pcm, snd_pcm_uframes_t offset, snd_pcm_uframes_t size);
+       int (*htimestamp)(snd_pcm_t *pcm, snd_pcm_uframes_t *avail, snd_htimestamp_t *tstamp);
        int (*poll_descriptors_count)(snd_pcm_t *pcm);
        int (*poll_descriptors)(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space);
        int (*poll_revents)(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
index 24d08ac929ba6edebe9aeade2fea057193d2efdf..079de1ee115557df1191dae4286215850f6550f8 100644 (file)
@@ -536,6 +536,7 @@ static snd_pcm_fast_ops_t snd_pcm_meter_fast_ops = {
        .readn = snd_pcm_mmap_readn,
        .avail_update = snd_pcm_meter_avail_update,
        .mmap_commit = snd_pcm_meter_mmap_commit,
+       .htimestamp = snd_pcm_generic_htimestamp,
        .poll_descriptors_count = snd_pcm_generic_poll_descriptors_count,
        .poll_descriptors = snd_pcm_generic_poll_descriptors,
        .poll_revents = snd_pcm_generic_poll_revents,
index 29bbfa4a74c5f38bf6e9d730d776af0849c4feed..a00ddb1e669f85980c503f030254c691ac4a4f44 100644 (file)
@@ -370,6 +370,7 @@ static snd_pcm_fast_ops_t snd_pcm_mmap_emul_fast_ops = {
        .readn = snd_pcm_generic_readn,
        .avail_update = snd_pcm_mmap_emul_avail_update,
        .mmap_commit = snd_pcm_mmap_emul_mmap_commit,
+       .htimestamp = snd_pcm_generic_htimestamp,
        .poll_descriptors = snd_pcm_generic_poll_descriptors,
        .poll_descriptors_count = snd_pcm_generic_poll_descriptors_count,
        .poll_revents = snd_pcm_generic_poll_revents,
index c2db21e5c5eff2376cfa1695f7eebdc58647d9f6..9b8583cedc447c425a6d79c33888908febeed301 100644 (file)
@@ -431,6 +431,14 @@ static snd_pcm_sframes_t snd_pcm_multi_avail_update(snd_pcm_t *pcm)
        return ret;
 }
 
+static int snd_pcm_multi_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail,
+                                   snd_htimestamp_t *tstamp)
+{
+       snd_pcm_multi_t *multi = pcm->private_data;
+       snd_pcm_t *slave = multi->slaves[multi->master_slave].pcm;
+       return snd_pcm_htimestamp(slave, avail, tstamp);
+}
+
 static int snd_pcm_multi_prepare(snd_pcm_t *pcm)
 {
        snd_pcm_multi_t *multi = pcm->private_data;
@@ -792,6 +800,7 @@ static snd_pcm_fast_ops_t snd_pcm_multi_fast_ops = {
        .unlink = snd_pcm_multi_unlink,
        .avail_update = snd_pcm_multi_avail_update,
        .mmap_commit = snd_pcm_multi_mmap_commit,
+       .htimestamp = snd_pcm_multi_htimestamp,
        .poll_descriptors_count = snd_pcm_multi_poll_descriptors_count,
        .poll_descriptors = snd_pcm_multi_poll_descriptors,
        .poll_revents = snd_pcm_multi_poll_revents,
index 5b48cb1b1475cd3f1bcbffdb0df2471b94bd136e..66735150c5cc2bc7bf256394c96456b352c14341 100644 (file)
@@ -244,6 +244,13 @@ static snd_pcm_sframes_t snd_pcm_null_avail_update(snd_pcm_t *pcm)
        return pcm->buffer_size;
 }
 
+static int snd_pcm_null_htimestamp(snd_pcm_t *pcm ATTRIBUTE_UNUSED,
+                                  snd_pcm_uframes_t *avail ATTRIBUTE_UNUSED,
+                                  snd_htimestamp_t *tstamp ATTRIBUTE_UNUSED)
+{
+       return -EIO;
+}
+
 static int snd_pcm_null_hw_refine(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params)
 {
        int err = snd_pcm_hw_refine_soft(pcm, params);
@@ -312,6 +319,7 @@ static snd_pcm_fast_ops_t snd_pcm_null_fast_ops = {
        .readn = snd_pcm_null_readn,
        .avail_update = snd_pcm_null_avail_update,
        .mmap_commit = snd_pcm_null_mmap_commit,
+       .htimestamp = snd_pcm_null_htimestamp,
 };
 
 /**
index 520f2e9d5bcb16088f9e2a690be64f6e4e020423..d5fc5d7d39a3939d329b2f21e233a72468a4355b 100644 (file)
@@ -575,6 +575,7 @@ snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops = {
        .readn = snd_pcm_plugin_readn,
        .avail_update = snd_pcm_plugin_avail_update,
        .mmap_commit = snd_pcm_plugin_mmap_commit,
+       .htimestamp = snd_pcm_generic_htimestamp,
        .poll_descriptors_count = snd_pcm_generic_poll_descriptors_count,
        .poll_descriptors = snd_pcm_generic_poll_descriptors,
        .poll_revents = snd_pcm_generic_poll_revents,
index 2487bd1065502f06a262f089c14cb4da1e437746..9e589ec2188af2447c5ef33269051970fecbe426 100644 (file)
@@ -1020,6 +1020,13 @@ static snd_pcm_sframes_t snd_pcm_rate_avail_update(snd_pcm_t *pcm)
  }
 }
 
+static int snd_pcm_rate_htimestamp(snd_pcm_t *pcm ATTRIBUTE_UNUSED,
+                                  snd_pcm_uframes_t *avail ATTRIBUTE_UNUSED,
+                                  snd_htimestamp_t *tstamp ATTRIBUTE_UNUSED)
+{
+       return -EIO; /* not implemented yet */
+}
+
 static int snd_pcm_rate_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
 {
        snd_pcm_rate_t *rate = pcm->private_data;
@@ -1189,6 +1196,7 @@ static snd_pcm_fast_ops_t snd_pcm_rate_fast_ops = {
        .readn = snd_pcm_mmap_readn,
        .avail_update = snd_pcm_rate_avail_update,
        .mmap_commit = snd_pcm_rate_mmap_commit,
+       .htimestamp = snd_pcm_rate_htimestamp,
        .poll_descriptors_count = snd_pcm_generic_poll_descriptors_count,
        .poll_descriptors = snd_pcm_generic_poll_descriptors,
        .poll_revents = snd_pcm_rate_poll_revents,
index b4e0467691241a504c5c05b68c76d3afdc8b1d18..a01e759185b3730adc306016f5e958e2b5133165 100644 (file)
@@ -798,6 +798,18 @@ static snd_pcm_sframes_t snd_pcm_share_avail_update(snd_pcm_t *pcm)
        return avail;
 }
 
+static int snd_pcm_share_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail,
+                                   snd_htimestamp_t *tstamp)
+{
+       snd_pcm_share_t *share = pcm->private_data;
+       snd_pcm_share_slave_t *slave = share->slave;
+       int err;
+       Pthread_mutex_lock(&slave->mutex);
+       err = snd_pcm_htimestamp(slave->pcm, avail, tstamp);
+       Pthread_mutex_unlock(&slave->mutex);
+       return err;
+}
+
 /* Call it with mutex held */
 static snd_pcm_sframes_t _snd_pcm_share_mmap_commit(snd_pcm_t *pcm,
                                                    snd_pcm_uframes_t offset ATTRIBUTE_UNUSED,
@@ -1308,6 +1320,7 @@ static snd_pcm_fast_ops_t snd_pcm_share_fast_ops = {
        .forward = snd_pcm_share_forward,
        .resume = snd_pcm_share_resume,
        .avail_update = snd_pcm_share_avail_update,
+       .htimestamp = snd_pcm_share_htimestamp,
        .mmap_commit = snd_pcm_share_mmap_commit,
 };
 
index c94396614cbb5440e4655a01656a3a637c2ff284..29f9d2337d88facf6bbdc97cdba1d6a11220d4a8 100644 (file)
@@ -441,6 +441,13 @@ static snd_pcm_sframes_t snd_pcm_shm_avail_update(snd_pcm_t *pcm)
        return err;
 }
 
+static int snd_pcm_shm_htimestamp(snd_pcm_t *pcm ATTRIBUTE_UNUSED,
+                                 snd_pcm_uframes_t *avail ATTRIBUTE_UNUSED,
+                                 snd_htimestamp_t *tstamp ATTRIBUTE_UNUSED)
+{
+       return -EIO;    /* not implemented yet */
+}
+
 static int snd_pcm_shm_prepare(snd_pcm_t *pcm)
 {
        snd_pcm_shm_t *shm = pcm->private_data;
@@ -609,6 +616,7 @@ static snd_pcm_fast_ops_t snd_pcm_shm_fast_ops = {
        .readn = snd_pcm_mmap_readn,
        .avail_update = snd_pcm_shm_avail_update,
        .mmap_commit = snd_pcm_shm_mmap_commit,
+       .htimestamp = snd_pcm_shm_htimestamp,
 };
 
 static int make_local_socket(const char *filename)