ALSA did not provide any direct means to infer the audio time for A/V sync and system/audio time correlations (eg. PulseAudio). Applications had to track the number of samples read/written and add/subtract the number of samples queued in the ring buffer. This accounting led to small errors, typically several samples, due to the two-step process. Computing the audio time in the kernel is more direct, as all the information is available in the same routines. Also add new .audio_wallclock routine to enable fine-grain synchronization between monotonic system time and audio hardware time. Using the wallclock, if supported in hardware, allows for a much better sub-microsecond precision and a common drift tracking for all devices sharing the same wall clock (master clock).
Showing the changes to include/uapi (1 of 5 files). Show all
Unified · Split
| @@ -136,7 +136,7 @@ struct snd_hwdep_dsp_image { · 135 unmodified lines | ||
| 136 | 136 | * * |
| 137 | 137 | *****************************************************************************/ |
| 138 | 138 | |
| 139 | −#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 10) | |
| 139 | +#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 11) | |
| 140 | 140 | |
| 141 | 141 | typedef unsigned long snd_pcm_uframes_t; |
| 142 | 142 | typedef signed long snd_pcm_sframes_t; |
| @@ -258,6 +258,7 @@ typedef int __bitwise snd_pcm_subformat_t; · 115 unmodified lines | ||
| 258 | 258 | #define SNDRV_PCM_INFO_JOINT_DUPLEX 0x00200000 /* playback and capture stream are somewhat correlated */ |
| 259 | 259 | #define SNDRV_PCM_INFO_SYNC_START 0x00400000 /* pcm support some kind of sync go */ |
| 260 | 260 | #define SNDRV_PCM_INFO_NO_PERIOD_WAKEUP 0x00800000 /* period wakeup can be disabled */ |
| 261 | +#define SNDRV_PCM_INFO_HAS_WALL_CLOCK 0x01000000 /* has audio wall clock for audio/system time sync */ | |
| 261 | 262 | #define SNDRV_PCM_INFO_FIFO_IN_FRAMES 0x80000000 /* internal kernel flag - FIFO size is in frames */ |
| 262 | 263 | |
| 263 | 264 | typedef int __bitwise snd_pcm_state_t; |
| @@ -406,7 +407,8 @@ struct snd_pcm_status { · 142 unmodified lines | ||
| 406 | 407 | snd_pcm_uframes_t avail_max; /* max frames available on hw since last status */ |
| 407 | 408 | snd_pcm_uframes_t overrange; /* count of ADC (capture) overrange detections from last status */ |
| 408 | 409 | snd_pcm_state_t suspended_state; /* suspended stream state */ |
| 409 | − unsigned char reserved[60]; /* must be filled with zero */ | |
| 410 | + struct timespec audio_tstamp; /* from sample counter or wall clock */ | |
| 411 | + unsigned char reserved[60-sizeof(struct timespec)]; /* must be filled with zero */ | |
| 410 | 412 | }; |
| 411 | 413 | |
| 412 | 414 | struct snd_pcm_mmap_status { |
| @@ -415,6 +417,7 @@ struct snd_pcm_mmap_status { · 2 unmodified lines | ||
| 415 | 417 | snd_pcm_uframes_t hw_ptr; /* RO: hw ptr (0...boundary-1) */ |
| 416 | 418 | struct timespec tstamp; /* Timestamp */ |
| 417 | 419 | snd_pcm_state_t suspended_state; /* RO: suspended stream state */ |
| 420 | + struct timespec audio_tstamp; /* from sample counter or wall clock */ | |
| 418 | 421 | }; |
| 419 | 422 | |
| 420 | 423 | struct snd_pcm_mmap_control { |