[alsa-devel] alsa timestamps
Takashi Iwai
tiwai at suse.de
Wed Nov 21 11:33:50 CET 2007
At Tue, 20 Nov 2007 18:07:25 +0200,
Heikki Lindholm wrote:
>
> Takashi Iwai kirjoitti:
> > At Tue, 20 Nov 2007 16:54:32 +0200,
> > Heikki Lindholm wrote:
> >> Takashi Iwai kirjoitti:
> >>> At Mon, 19 Nov 2007 15:41:46 +0200,
> >>> Heikki Lindholm wrote:
> >>>> Jaroslav Kysela kirjoitti:
> >>>>> On Mon, 19 Nov 2007, Heikki Lindholm wrote:
> >>>>>
> >>>>>> Heikki Lindholm kirjoitti:
> >>>>>>> Hello list,
> >>>>>>>
> >>>>>>> I took up some old dusty code of mine that uses snd_pcm_state followed
> >>>>>>> by snd_pcm_status_get_tstamp when in capture mode. The code used to
> >>>>>>> work, but now the returned timestamps are all zeroes. Is there some API
> >>>>>>> change done recently or is the whole timestamping deprecated or
> >>>>>>> something? I've tried with different drivers on ubuntu's alsa .14 and
> >>>>>>> gentoo's .14. I've also tried mmap'ed and r/w modes, and I'm setting the
> >>>>>>> TSTAMP_MMAP sw param.
> >>>>>> I figured out that this doesn't happen when using hw:x,y devices. Is it
> >>>>>> a documented feature that some (software?) devices don't fill in timestamps?
> >>>>> I think that it should be fixed. Could you send us 'snd_pcm_dump()' for a
> >>>>> non-working device? It's probably ommited code in direct pcm plugins (dmix
> >>>>> & etc.).
> >>>> Here goes. The driver is snd_aoa. It seems as if the timestamp mode
> >>>> isn't propagated to the hw device.
> >>> AFAIK, the time-stamp mode isn't handled properly with direct plugins
> >>> because of its nature. Since the direct plugins share the same PCM
> >>> hardware instance with multiple processes, you cannot change the
> >>> parameter arbitrarily from a single client.
> >>>
> >>> We may implement an emulation in alsa-lib instead, though...
> >> For the time being, is there any other way of determining whether a pcm
> >> supports time stamps than just trying out and seeing if zero is all that
> >> comes out?
> >
> > Hmm, at the second look at the dmix/dsnoop code, it has some lines
> > that actually update the timestamp value (as emulation). So,
> > basically it should work. Maybe some other parts are broken...
> > Do you have a small test case code just for checking?
>
> Attached a test case that I just wrote. Seems I need it anyway since
> drivers are acting bogus, too. On a Power Mac G5, using snd_aoa, running
> the program with
> ./alsatest hw:0,0 1024
> produces good timestamps whereas running with
> ./alsatest default 1024
> produces zeros (the second param is period size).
> I also observed the same behaviour on a bog standard x86, with SB Live,
> I think..
Thanks. Actually it's a bug in alsa-lib. The patch below should fix
the problem. I'll push it to the HG tree.
Takashi
diff -r 39d34d6a4587 src/pcm/pcm_direct.c
--- a/src/pcm/pcm_direct.c Tue Nov 20 15:29:10 2007 +0100
+++ b/src/pcm/pcm_direct.c Wed Nov 21 12:06:52 2007 +0100
@@ -1001,6 +1001,17 @@ int snd_pcm_direct_initialize_slave(snd_
return ret;
}
+ /* set timestamp mode to MMAP
+ * the slave timestamp is copied appropriately in dsnoop/dmix/dshare
+ * based on the tstamp_mode of each client
+ */
+ ret = snd_pcm_sw_params_set_tstamp_mode(spcm, sw_params,
+ SND_PCM_TSTAMP_MMAP);
+ if (ret < 0) {
+ SNDERR("unable to tstamp mode MMAP");
+ return ret;
+ }
+
if (dmix->type != SND_PCM_TYPE_DMIX)
goto __skip_silencing;
diff -r 39d34d6a4587 src/pcm/pcm_dmix.c
--- a/src/pcm/pcm_dmix.c Tue Nov 20 15:29:10 2007 +0100
+++ b/src/pcm/pcm_dmix.c Wed Nov 21 12:06:52 2007 +0100
@@ -420,7 +420,14 @@ static int snd_pcm_dmix_status(snd_pcm_t
memset(status, 0, sizeof(*status));
status->state = snd_pcm_dmix_state(pcm);
status->trigger_tstamp = dmix->trigger_tstamp;
- status->tstamp = snd_pcm_hw_fast_tstamp(dmix->spcm);
+ if (pcm->tstamp_mode == SND_PCM_TSTAMP_MMAP)
+ status->tstamp = snd_pcm_hw_fast_tstamp(dmix->spcm);
+ else {
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ status->tstamp.tv_sec = tv.tv_sec;
+ status->tstamp.tv_nsec = tv.tv_usec * 1000L;
+ }
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;
diff -r 39d34d6a4587 src/pcm/pcm_dshare.c
--- a/src/pcm/pcm_dshare.c Tue Nov 20 15:29:10 2007 +0100
+++ b/src/pcm/pcm_dshare.c Wed Nov 21 12:06:52 2007 +0100
@@ -229,7 +229,14 @@ static int snd_pcm_dshare_status(snd_pcm
memset(status, 0, sizeof(*status));
status->state = snd_pcm_state(dshare->spcm);
status->trigger_tstamp = dshare->trigger_tstamp;
- status->tstamp = snd_pcm_hw_fast_tstamp(dshare->spcm);
+ if (pcm->tstamp_mode == SND_PCM_TSTAMP_MMAP)
+ status->tstamp = snd_pcm_hw_fast_tstamp(dshare->spcm);
+ else {
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ status->tstamp.tv_sec = tv.tv_sec;
+ status->tstamp.tv_nsec = tv.tv_usec * 1000L;
+ }
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;
diff -r 39d34d6a4587 src/pcm/pcm_dsnoop.c
--- a/src/pcm/pcm_dsnoop.c Tue Nov 20 15:29:10 2007 +0100
+++ b/src/pcm/pcm_dsnoop.c Wed Nov 21 12:06:52 2007 +0100
@@ -175,7 +175,14 @@ static int snd_pcm_dsnoop_status(snd_pcm
state = snd_pcm_state(dsnoop->spcm);
status->state = state == SND_PCM_STATE_RUNNING ? dsnoop->state : state;
status->trigger_tstamp = dsnoop->trigger_tstamp;
- status->tstamp = snd_pcm_hw_fast_tstamp(dsnoop->spcm);
+ if (pcm->tstamp_mode == SND_PCM_TSTAMP_MMAP)
+ status->tstamp = snd_pcm_hw_fast_tstamp(dsnoop->spcm);
+ else {
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ status->tstamp.tv_sec = tv.tv_sec;
+ status->tstamp.tv_nsec = tv.tv_usec * 1000L;
+ }
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;
More information about the Alsa-devel
mailing list