[alsa-devel] Latency and timestamps

Takashi Iwai tiwai at suse.de
Wed Nov 21 15:25:15 CET 2007


At Wed, 21 Nov 2007 14:11:37 +0100,
I wrote:
> 
> At Wed, 21 Nov 2007 15:26:05 +0200,
> Heikki Lindholm wrote:
> > 
> > Takashi Iwai kirjoitti:
> > > At Mon, 19 Nov 2007 22:46:31 -0200,
> > > Claudio Matsuoka wrote:
> > >> Hi,
> > >>
> > >> I'm adding latency control to an application and didn't find much
> > >> documentation about the pcm status functions aside from a very brief
> > >> description and the latency.c example. What exactly are the "trigger
> > >> timestamp" and "now timestamp" returned by
> > >> snd_pcm_status_get_trigger_tstamp() and snd_pcm_status_get_tstamp()?
> > > 
> > > The trigger_tstamp is the time-stamp at the last time the PCM status
> > > change occured.  For example, when the PCM is really triggered to
> > > start, or stopped, or XRUN, etc.  It won't be changed as long as the 
> > > PCM status is kept.
> > > 
> > > OTOH, the tstamp is the current timestamp (now).  But, this value has
> > > a slightly different meaning when tstamp_mode is set to
> > > SND_PCM_TSTAMP_MMAP.  Then it keeps the timestamp of the last period
> > > update time instead of the now.
> > 
> > I looked at the code and I'm not sure I understand the above "last 
> > period update time" correctly. I'd like to think that MMAP timestamp is 
> > updated by the driver interrupt handler when a new period arrives _and 
> > only there_, but the code seems somewhat different:
> > - the timestamp is generated in snd_pcm_update_hw_ptr_pos
> > - snd_pcm_update_hw_ptr_pos is called by snd_pcm_update_hw_ptr_interrupt
> > - the driver interrupt updates the timestamp in snd_pcm_period_elapsed
> > BUT if the user calls snd_pcm_status
> > - snd_pcm_status calls snd_pcm_update_hw_ptr
> > - snd_pcm_update_hw_ptr calls snd_pcm_update_hw_ptr_pos
> > and therefore it seems that the timestamp is updated when calling 
> > snd_pcm_status also, effectively making the timestamp a "now" timestamp 
> > anyway.
> 
> Oh, yeah, it's broken.  I think the original design was supposed to
> update the mmap update.  Let's fix this.

And here is the patch.


Takashi

diff -r a37346b0c0be core/pcm_lib.c
--- a/core/pcm_lib.c	Tue Nov 20 18:32:08 2007 +0100
+++ b/core/pcm_lib.c	Wed Nov 21 16:00:41 2007 +0100
@@ -148,8 +148,6 @@ static inline snd_pcm_uframes_t snd_pcm_
 	pos = substream->ops->pointer(substream);
 	if (pos == SNDRV_PCM_POS_XRUN)
 		return pos; /* XRUN */
-	if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP)
-		getnstimeofday((struct timespec *)&runtime->status->tstamp);
 #ifdef CONFIG_SND_DEBUG
 	if (pos >= runtime->buffer_size) {
 		snd_printk(KERN_ERR  "BUG: stream = %i, pos = 0x%lx, buffer size = 0x%lx, period size = 0x%lx\n", substream->stream, pos, runtime->buffer_size, runtime->period_size);
@@ -189,6 +187,8 @@ static inline int snd_pcm_update_hw_ptr_
 	snd_pcm_uframes_t new_hw_ptr, hw_ptr_interrupt;
 	snd_pcm_sframes_t delta;
 
+	if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_MMAP)
+		getnstimeofday((struct timespec *)&runtime->status->tstamp);
 	pos = snd_pcm_update_hw_ptr_pos(substream, runtime);
 	if (pos == SNDRV_PCM_POS_XRUN) {
 		xrun(substream);
diff -r a37346b0c0be core/pcm_native.c
--- a/core/pcm_native.c	Tue Nov 20 18:32:08 2007 +0100
+++ b/core/pcm_native.c	Wed Nov 21 16:00:41 2007 +0100
@@ -595,7 +595,7 @@ int snd_pcm_status(struct snd_pcm_substr
 	status->trigger_tstamp = runtime->trigger_tstamp;
 	if (snd_pcm_running(substream)) {
 		snd_pcm_update_hw_ptr(substream);
-		if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP)
+		if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_MMAP)
 			status->tstamp = runtime->status->tstamp;
 		else
 			getnstimeofday(&status->tstamp);


More information about the Alsa-devel mailing list