summaryrefslogtreecommitdiff
path: root/test/audio_time.c
diff options
context:
space:
mode:
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>2012-06-12 14:36:40 -0500
committerTakashi Iwai <tiwai@suse.de>2012-10-25 00:13:51 +0200
commitcf40ea169aad366b222283f431addafea6327149 (patch)
tree0ed3637b87387716284d1821b1f4c0b3449d34c7 /test/audio_time.c
parent4bdb09126a32feb4394eaeb1d400d87e7c968770 (diff)
downloadalsa-lib-cf40ea169aad366b222283f431addafea6327149.tar.gz
pcm: support for audio timestamps
add new snd_pcm_status_get_audio_htstamp() routine to query the audio timestamps provided by the kernel. This change provides applications with better ways to track elapsed time. Before this patch, applications would subtract queued samples (delay) from written samples, resulting in a 1-2 sample error. Also add snd_pcm_hw_params_supports_audio_wallclock_ts() to query what the hardware supports. TODO: check protocol compatibility? Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'test/audio_time.c')
-rw-r--r--test/audio_time.c68
1 files changed, 58 insertions, 10 deletions
diff --git a/test/audio_time.c b/test/audio_time.c
index a910783b..03817c7c 100644
--- a/test/audio_time.c
+++ b/test/audio_time.c
@@ -33,6 +33,7 @@ long long timediff(snd_htimestamp_t t1, snd_htimestamp_t t2)
void gettimestamp(snd_pcm_t *handle, snd_htimestamp_t *timestamp,
snd_htimestamp_t *trigger_timestamp,
+ snd_htimestamp_t *audio_timestamp,
snd_pcm_uframes_t *avail, snd_pcm_sframes_t *delay)
{
int err;
@@ -45,6 +46,7 @@ void gettimestamp(snd_pcm_t *handle, snd_htimestamp_t *timestamp,
}
snd_pcm_status_get_trigger_htstamp(status, trigger_timestamp);
snd_pcm_status_get_htstamp(status, timestamp);
+ snd_pcm_status_get_audio_htstamp(status, audio_timestamp);
*avail = snd_pcm_status_get_avail(status);
*delay = snd_pcm_status_get_delay(status);
}
@@ -53,6 +55,7 @@ void gettimestamp(snd_pcm_t *handle, snd_htimestamp_t *timestamp,
#define PCM_LINK /* sync start for playback and capture */
#define TRACK_CAPTURE /* dump capture timing info */
#define TRACK_PLAYBACK /* dump playback timing info */
+#define TRACK_SAMPLE_COUNTS /* show difference between sample counters and audiotimestamps returned by driver */
#define PLAYBACK_BUFFERS 4
@@ -65,9 +68,13 @@ int main(void)
snd_pcm_sframes_t frames;
snd_htimestamp_t tstamp_c, tstamp_p;
snd_htimestamp_t trigger_tstamp_c, trigger_tstamp_p;
+ snd_htimestamp_t audio_tstamp_c, audio_tstamp_p;
unsigned char buffer_p[PERIOD*4*4];
unsigned char buffer_c[PERIOD*4*4];
+ snd_pcm_hw_params_t *hwparams_p;
+ snd_pcm_hw_params_t *hwparams_c;
+
snd_pcm_sw_params_t *swparams_p;
snd_pcm_sw_params_t *swparams_c;
@@ -94,6 +101,18 @@ int main(void)
goto _exit;
}
+ snd_pcm_hw_params_alloca(&hwparams_p);
+ /* get the current hwparams */
+ err = snd_pcm_hw_params_current(handle_p, hwparams_p);
+ if (err < 0) {
+ printf("Unable to determine current hwparams_p: %s\n", snd_strerror(err));
+ goto _exit;
+ }
+ if (snd_pcm_hw_params_supports_audio_wallclock_ts(hwparams_p))
+ printf("Playback relies on audio wallclock timestamps\n");
+ else
+ printf("Playback relies on audio sample counter timestamps\n");
+
snd_pcm_sw_params_alloca(&swparams_p);
/* get the current swparams */
err = snd_pcm_sw_params_current(handle_p, swparams_p);
@@ -131,6 +150,18 @@ int main(void)
goto _exit;
}
+ snd_pcm_hw_params_alloca(&hwparams_c);
+ /* get the current hwparams */
+ err = snd_pcm_hw_params_current(handle_c, hwparams_c);
+ if (err < 0) {
+ printf("Unable to determine current hwparams_c: %s\n", snd_strerror(err));
+ goto _exit;
+ }
+ if (snd_pcm_hw_params_supports_audio_wallclock_ts(hwparams_c))
+ printf("Capture relies on audio wallclock timestamps\n");
+ else
+ printf("Capture relies on audio sample counter timestamps\n");
+
snd_pcm_sw_params_alloca(&swparams_c);
/* get the current swparams */
err = snd_pcm_sw_params_current(handle_c, swparams_c);
@@ -202,26 +233,43 @@ int main(void)
frame_count_p += frames;
#if defined(TRACK_PLAYBACK)
- gettimestamp(handle_p, &tstamp_p, &trigger_tstamp_p, &avail_p, &delay_p);
+ gettimestamp(handle_p, &tstamp_p, &trigger_tstamp_p, &audio_tstamp_p, &avail_p, &delay_p);
+#if defined(TRACK_SAMPLE_COUNTS)
curr_count_p = frame_count_p - delay_p; /* written minus queued */
- printf("playback: systime: %lli nsec, sample time %lli nsec \tsystime delta %lli \n",
- timediff(tstamp_p,trigger_tstamp_p),
- (long long)round(((float)curr_count_p * 1000000000.0 / 48000.0)),
- timediff(tstamp_p, trigger_tstamp_p) - (long long)round((double)curr_count_p * 1000000000.0 / 48000.0)
+ printf("playback: curr_count %lli driver count %lli, delta %lli\n",
+ (long long)curr_count_p * 1000000000LL / 48000 ,
+ timestamp2ns(audio_tstamp_p),
+ (long long)curr_count_p * 1000000000LL / 48000 - timestamp2ns(audio_tstamp_p)
+ );
+#endif
+
+ printf("playback: systime: %lli nsec, audio time %lli nsec, \tsystime delta %lli\n",
+ timediff(tstamp_p, trigger_tstamp_p),
+ timestamp2ns(audio_tstamp_p),
+ timediff(tstamp_p, trigger_tstamp_p) - timestamp2ns(audio_tstamp_p)
);
#endif
#if defined(TRACK_CAPTURE)
- gettimestamp(handle_c, &tstamp_c, &trigger_tstamp_c, &avail_c, &delay_c);
+ gettimestamp(handle_c, &tstamp_c, &trigger_tstamp_c, &audio_tstamp_c, &avail_c, &delay_c);
+#if defined(TRACK_SAMPLE_COUNTS)
curr_count_c = frame_count_c + delay_c; /* read plus queued */
- printf("\t capture: systime: %lli nsec, sample time %lli nsec \tsystime delta %lli \n",
- timediff(tstamp_c,trigger_tstamp_c),
- (long long)round(((float)curr_count_c * 1000000000.0 / 48000.0)),
- timediff(tstamp_c, trigger_tstamp_c) - (long long)round((double)curr_count_c * 1000000000.0 / 48000.0)
+
+ printf("capture: curr_count %lli driver count %lli, delta %lli\n",
+ (long long)curr_count_c * 1000000000LL / 48000 ,
+ timestamp2ns(audio_tstamp_c),
+ (long long)curr_count_c * 1000000000LL / 48000 - timestamp2ns(audio_tstamp_c)
+ );
+#endif
+
+ printf("\t capture: systime: %lli nsec, audio time %lli nsec, \tsystime delta %lli\n",
+ timediff(tstamp_c, trigger_tstamp_c),
+ timestamp2ns(audio_tstamp_c),
+ timediff(tstamp_c, trigger_tstamp_c) - timestamp2ns(audio_tstamp_c)
);
#endif