[alsa-devel] [PATCH] pcm: support for audio wallclock
add new snd_pcm_status_get_htstamp_wallclk() routine to query the audio timestamps read from the wallclock.
Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- include/pcm.h | 1 + include/sound/asound.h | 7 ++++++- src/pcm/pcm.c | 16 ++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletions(-)
diff --git a/include/pcm.h b/include/pcm.h index 4997557..325c0ea 100644 --- a/include/pcm.h +++ b/include/pcm.h @@ -858,6 +858,7 @@ void snd_pcm_status_get_trigger_tstamp(const snd_pcm_status_t *obj, snd_timestam void snd_pcm_status_get_trigger_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr); void snd_pcm_status_get_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr); void snd_pcm_status_get_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr); +void snd_pcm_status_get_htstamp_wallclk(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr); snd_pcm_sframes_t snd_pcm_status_get_delay(const snd_pcm_status_t *obj); snd_pcm_uframes_t snd_pcm_status_get_avail(const snd_pcm_status_t *obj); snd_pcm_uframes_t snd_pcm_status_get_avail_max(const snd_pcm_status_t *obj); diff --git a/include/sound/asound.h b/include/sound/asound.h index 07c03fa..c186fd6 100644 --- a/include/sound/asound.h +++ b/include/sound/asound.h @@ -285,6 +285,7 @@ enum sndrv_pcm_subformat { #define SNDRV_PCM_INFO_JOINT_DUPLEX 0x00200000 /* playback and capture stream are somewhat correlated */ #define SNDRV_PCM_INFO_SYNC_START 0x00400000 /* pcm support some kind of sync go */ #define SNDRV_PCM_INFO_NO_PERIOD_WAKEUP 0x00800000 /* period wakeup can be disabled */ +#define SNDRV_PCM_INFO_HAS_WALL_CLOCK 0x01000000 /* has audio wall clock for audio/system time sync */
enum sndrv_pcm_state { SNDRV_PCM_STATE_OPEN = 0, /* stream is open */ @@ -426,7 +427,10 @@ struct sndrv_pcm_status { sndrv_pcm_uframes_t avail_max; /* max frames available on hw since last status */ sndrv_pcm_uframes_t overrange; /* count of ADC (capture) overrange detections from last status */ int suspended_state; /* suspended stream state */ - unsigned char reserved[60]; /* must be filled with zero */ + union { + unsigned char reserved[60]; /* must be filled with zero */ + struct timespec audio_tstamp; /* audio wall clock timestamp */ + } ext; };
struct sndrv_pcm_mmap_status { @@ -434,6 +438,7 @@ struct sndrv_pcm_mmap_status { int pad1; /* Needed for 64 bit alignment */ sndrv_pcm_uframes_t hw_ptr; /* RO: hw ptr (0...boundary-1) */ struct timespec tstamp; /* Timestamp */ + struct timespec audio_tstamp; /* audio wall clock timestamp */ int suspended_state; /* RO: suspended stream state */ };
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 18b43b3..2221865 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -6213,6 +6213,22 @@ void snd_pcm_status_get_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *p use_default_symbol_version(__snd_pcm_status_get_htstamp, snd_pcm_status_get_htstamp, ALSA_0.9.0rc8);
/** + * \brief Get "now" hi-res audio wallclock timestamp from a PCM status container + * \param obj pointer to #snd_pcm_status_t + * \param ptr Pointer to returned timestamp + */ +#ifndef DOXYGEN +void INTERNAL(snd_pcm_status_get_htstamp_wallclk)(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr) +#else +void snd_pcm_status_get_htstamp_wallclk(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr) +#endif +{ + assert(obj && ptr); + *ptr = obj->ext.audio_tstamp; +} +use_default_symbol_version(__snd_pcm_status_get_htstamp_wallclk, snd_pcm_status_get_htstamp_wallclk, ALSA_0.9.0rc8); /* FIXME, no idea why this is needed */ + +/** * \brief Get delay from a PCM status container (see #snd_pcm_delay) * \return Delay in frames *
At Wed, 13 Jun 2012 15:27:47 -0500, Pierre-Louis Bossart wrote:
add new snd_pcm_status_get_htstamp_wallclk() routine to query the audio timestamps read from the wallclock.
Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
include/pcm.h | 1 + include/sound/asound.h | 7 ++++++- src/pcm/pcm.c | 16 ++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletions(-)
diff --git a/include/pcm.h b/include/pcm.h index 4997557..325c0ea 100644 --- a/include/pcm.h +++ b/include/pcm.h @@ -858,6 +858,7 @@ void snd_pcm_status_get_trigger_tstamp(const snd_pcm_status_t *obj, snd_timestam void snd_pcm_status_get_trigger_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr); void snd_pcm_status_get_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr); void snd_pcm_status_get_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr); +void snd_pcm_status_get_htstamp_wallclk(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr); snd_pcm_sframes_t snd_pcm_status_get_delay(const snd_pcm_status_t *obj); snd_pcm_uframes_t snd_pcm_status_get_avail(const snd_pcm_status_t *obj); snd_pcm_uframes_t snd_pcm_status_get_avail_max(const snd_pcm_status_t *obj); diff --git a/include/sound/asound.h b/include/sound/asound.h index 07c03fa..c186fd6 100644 --- a/include/sound/asound.h +++ b/include/sound/asound.h @@ -285,6 +285,7 @@ enum sndrv_pcm_subformat { #define SNDRV_PCM_INFO_JOINT_DUPLEX 0x00200000 /* playback and capture stream are somewhat correlated */ #define SNDRV_PCM_INFO_SYNC_START 0x00400000 /* pcm support some kind of sync go */ #define SNDRV_PCM_INFO_NO_PERIOD_WAKEUP 0x00800000 /* period wakeup can be disabled */ +#define SNDRV_PCM_INFO_HAS_WALL_CLOCK 0x01000000 /* has audio wall clock for audio/system time sync */
enum sndrv_pcm_state { SNDRV_PCM_STATE_OPEN = 0, /* stream is open */ @@ -426,7 +427,10 @@ struct sndrv_pcm_status { sndrv_pcm_uframes_t avail_max; /* max frames available on hw since last status */ sndrv_pcm_uframes_t overrange; /* count of ADC (capture) overrange detections from last status */ int suspended_state; /* suspended stream state */
- unsigned char reserved[60]; /* must be filled with zero */
- union {
unsigned char reserved[60]; /* must be filled with zero */
struct timespec audio_tstamp; /* audio wall clock timestamp */
- } ext;
};
struct sndrv_pcm_mmap_status { @@ -434,6 +438,7 @@ struct sndrv_pcm_mmap_status { int pad1; /* Needed for 64 bit alignment */ sndrv_pcm_uframes_t hw_ptr; /* RO: hw ptr (0...boundary-1) */ struct timespec tstamp; /* Timestamp */
- struct timespec audio_tstamp; /* audio wall clock timestamp */ int suspended_state; /* RO: suspended stream state */
};
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 18b43b3..2221865 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -6213,6 +6213,22 @@ void snd_pcm_status_get_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *p use_default_symbol_version(__snd_pcm_status_get_htstamp, snd_pcm_status_get_htstamp, ALSA_0.9.0rc8);
You need to provide a function to indicate whether htstamp_wallclk is available or not. Since the function returning tstamp_wallclk is a void function and it itself can't return the error, user can't know whether it's a bogus value or not.
And that function should check whether the running PCM protocol version is high enough to support the new ABI.
/**
- \brief Get "now" hi-res audio wallclock timestamp from a PCM status container
- \param obj pointer to #snd_pcm_status_t
- \param ptr Pointer to returned timestamp
- */
+#ifndef DOXYGEN +void INTERNAL(snd_pcm_status_get_htstamp_wallclk)(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr) +#else +void snd_pcm_status_get_htstamp_wallclk(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr) +#endif
I think you can avoid this hack for the new functions.
+{
- assert(obj && ptr);
- *ptr = obj->ext.audio_tstamp;
+} +use_default_symbol_version(__snd_pcm_status_get_htstamp_wallclk, snd_pcm_status_get_htstamp_wallclk, ALSA_0.9.0rc8); /* FIXME, no idea why this is needed */
Ditto. It was needed just for those functions that have been added to 0.9.0rc8 release.
Takashi
You need to provide a function to indicate whether htstamp_wallclk is available or not. Since the function returning tstamp_wallclk is a void function and it itself can't return the error, user can't know whether it's a bogus value or not.
Yes, this was planned but I wasn't sure how to go about it. These types of routines usually rely on hw_params, I guess I could query them and check the .info field. Not sure if there's another way. Also maybe I should change the return type to provide -EINVAL is somehow the audio timestamp is not available for a specific device (digital input as Clemens mentioned)
And that function should check whether the running PCM protocol version is high enough to support the new ABI.
Yep
\
+#ifndef DOXYGEN +void INTERNAL(snd_pcm_status_get_htstamp_wallclk)(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr) +#else +void snd_pcm_status_get_htstamp_wallclk(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr) +#endif
I think you can avoid this hack for the new functions.
Ok, I have no idea what I am doing here, just copy-pasted to make it work...
participants (2)
-
Pierre-Louis Bossart
-
Takashi Iwai