return snd_pcm_htimestamp(generic->slave, avail, tstamp);
}
+/* stand-alone version - similar like snd_pcm_hw_htimestamp but
+ * taking the tstamp via gettimestamp().
+ */
+int snd_pcm_generic_real_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail,
+ snd_htimestamp_t *tstamp)
+{
+ snd_pcm_sframes_t avail1;
+ int ok = 0;
+
+ while (1) {
+ avail1 = snd_pcm_avail_update(pcm);
+ if (avail1 < 0)
+ return avail1;
+ if (ok && (snd_pcm_uframes_t)avail1 == *avail)
+ break;
+ *avail = avail1;
+ gettimestamp(tstamp, pcm->monotonic);
+ ok = 1;
+ }
+ return 0;
+}
+
int snd_pcm_generic_mmap(snd_pcm_t *pcm)
{
if (pcm->mmap_shadow) {
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_real_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail,
+ snd_htimestamp_t *tstamp);
int snd_pcm_generic_mmap(snd_pcm_t *pcm);
int snd_pcm_generic_munmap(snd_pcm_t *pcm);
#include "pcm_local.h"
#include "pcm_ioplug.h"
#include "pcm_ext_parm.h"
+#include "pcm_generic.h"
#ifndef PIC
/* entry for static linking */
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;
.readn = snd_pcm_ioplug_readn,
.avail_update = snd_pcm_ioplug_avail_update,
.mmap_commit = snd_pcm_ioplug_mmap_commit,
- .htimestamp = snd_pcm_ioplug_htimestamp,
+ .htimestamp = snd_pcm_generic_real_htimestamp,
.poll_descriptors_count = snd_pcm_ioplug_poll_descriptors_count,
.poll_descriptors = snd_pcm_ioplug_poll_descriptors,
.poll_revents = snd_pcm_ioplug_poll_revents,
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);
.readn = snd_pcm_null_readn,
.avail_update = snd_pcm_null_avail_update,
.mmap_commit = snd_pcm_null_mmap_commit,
- .htimestamp = snd_pcm_null_htimestamp,
+ .htimestamp = snd_pcm_generic_real_htimestamp,
};
/**
}
}
-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)
+static int snd_pcm_rate_htimestamp(snd_pcm_t *pcm,
+ snd_pcm_uframes_t *avail,
+ snd_htimestamp_t *tstamp)
{
- return -EIO; /* not implemented yet */
+ snd_pcm_rate_t *rate = pcm->private_data;
+ snd_pcm_sframes_t avail1;
+ snd_pcm_uframes_t tmp;
+ int ok = 0, err;
+
+ while (1) {
+ /* the position is from this plugin itself */
+ avail1 = snd_pcm_avail_update(pcm);
+ if (avail1 < 0)
+ return avail1;
+ if (ok && (snd_pcm_uframes_t)avail1 == *avail)
+ break;
+ *avail = avail1;
+ /* timestamp is taken from the slave PCM */
+ err = snd_pcm_htimestamp(rate->gen.slave, &tmp, tstamp);
+ if (err < 0)
+ return err;
+ ok = 1;
+ }
+ return 0;
}
static int snd_pcm_rate_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)