All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 00/10] audio timestamping evolutions
@ 2015-01-30 23:55 Pierre-Louis Bossart
  2015-01-30 23:55 ` [PATCH v4 01/10] ALSA: core: don't override timestamp unconditionally Pierre-Louis Bossart
                   ` (10 more replies)
  0 siblings, 11 replies; 22+ messages in thread
From: Pierre-Louis Bossart @ 2015-01-30 23:55 UTC (permalink / raw)
  To: alsa-devel; +Cc: Pierre-Louis Bossart

This series of patches was inspired by recent threads on the alsa
mailing list, as well issues detected with existing and upcoming
hardware:

1. there was a request from the PulseAudio community to get more
information from drivers to make rewinds safer. While the conclusion
was that it's nearly impossible for a driver developer to provide this
information, there are however ways to assess the granularity of the
hw_ptr updates using timestamping capabilities, and indirectly
understand how safe rewinds might be.

2. There was also a request to add a start_at capability based either
on system hr timers or a wall clock, which requires a means to expose
both types of information to applications. Rather than adding new sets
of timestamps, it is suggested the new start_at functionality relies
on the new definition provides by these patches

3. For new hardware, there is a neeed to let low-level drivers
handle timestamping instead of having the ALSA core do
it. Similarly there is a need to let the low-level driver update
the initial estimate for the trigger timestamp if there are
delays to start a stream (eg. with USB)

These patches try to provide an answer to these multiple needs by
building on the work done two years ago to expose wall clock
information to applications. The evolution is to let application
select which audio timestamp they are interested in, track the delay
and drifts between recurring measurements and get, when possible, an
idea of the accuracy of the underlying hardware. A backwards compatible mode
is provided in case userspace doesn't provide any timestamp selection (results
based on HDAudio wallclock for playback, hw_ptr in all other cases). 

The first 4 patches are corrections for misses in the way the system
and trigger timestamps are handled, and the last 6 provide the
additional audio timestamping selection. A second batch is planned to
enable hardware capabilities in a low-level drivers.

A corresponding set of patches is available for alsa-lib.

V2 changes:

trigger_tstamp:
trigger_tstamp_latched, pending redefined as bool
trigger_tstamp_latched reset in snd_pcm_pre_start()

audio_ts_config, report:
keep separate structure but use different bitfields for in and out.
use u32 instead of __u32, add comments that these structures are internal
COMPAT backwards compatible mode, uses WALL_CLOCK/LINK for HDAudio
playback and DEFAULT (hw_ptr) everywhere else

INFO bits:
reclaimed 32-bits from hw_params, renamed as info_ext
moved all timestamp info to info_ext

snd_pcm_status:
read only 32-bit audio_tstamp_data, ignore all other fields

V3/4:
Addressed feedback from Jaroslav:
no change to STATUS ioctl, new functionality introduced in STATUS_EXT
ioctl with r/w params.
bumped PCM protocol for detection on STATUS_EXT in userspace
used 32-bit word for accuracy report, no mantissa/exponent packing
rolled back info_ext changes, all INFO fields remain in same word

Merged comments from Liam (code simplifications)
fixed packing

Added driver_tstamp field in case there is a delay in passing the 
tstamp and audio_tstamp over IPC.



Pierre-Louis Bossart (10):
  ALSA: core: don't override timestamp unconditionally
  ALSA: core: allow for trigger_tstamp snapshot in .trigger
  ALSA: hda: read trigger_timestamp immediately after starting DMA
  ALSA: usb: update trigger timestamp on first non-zero URB submitted
  ALSA: core: selection of audio_tstamp type and accuracy reports
  ALSA: core: pass audio tstamp config from userspace
  ALSA: core: pass audio tstamp config from userspace in compat mode
  ALSA: core: replace .wall_clock by .get_time_info
  ALSA: hda: replace .wallclock by .get_time_info
  ALSA: bump PCM protocol to 2.0.13

 Documentation/sound/alsa/timestamping.txt | 200 ++++++++++++++++++++++++++++++
 include/sound/pcm.h                       |  67 +++++++++-
 include/uapi/sound/asound.h               |  36 +++++-
 sound/core/pcm_compat.c                   |  36 +++++-
 sound/core/pcm_lib.c                      |  88 ++++++++-----
 sound/core/pcm_native.c                   |  58 ++++++++-
 sound/pci/hda/hda_controller.c            |  43 +++++--
 sound/usb/pcm.c                           |   9 ++
 8 files changed, 478 insertions(+), 59 deletions(-)
 create mode 100644 Documentation/sound/alsa/timestamping.txt

-- 
1.9.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v4 01/10] ALSA: core: don't override timestamp unconditionally
  2015-01-30 23:55 [PATCH v4 00/10] audio timestamping evolutions Pierre-Louis Bossart
@ 2015-01-30 23:55 ` Pierre-Louis Bossart
  2015-01-30 23:55 ` [PATCH v4 02/10] ALSA: core: allow for trigger_tstamp snapshot in .trigger Pierre-Louis Bossart
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: Pierre-Louis Bossart @ 2015-01-30 23:55 UTC (permalink / raw)
  To: alsa-devel; +Cc: Pierre-Louis Bossart

timestamp in RUNNING mode is already taken in update_hw_ptr routine,
getting a new timestamp introduces offset between hw_ptr, audio_tstamp
and system time

Add else condition to read timestamp as fallback and only when
enabled

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 sound/core/pcm_native.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index ff3abc3..7bbc34d 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -720,8 +720,11 @@ int snd_pcm_status(struct snd_pcm_substream *substream,
 				runtime->status->audio_tstamp;
 			goto _tstamp_end;
 		}
+	} else {
+		/* get tstamp only in fallback mode and only if enabled */
+		if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
+			snd_pcm_gettime(runtime, &status->tstamp);
 	}
-	snd_pcm_gettime(runtime, &status->tstamp);
  _tstamp_end:
 	status->appl_ptr = runtime->control->appl_ptr;
 	status->hw_ptr = runtime->status->hw_ptr;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v4 02/10] ALSA: core: allow for trigger_tstamp snapshot in .trigger
  2015-01-30 23:55 [PATCH v4 00/10] audio timestamping evolutions Pierre-Louis Bossart
  2015-01-30 23:55 ` [PATCH v4 01/10] ALSA: core: don't override timestamp unconditionally Pierre-Louis Bossart
@ 2015-01-30 23:55 ` Pierre-Louis Bossart
  2015-02-02 10:48   ` Takashi Iwai
  2015-01-30 23:55 ` [PATCH v4 03/10] ALSA: hda: read trigger_timestamp immediately after starting DMA Pierre-Louis Bossart
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: Pierre-Louis Bossart @ 2015-01-30 23:55 UTC (permalink / raw)
  To: alsa-devel; +Cc: Pierre-Louis Bossart

Don't use generic snapshot of trigger_tstamp if low-level driver or
hardware can get a more precise value for better audio/system time
synchronization.

Also add definitions for delayed updates if actual trigger tstamp
can be only be provided after a delay due to hardware constraints.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 include/sound/pcm.h     | 2 ++
 sound/core/pcm_native.c | 4 +++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index cd09c1b..a8b98c5 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -279,6 +279,8 @@ struct snd_pcm_runtime {
 	/* -- Status -- */
 	struct snd_pcm_substream *trigger_master;
 	struct timespec trigger_tstamp;	/* trigger timestamp */
+	bool trigger_tstamp_latched;     /* trigger timestamp latched in low-level driver/hardware */
+	bool trigger_tstamp_pending_update; /* trigger timestamp being updated from initial estimate */
 	int overrange;
 	snd_pcm_uframes_t avail_max;
 	snd_pcm_uframes_t hw_ptr_base;	/* Position at buffer restart */
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 7bbc34d..4a97029 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -810,7 +810,8 @@ static void snd_pcm_trigger_tstamp(struct snd_pcm_substream *substream)
 	if (runtime->trigger_master == NULL)
 		return;
 	if (runtime->trigger_master == substream) {
-		snd_pcm_gettime(runtime, &runtime->trigger_tstamp);
+		if (runtime->trigger_tstamp_latched == 0)
+			snd_pcm_gettime(runtime, &runtime->trigger_tstamp);
 	} else {
 		snd_pcm_trigger_tstamp(runtime->trigger_master);
 		runtime->trigger_tstamp = runtime->trigger_master->runtime->trigger_tstamp;
@@ -979,6 +980,7 @@ static int snd_pcm_pre_start(struct snd_pcm_substream *substream, int state)
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
 	    !snd_pcm_playback_data(substream))
 		return -EPIPE;
+	runtime->trigger_tstamp_latched = 0;
 	runtime->trigger_master = substream;
 	return 0;
 }
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v4 03/10] ALSA: hda: read trigger_timestamp immediately after starting DMA
  2015-01-30 23:55 [PATCH v4 00/10] audio timestamping evolutions Pierre-Louis Bossart
  2015-01-30 23:55 ` [PATCH v4 01/10] ALSA: core: don't override timestamp unconditionally Pierre-Louis Bossart
  2015-01-30 23:55 ` [PATCH v4 02/10] ALSA: core: allow for trigger_tstamp snapshot in .trigger Pierre-Louis Bossart
@ 2015-01-30 23:55 ` Pierre-Louis Bossart
  2015-02-02 10:49   ` Takashi Iwai
  2015-01-30 23:55 ` [PATCH v4 04/10] ALSA: usb: update trigger timestamp on first non-zero URB submitted Pierre-Louis Bossart
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: Pierre-Louis Bossart @ 2015-01-30 23:55 UTC (permalink / raw)
  To: alsa-devel; +Cc: Pierre-Louis Bossart

Make sure wallclock counter and trigger timestamp are read very
close to each other for better alignment.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 sound/pci/hda/hda_controller.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index 0cfc9c8..271f86e 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -657,6 +657,9 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 		azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) & ~sbits);
 	if (start) {
 		azx_timecounter_init(substream, 0, 0);
+		snd_pcm_gettime(substream->runtime, &substream->runtime->trigger_tstamp);
+		substream->runtime->trigger_tstamp_latched = 1;
+
 		if (nsync > 1) {
 			cycle_t cycle_last;
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v4 04/10] ALSA: usb: update trigger timestamp on first non-zero URB submitted
  2015-01-30 23:55 [PATCH v4 00/10] audio timestamping evolutions Pierre-Louis Bossart
                   ` (2 preceding siblings ...)
  2015-01-30 23:55 ` [PATCH v4 03/10] ALSA: hda: read trigger_timestamp immediately after starting DMA Pierre-Louis Bossart
@ 2015-01-30 23:55 ` Pierre-Louis Bossart
  2015-02-02 10:52   ` Takashi Iwai
  2015-01-30 23:55 ` [PATCH v4 05/10] ALSA: core: selection of audio_tstamp type and accuracy reports Pierre-Louis Bossart
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: Pierre-Louis Bossart @ 2015-01-30 23:55 UTC (permalink / raw)
  To: alsa-devel; +Cc: Pierre-Louis Bossart

The first URBs are submitted during the prepare stage. When .trigger is
called, the ALSA core saves a trigger tstamp that doesn't correspond to
the actual time when the samples are submitted. The trigger_tstamp is
now updated when the first data are submitted to avoid any time offsets.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 sound/usb/pcm.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 0d8aba5..7c36fc1 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -1464,6 +1464,14 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
 	subs->last_frame_number = usb_get_current_frame_number(subs->dev);
 	subs->last_frame_number &= 0xFF; /* keep 8 LSBs */
 
+	if (runtime->trigger_tstamp_pending_update == 1) {
+		/* this is the first actual URB submitted,
+		 * update trigger timestamp to reflect actual start time
+		 */
+		snd_pcm_gettime(runtime, &runtime->trigger_tstamp);
+		runtime->trigger_tstamp_pending_update = 0;
+	}
+
 	spin_unlock_irqrestore(&subs->lock, flags);
 	urb->transfer_buffer_length = bytes;
 	if (period_elapsed)
@@ -1550,6 +1558,7 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
+		substream->runtime->trigger_tstamp_pending_update = 1;
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		subs->data_endpoint->prepare_data_urb = prepare_playback_urb;
 		subs->data_endpoint->retire_data_urb = retire_playback_urb;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v4 05/10] ALSA: core: selection of audio_tstamp type and accuracy reports
  2015-01-30 23:55 [PATCH v4 00/10] audio timestamping evolutions Pierre-Louis Bossart
                   ` (3 preceding siblings ...)
  2015-01-30 23:55 ` [PATCH v4 04/10] ALSA: usb: update trigger timestamp on first non-zero URB submitted Pierre-Louis Bossart
@ 2015-01-30 23:55 ` Pierre-Louis Bossart
  2015-01-31  7:37   ` Alexander E. Patrakov
  2015-01-30 23:55 ` [PATCH v4 06/10] ALSA: core: pass audio tstamp config from userspace Pierre-Louis Bossart
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: Pierre-Louis Bossart @ 2015-01-30 23:55 UTC (permalink / raw)
  To: alsa-devel; +Cc: Pierre-Louis Bossart

Audio timestamps can be extracted from sample counters, wall clocks,
PHC clocks (Ethernet AVB), on-demand synchronized snapshots. This
patch provides the ability to report timestamping capabilities, select
timestamp types and retrieve timestamp accuracy, if supported.
Details can be found in Documentations/sound/alsa/timestamping.txt

This functionality is introduced by reclaiming the reserved_aligned
field introduced by commit9c7066aef4a5eb8e4063de28f06c508bf6f2963a
in snd_pcm_status to provide userspace with selection/query capabilities.
Additional driver_tstamp and audio_tstamp_accuracy fields are also added.

snd_pcm_mmap_status remains a read-only structure with only
the audio timestamp value accessible from user space. The selection
of audio timestamp type is done through snd_pcm_status only

This commit does not impact ABI and does not impact the default
behavior. By default audio timestamp is aligned with hw_pointer and
reports the DMA position. Backwards compatibility is handled by using
the HDAudio wall clock for playback and the hw_ptr for all other
cases.

For timestamp selection a new STATUS_EXT ioctl is introduced with
read/write parameters. Alsa-lib will be modified to make use of
STATUS_EXT.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 Documentation/sound/alsa/timestamping.txt | 200 ++++++++++++++++++++++++++++++
 include/sound/pcm.h                       |  59 +++++++++
 include/uapi/sound/asound.h               |  34 ++++-
 3 files changed, 289 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/sound/alsa/timestamping.txt

diff --git a/Documentation/sound/alsa/timestamping.txt b/Documentation/sound/alsa/timestamping.txt
new file mode 100644
index 0000000..0b191a2
--- /dev/null
+++ b/Documentation/sound/alsa/timestamping.txt
@@ -0,0 +1,200 @@
+The ALSA API can provide two different system timestamps:
+
+- Trigger_tstamp is the system time snapshot taken when the .trigger
+callback is invoked. This snapshot is taken by the ALSA core in the
+general case, but specific hardware may have synchronization
+capabilities or conversely may only be able to provide a correct
+estimate with a delay. In the latter two cases, the low-level driver
+is responsible for updating the trigger_tstamp at the most appropriate
+and precise moment. Applications should not rely solely on the first
+trigger_tstamp but update their internal calculations if the driver
+provides a refined estimate with a delay.
+
+- tstamp is the current system timestamp updated during the last
+event or application query.
+The difference (tstamp - trigger_tstamp) defines the elapsed time.
+
+The ALSA API provides reports two basic pieces of information, avail
+and delay, which combined with the trigger and current system
+timestamps allow for applications to keep track of the 'fullness' of
+the ring buffer and the amount of queued samples.
+
+The use of these different pointers and time information depends on
+the application needs:
+
+- 'avail' reports how much can be written in the ring buffer
+- 'delay' reports the time it will take to hear a new sample after all
+queued samples have been played out.
+
+When timestamps are enabled, the avail/delay information is reported
+along with a snapshot of system time. Applications can select from
+CLOCK_REALTIME (NTP corrections including going backwards),
+CLOCK_MONOTONIC (NTP corrections but never going backwards),
+CLOCK_MONOTIC_RAW (without NTP corrections) and change the mode
+dynamically with sw_params
+
+
+The ALSA API also provide an audio_tstamp which reflects the passage
+of time as measured by different components of audio hardware.  In
+ascii-art, this could be represented as follows (for the playback
+case):
+
+
+--------------------------------------------------------------> time
+  ^               ^              ^                ^           ^
+  |               |              |                |           |
+ analog         link            dma              app       FullBuffer
+ time           time           time              time        time
+  |               |              |                |           |
+  |< codec delay >|<--hw delay-->|<queued samples>|<---avail->|
+  |<----------------- delay---------------------->|           |
+			         |<----ring buffer length---->|
+
+The analog time is taken at the last stage of the playback, as close
+as possible to the actual transducer
+
+The link time is taken at the output of the SOC/chipset as the samples
+are pushed on a link. The link time can be directly measured if
+supported in hardware by sample counters or wallclocks (e.g. with
+HDAudio 24MHz or PTP clock for networked solutions) or indirectly
+estimated (e.g. with the frame counter in USB).
+
+The DMA time is measured using counters - typically the least reliable
+of all measurements due to the bursty natured of DMA transfers.
+
+The app time corresponds to the time tracked by an application after
+writing in the ring buffer.
+
+The application can query what the hardware supports, define which
+audio time it wants reported by selecting the relevant settings in
+audio_tstamp_config fields, get an estimate of the timestamp
+accuracy. It can also request the delay-to-analog be included in the
+measurement. Direct access to the link time is very interesting on
+platforms that provide an embedded DSP; measuring directly the link
+time with dedicated hardware, possibly synchronized with system time,
+removes the need to keep track of internal DSP processing times and
+latency.
+
+In case the application requests an audio tstamp that is not supported
+in hardware/low-level driver, the type is overridden as DEFAULT and the
+timestamp will report the DMA time based on the hw_pointer value.
+
+For backwards compatibility with previous implementations that did not
+provide timestamp selection, with a zero-valued COMPAT timestamp type
+the results will default to the HDAudio wall clock for playback
+streams and to the DMA time (hw_ptr) in all other cases.
+
+The audio timestamp accuracy can be returned to user-space, so that
+appropriate decisions are made:
+
+- for dma time (default), the granularity of the transfers can be
+  inferred from the steps between updates and in turn provide
+  information on how much the application pointer can be rewound
+  safely.
+
+- the link time can be used to track long-term drifts between audio
+  and system time using the (tstamp-trigger_tstamp)/audio_tstamp
+  ratio, the precision helps define how much smoothing/low-pass
+  filtering is required. The link time can be either reset on startup
+  or reported as is (the latter being useful to compare progress of
+  different streams - but may require the wallclock to be always
+  running and not wrap-around during idle periods). If supported in
+  hardware, the absolute link time could also be used to define a
+  precise start time (patches WIP)
+
+- including the delay in the audio timestamp may
+  counter-intuitively not increase the precision of timestamps, e.g. if a
+  codec includes variable-latency DSP processing or a chain of
+  hardware components the delay is typically not known with precision.
+
+The accuracy is reported in nanosecond units (using an unsigned 32-bit
+word), which gives a max precision of 4.29s, more than enough for
+audio applications...
+
+Due to the varied nature of timestamping needs, even for a single
+application, the audio_tstamp_config can be changed dynamically. In
+the STATUS ioctl, the parameters are read-only and do not allow for
+any application selection. To work around this limitation without
+impacting legacy applications, a new STATUS_EXT ioctl is introduced
+with read/write parameters. ALSA-lib will be modified to make use of
+STATUS_EXT and effectively deprecate STATUS.
+
+The ALSA API only allows for a single audio timestamp to be reported
+at a time. This is a conscious design decision, reading the audio
+timestamps from hardware registers or from IPC takes time, the more
+timestamps are read the more imprecise the combined measurements
+are. To avoid any interpretation issues, a single (system, audio)
+timestamp is reported. Applications that need different timestamps
+will be required to issue multiple queries and perform an
+interpolation of the results
+
+In some hardware-specific configuration, the system timestamp is
+latched by a low-level audio subsytem, and the information provided
+back to the driver. Due to potential delays in the communication with
+the hardware, there is a risk of misalignment with the avail and delay
+information. To make sure applications are not confused, a
+driver_timestamp field is added in the snd_pcm_status structure; this
+timestamp shows when the information is put together by the driver
+before returning from the STATUS and STATUS_EXT ioctl. in most cases
+this driver_timestamp will be identical to the regular system tstamp.
+
+Examples of typestamping with HDaudio:
+
+1. DMA timestamp, no compensation for DMA+analog delay
+$ ./audio_time  -p --ts_type=1
+playback: systime: 341121338 nsec, audio time 342000000 nsec, 	systime delta -878662
+playback: systime: 426236663 nsec, audio time 427187500 nsec, 	systime delta -950837
+playback: systime: 597080580 nsec, audio time 598000000 nsec, 	systime delta -919420
+playback: systime: 682059782 nsec, audio time 683020833 nsec, 	systime delta -961051
+playback: systime: 852896415 nsec, audio time 853854166 nsec, 	systime delta -957751
+playback: systime: 937903344 nsec, audio time 938854166 nsec, 	systime delta -950822
+
+2. DMA timestamp, compensation for DMA+analog delay
+$ ./audio_time  -p --ts_type=1 -d
+playback: systime: 341053347 nsec, audio time 341062500 nsec, 	systime delta -9153
+playback: systime: 426072447 nsec, audio time 426062500 nsec, 	systime delta 9947
+playback: systime: 596899518 nsec, audio time 596895833 nsec, 	systime delta 3685
+playback: systime: 681915317 nsec, audio time 681916666 nsec, 	systime delta -1349
+playback: systime: 852741306 nsec, audio time 852750000 nsec, 	systime delta -8694
+
+3. link timestamp, compensation for DMA+analog delay
+$ ./audio_time  -p --ts_type=2 -d
+playback: systime: 341060004 nsec, audio time 341062791 nsec, 	systime delta -2787
+playback: systime: 426242074 nsec, audio time 426244875 nsec, 	systime delta -2801
+playback: systime: 597080992 nsec, audio time 597084583 nsec, 	systime delta -3591
+playback: systime: 682084512 nsec, audio time 682088291 nsec, 	systime delta -3779
+playback: systime: 852936229 nsec, audio time 852940916 nsec, 	systime delta -4687
+playback: systime: 938107562 nsec, audio time 938112708 nsec, 	systime delta -5146
+
+Example 1 shows that the timestamp at the DMA level is close to 1ms
+ahead of the actual playback time (as a side time this sort of
+measurement can help define rewind safeguards). Compensating for the
+DMA-link delay in example 2 helps remove the hardware buffering abut
+the information is still very jittery, with up to one sample of
+error. In example 3 where the timestamps are measured with the link
+wallclock, the timestamps show a monotonic behavior and a lower
+dispersion.
+
+Example 3 and 4 are with USB audio class. Example 3 shows a high
+offset between audio time and system time due to buffering. Example 4
+shows how compensating for the delay exposes a 1ms accuracy (due to
+the use of the frame counter by the driver)
+
+Example 3: DMA timestamp, no compensation for delay, delta of ~5ms
+$ ./audio_time -p -Dhw:1 -t1
+playback: systime: 120174019 nsec, audio time 125000000 nsec, 	systime delta -4825981
+playback: systime: 245041136 nsec, audio time 250000000 nsec, 	systime delta -4958864
+playback: systime: 370106088 nsec, audio time 375000000 nsec, 	systime delta -4893912
+playback: systime: 495040065 nsec, audio time 500000000 nsec, 	systime delta -4959935
+playback: systime: 620038179 nsec, audio time 625000000 nsec, 	systime delta -4961821
+playback: systime: 745087741 nsec, audio time 750000000 nsec, 	systime delta -4912259
+playback: systime: 870037336 nsec, audio time 875000000 nsec, 	systime delta -4962664
+
+Example 4: DMA timestamp, compensation for delay, delay of ~1ms
+$ ./audio_time -p -Dhw:1 -t1 -d
+playback: systime: 120190520 nsec, audio time 120000000 nsec, 	systime delta 190520
+playback: systime: 245036740 nsec, audio time 244000000 nsec, 	systime delta 1036740
+playback: systime: 370034081 nsec, audio time 369000000 nsec, 	systime delta 1034081
+playback: systime: 495159907 nsec, audio time 494000000 nsec, 	systime delta 1159907
+playback: systime: 620098824 nsec, audio time 619000000 nsec, 	systime delta 1098824
+playback: systime: 745031847 nsec, audio time 744000000 nsec, 	systime delta 1031847
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index a8b98c5..314b9d4 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -60,6 +60,9 @@ struct snd_pcm_hardware {
 
 struct snd_pcm_substream;
 
+struct snd_pcm_audio_tstamp_config; /* definitions further down */
+struct snd_pcm_audio_tstamp_report;
+
 struct snd_pcm_ops {
 	int (*open)(struct snd_pcm_substream *substream);
 	int (*close)(struct snd_pcm_substream *substream);
@@ -275,6 +278,57 @@ struct snd_pcm_hw_constraint_list {
 
 struct snd_pcm_hwptr_log;
 
+/*
+ * userspace-provided audio timestamp config to kernel,
+ * structure is for internal use only and filled with dedicated unpack routine
+ */
+struct snd_pcm_audio_tstamp_config {
+	/* 5 of max 16 bits used */
+	u32 type_requested:4;
+	u32 report_delay:1; /* add total delay to A/D or D/A */
+};
+
+static inline void snd_pcm_unpack_audio_tstamp_config(__u32 data,
+						struct snd_pcm_audio_tstamp_config *config)
+{
+	config->type_requested = data & 0xF;
+	config->report_delay = (data >> 4) & 1;
+}
+
+/*
+ * kernel-provided audio timestamp report to user-space
+ * structure is for internal use only and read by dedicated pack routine
+ */
+struct snd_pcm_audio_tstamp_report {
+	/* 6 of max 16 bits used for bit-fields */
+
+	/* for backwards compatibility */
+	u32 valid:1;
+
+	/* actual type if hardware could not support requested timestamp */
+	u32 actual_type:4;
+
+	/* accuracy represented in ns units */
+	u32 accuracy_report:1; /* 0 if accuracy unknown, 1 if accuracy field is valid */
+	u32 accuracy; /* up to 4.29s, will be packed in separate field  */
+};
+
+static inline void snd_pcm_pack_audio_tstamp_report(__u32 *data, __u32 *accuracy,
+						struct snd_pcm_audio_tstamp_report *report)
+{
+	u32 tmp;
+
+	tmp = report->accuracy_report;
+	tmp <<= 4;
+	tmp |= report->actual_type;
+	tmp <<= 1;
+	tmp |= report->valid;
+
+	*data |= (tmp << 16);
+	*accuracy = report->accuracy;
+}
+
+
 struct snd_pcm_runtime {
 	/* -- Status -- */
 	struct snd_pcm_substream *trigger_master;
@@ -356,6 +410,11 @@ struct snd_pcm_runtime {
 
 	struct snd_dma_buffer *dma_buffer_p;	/* allocated buffer */
 
+	/* -- audio timestamp config -- */
+	struct snd_pcm_audio_tstamp_config audio_tstamp_config;
+	struct snd_pcm_audio_tstamp_report audio_tstamp_report;
+	struct timespec driver_tstamp;
+
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
 	/* -- OSS things -- */
 	struct snd_pcm_oss_runtime oss;
diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h
index 0e88e7a..acef4e4 100644
--- a/include/uapi/sound/asound.h
+++ b/include/uapi/sound/asound.h
@@ -267,10 +267,17 @@ typedef int __bitwise snd_pcm_subformat_t;
 #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 */
+#define SNDRV_PCM_INFO_HAS_WALL_CLOCK   0x01000000      /* (Deprecated)has audio wall clock for audio/system time sync */
+#define SNDRV_PCM_INFO_HAS_LINK_ATIME              0x01000000  /* report hardware link audio time, reset on startup */
+#define SNDRV_PCM_INFO_HAS_LINK_ABSOLUTE_ATIME     0x02000000  /* report absolute hardware link audio time, not reset on startup */
+#define SNDRV_PCM_INFO_HAS_LINK_ESTIMATED_ATIME    0x04000000  /* report estimated link audio time */
+#define SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME 0x08000000  /* report synchronized audio/system time */
+
 #define SNDRV_PCM_INFO_DRAIN_TRIGGER	0x40000000		/* internal kernel flag - trigger in drain */
 #define SNDRV_PCM_INFO_FIFO_IN_FRAMES	0x80000000	/* internal kernel flag - FIFO size is in frames */
 
+
+
 typedef int __bitwise snd_pcm_state_t;
 #define	SNDRV_PCM_STATE_OPEN		((__force snd_pcm_state_t) 0) /* stream is open */
 #define	SNDRV_PCM_STATE_SETUP		((__force snd_pcm_state_t) 1) /* stream has a setup */
@@ -408,6 +415,22 @@ struct snd_pcm_channel_info {
 	unsigned int step;		/* samples distance in bits */
 };
 
+enum {
+	/*
+	 *  first definition for backwards compatibility only,
+	 *  maps to wallclock/link time for HDAudio playback and DEFAULT/DMA time for everything else
+	 */
+	SNDRV_PCM_AUDIO_TSTAMP_TYPE_COMPAT = 0,
+
+	/* timestamp definitions */
+	SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT = 1,           /* DMA time, reported as per hw_ptr */
+	SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK = 2,	           /* link time reported by sample or wallclock counter, reset on startup */
+	SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_ABSOLUTE = 3,	   /* link time reported by sample or wallclock counter, not reset on startup */
+	SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_ESTIMATED = 4,    /* link time estimated indirectly */
+	SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED = 5, /* link time synchronized with system time */
+	SNDRV_PCM_AUDIO_TSTAMP_TYPE_LAST = SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED
+};
+
 struct snd_pcm_status {
 	snd_pcm_state_t state;		/* stream state */
 	struct timespec trigger_tstamp;	/* time when stream was started/stopped/paused */
@@ -419,9 +442,11 @@ struct snd_pcm_status {
 	snd_pcm_uframes_t avail_max;	/* max frames available on hw since last status */
 	snd_pcm_uframes_t overrange;	/* count of ADC (capture) overrange detections from last status */
 	snd_pcm_state_t suspended_state; /* suspended stream state */
-	__u32 reserved_alignment;	/* must be filled with zero */
-	struct timespec audio_tstamp;	/* from sample counter or wall clock */
-	unsigned char reserved[56-sizeof(struct timespec)]; /* must be filled with zero */
+	__u32 audio_tstamp_data;	 /* needed for 64-bit alignment, used for configs/report to/from userspace */
+	struct timespec audio_tstamp;	/* sample counter, wall clock, PHC or on-demand sync'ed */
+	struct timespec driver_tstamp;	/* useful in case reference system tstamp is reported with delay */
+	__u32 audio_tstamp_accuracy;	/* in ns units, only valid if indicated in audio_tstamp_data */
+	unsigned char reserved[52-2*sizeof(struct timespec)]; /* must be filled with zero */
 };
 
 struct snd_pcm_mmap_status {
@@ -534,6 +559,7 @@ enum {
 #define SNDRV_PCM_IOCTL_DELAY		_IOR('A', 0x21, snd_pcm_sframes_t)
 #define SNDRV_PCM_IOCTL_HWSYNC		_IO('A', 0x22)
 #define SNDRV_PCM_IOCTL_SYNC_PTR	_IOWR('A', 0x23, struct snd_pcm_sync_ptr)
+#define SNDRV_PCM_IOCTL_STATUS_EXT	_IOWR('A', 0x24, struct snd_pcm_status)
 #define SNDRV_PCM_IOCTL_CHANNEL_INFO	_IOR('A', 0x32, struct snd_pcm_channel_info)
 #define SNDRV_PCM_IOCTL_PREPARE		_IO('A', 0x40)
 #define SNDRV_PCM_IOCTL_RESET		_IO('A', 0x41)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v4 06/10] ALSA: core: pass audio tstamp config from userspace
  2015-01-30 23:55 [PATCH v4 00/10] audio timestamping evolutions Pierre-Louis Bossart
                   ` (4 preceding siblings ...)
  2015-01-30 23:55 ` [PATCH v4 05/10] ALSA: core: selection of audio_tstamp type and accuracy reports Pierre-Louis Bossart
@ 2015-01-30 23:55 ` Pierre-Louis Bossart
  2015-01-30 23:56 ` [PATCH v4 07/10] ALSA: core: pass audio tstamp config from userspace in compat mode Pierre-Louis Bossart
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: Pierre-Louis Bossart @ 2015-01-30 23:55 UTC (permalink / raw)
  To: alsa-devel; +Cc: Pierre-Louis Bossart

Let userspace select audio timestamp config when the
STATUS_EXT ioctl is used, ignore and zero all
other fields
No change for the existing STATUS ioctl, parameters
are treated as read-only.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 sound/core/pcm_native.c | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 4a97029..544f563 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -753,12 +753,27 @@ int snd_pcm_status(struct snd_pcm_substream *substream,
 }
 
 static int snd_pcm_status_user(struct snd_pcm_substream *substream,
-			       struct snd_pcm_status __user * _status)
+			       struct snd_pcm_status __user * _status,
+			       bool ext)
 {
 	struct snd_pcm_status status;
 	int res;
-	
-	memset(&status, 0, sizeof(status));
+	u32  audio_tstamp_data;
+	u32  __user *_audio_tstamp_data;
+
+	if (ext == false) {
+		memset(&status, 0, sizeof(status));
+	} else {
+		/*
+		 * parameters are read/write, get audio_tstamp_data from user,
+		 * ignore rest of status structure
+		 */
+		_audio_tstamp_data = (u32 __user *)(&_status->audio_tstamp_data);
+		if (get_user(audio_tstamp_data, _audio_tstamp_data))
+			return -EFAULT;
+		memset(&status, 0, sizeof(status));
+		status.audio_tstamp_data = audio_tstamp_data;
+	}
 	res = snd_pcm_status(substream, &status);
 	if (res < 0)
 		return res;
@@ -2723,7 +2738,9 @@ static int snd_pcm_common_ioctl1(struct file *file,
 	case SNDRV_PCM_IOCTL_SW_PARAMS:
 		return snd_pcm_sw_params_user(substream, arg);
 	case SNDRV_PCM_IOCTL_STATUS:
-		return snd_pcm_status_user(substream, arg);
+		return snd_pcm_status_user(substream, arg, false);
+	case SNDRV_PCM_IOCTL_STATUS_EXT:
+		return snd_pcm_status_user(substream, arg, true);
 	case SNDRV_PCM_IOCTL_CHANNEL_INFO:
 		return snd_pcm_channel_info_user(substream, arg);
 	case SNDRV_PCM_IOCTL_PREPARE:
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v4 07/10] ALSA: core: pass audio tstamp config from userspace in compat mode
  2015-01-30 23:55 [PATCH v4 00/10] audio timestamping evolutions Pierre-Louis Bossart
                   ` (5 preceding siblings ...)
  2015-01-30 23:55 ` [PATCH v4 06/10] ALSA: core: pass audio tstamp config from userspace Pierre-Louis Bossart
@ 2015-01-30 23:56 ` Pierre-Louis Bossart
  2015-01-30 23:56 ` [PATCH v4 08/10] ALSA: core: replace .wall_clock by .get_time_info Pierre-Louis Bossart
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: Pierre-Louis Bossart @ 2015-01-30 23:56 UTC (permalink / raw)
  To: alsa-devel; +Cc: Pierre-Louis Bossart

Let userspace select audio timestamp config, ignore and zero all
other fields
Use audio_tstamp_data to retrieve config and pass report back to
user space

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 sound/core/pcm_compat.c | 36 ++++++++++++++++++++++++++++++------
 1 file changed, 30 insertions(+), 6 deletions(-)

diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index 2d957ba..188b991 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -194,18 +194,36 @@ struct snd_pcm_status32 {
 	u32 avail_max;
 	u32 overrange;
 	s32 suspended_state;
-	u32 reserved_alignment;
+	u32 audio_tstamp_data;
 	struct compat_timespec audio_tstamp;
-	unsigned char reserved[56-sizeof(struct compat_timespec)];
+	struct compat_timespec driver_tstamp;
+	u32 audio_tstamp_accuracy;
+	unsigned char reserved[52-2*sizeof(struct compat_timespec)];
 } __attribute__((packed));
 
 
 static int snd_pcm_status_user_compat(struct snd_pcm_substream *substream,
-				      struct snd_pcm_status32 __user *src)
+				      struct snd_pcm_status32 __user *src,
+				      bool ext)
 {
 	struct snd_pcm_status status;
 	int err;
-
+	u32  audio_tstamp_data;
+	u32  __user *_audio_tstamp_data;
+
+	if (ext == false) {
+		memset(&status, 0, sizeof(status));
+	}  else {
+		/*
+		 * parameters are read/write, get audio_tstamp_data from user,
+		 * ignore rest of status structure
+		 */
+		_audio_tstamp_data = (u32 __user *)(&src->audio_tstamp_data);
+		if (get_user(audio_tstamp_data, _audio_tstamp_data))
+			return -EFAULT;
+		memset(&status, 0, sizeof(status));
+		status.audio_tstamp_data = audio_tstamp_data;
+	}
 	err = snd_pcm_status(substream, &status);
 	if (err < 0)
 		return err;
@@ -222,7 +240,10 @@ static int snd_pcm_status_user_compat(struct snd_pcm_substream *substream,
 	    put_user(status.avail_max, &src->avail_max) ||
 	    put_user(status.overrange, &src->overrange) ||
 	    put_user(status.suspended_state, &src->suspended_state) ||
-	    compat_put_timespec(&status.audio_tstamp, &src->audio_tstamp))
+	    put_user(status.audio_tstamp_data, &src->audio_tstamp_data) ||
+	    compat_put_timespec(&status.audio_tstamp, &src->audio_tstamp) ||
+	    compat_put_timespec(&status.driver_tstamp, &src->driver_tstamp) ||
+	    put_user(status.audio_tstamp_accuracy, &src->audio_tstamp_accuracy))
 		return -EFAULT;
 
 	return err;
@@ -457,6 +478,7 @@ enum {
 	SNDRV_PCM_IOCTL_HW_PARAMS32 = _IOWR('A', 0x11, struct snd_pcm_hw_params32),
 	SNDRV_PCM_IOCTL_SW_PARAMS32 = _IOWR('A', 0x13, struct snd_pcm_sw_params32),
 	SNDRV_PCM_IOCTL_STATUS32 = _IOR('A', 0x20, struct snd_pcm_status32),
+	SNDRV_PCM_IOCTL_STATUS_EXT32 = _IOWR('A', 0x24, struct snd_pcm_status32),
 	SNDRV_PCM_IOCTL_DELAY32 = _IOR('A', 0x21, s32),
 	SNDRV_PCM_IOCTL_CHANNEL_INFO32 = _IOR('A', 0x32, struct snd_pcm_channel_info32),
 	SNDRV_PCM_IOCTL_REWIND32 = _IOW('A', 0x46, u32),
@@ -517,7 +539,9 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
 	case SNDRV_PCM_IOCTL_SW_PARAMS32:
 		return snd_pcm_ioctl_sw_params_compat(substream, argp);
 	case SNDRV_PCM_IOCTL_STATUS32:
-		return snd_pcm_status_user_compat(substream, argp);
+		return snd_pcm_status_user_compat(substream, argp, false);
+	case SNDRV_PCM_IOCTL_STATUS_EXT32:
+		return snd_pcm_status_user_compat(substream, argp, true);
 	case SNDRV_PCM_IOCTL_SYNC_PTR32:
 		return snd_pcm_ioctl_sync_ptr_compat(substream, argp);
 	case SNDRV_PCM_IOCTL_CHANNEL_INFO32:
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v4 08/10] ALSA: core: replace .wall_clock by .get_time_info
  2015-01-30 23:55 [PATCH v4 00/10] audio timestamping evolutions Pierre-Louis Bossart
                   ` (6 preceding siblings ...)
  2015-01-30 23:56 ` [PATCH v4 07/10] ALSA: core: pass audio tstamp config from userspace in compat mode Pierre-Louis Bossart
@ 2015-01-30 23:56 ` Pierre-Louis Bossart
  2015-01-30 23:56 ` [PATCH v4 09/10] ALSA: hda: replace .wallclock " Pierre-Louis Bossart
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: Pierre-Louis Bossart @ 2015-01-30 23:56 UTC (permalink / raw)
  To: alsa-devel; +Cc: Pierre-Louis Bossart

Introduce more generic .get_time_info to retrieve
system timestamp and audio timestamp in single routine.
The .wall_clock method is removed but the same functionality is
preserved for backwards legacy.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 include/sound/pcm.h     |  6 ++--
 sound/core/pcm_lib.c    | 88 +++++++++++++++++++++++++++++++++----------------
 sound/core/pcm_native.c | 24 ++++++++++++++
 3 files changed, 87 insertions(+), 31 deletions(-)

diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 314b9d4..ad6d9f3 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -74,8 +74,10 @@ struct snd_pcm_ops {
 	int (*prepare)(struct snd_pcm_substream *substream);
 	int (*trigger)(struct snd_pcm_substream *substream, int cmd);
 	snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *substream);
-	int (*wall_clock)(struct snd_pcm_substream *substream,
-			  struct timespec *audio_ts);
+	int (*get_time_info)(struct snd_pcm_substream *substream,
+			struct timespec *system_ts, struct timespec *audio_ts,
+			struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
+			struct snd_pcm_audio_tstamp_report *audio_tstamp_report);
 	int (*copy)(struct snd_pcm_substream *substream, int channel,
 		    snd_pcm_uframes_t pos,
 		    void __user *buf, snd_pcm_uframes_t count);
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index db05e04..9fbb0db 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -232,6 +232,49 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream,
 	return 0;
 }
 
+static void update_audio_tstamp(struct snd_pcm_substream *substream,
+				struct timespec *curr_tstamp,
+				struct timespec *audio_tstamp)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	u64 audio_frames, audio_nsecs;
+	struct timespec driver_tstamp;
+
+	if (runtime->tstamp_mode != SNDRV_PCM_TSTAMP_ENABLE)
+		return;
+
+	if (!(substream->ops->get_time_info) ||
+		(runtime->audio_tstamp_report.actual_type ==
+			SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT)) {
+
+		/*
+		 * provide audio timestamp derived from pointer position
+		 * add delay only if requested
+		 */
+
+		audio_frames = runtime->hw_ptr_wrap + runtime->status->hw_ptr;
+
+		if (runtime->audio_tstamp_config.report_delay) {
+			if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+				audio_frames -=  runtime->delay;
+			else
+				audio_frames +=  runtime->delay;
+		}
+		audio_nsecs = div_u64(audio_frames * 1000000000LL,
+				runtime->rate);
+		*audio_tstamp = ns_to_timespec(audio_nsecs);
+	}
+	runtime->status->audio_tstamp = *audio_tstamp;
+	runtime->status->tstamp = *curr_tstamp;
+
+	/*
+	 * re-take a driver timestamp to let apps detect if the reference tstamp
+	 * read by low-level hardware was provided with a delay
+	 */
+	snd_pcm_gettime(substream->runtime, (struct timespec *)&driver_tstamp);
+	runtime->driver_tstamp = driver_tstamp;
+}
+
 static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
 				  unsigned int in_interrupt)
 {
@@ -256,11 +299,18 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
 	pos = substream->ops->pointer(substream);
 	curr_jiffies = jiffies;
 	if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) {
-		snd_pcm_gettime(runtime, (struct timespec *)&curr_tstamp);
-
-		if ((runtime->hw.info & SNDRV_PCM_INFO_HAS_WALL_CLOCK) &&
-			(substream->ops->wall_clock))
-			substream->ops->wall_clock(substream, &audio_tstamp);
+		if ((substream->ops->get_time_info) &&
+			(runtime->audio_tstamp_config.type_requested != SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT)) {
+			substream->ops->get_time_info(substream, &curr_tstamp,
+						&audio_tstamp,
+						&runtime->audio_tstamp_config,
+						&runtime->audio_tstamp_report);
+
+			/* re-test in case tstamp type is not supported in hardware and was demoted to DEFAULT */
+			if (runtime->audio_tstamp_report.actual_type == SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT)
+				snd_pcm_gettime(runtime, (struct timespec *)&curr_tstamp);
+		} else
+			snd_pcm_gettime(runtime, (struct timespec *)&curr_tstamp);
 	}
 
 	if (pos == SNDRV_PCM_POS_XRUN) {
@@ -403,8 +453,10 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
 	}
 
  no_delta_check:
-	if (runtime->status->hw_ptr == new_hw_ptr)
+	if (runtime->status->hw_ptr == new_hw_ptr) {
+		update_audio_tstamp(substream, &curr_tstamp, &audio_tstamp);
 		return 0;
+	}
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
 	    runtime->silence_size > 0)
@@ -426,30 +478,8 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
 		snd_BUG_ON(crossed_boundary != 1);
 		runtime->hw_ptr_wrap += runtime->boundary;
 	}
-	if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) {
-		runtime->status->tstamp = curr_tstamp;
 
-		if (!(runtime->hw.info & SNDRV_PCM_INFO_HAS_WALL_CLOCK)) {
-			/*
-			 * no wall clock available, provide audio timestamp
-			 * derived from pointer position+delay
-			 */
-			u64 audio_frames, audio_nsecs;
-
-			if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-				audio_frames = runtime->hw_ptr_wrap
-					+ runtime->status->hw_ptr
-					- runtime->delay;
-			else
-				audio_frames = runtime->hw_ptr_wrap
-					+ runtime->status->hw_ptr
-					+ runtime->delay;
-			audio_nsecs = div_u64(audio_frames * 1000000000LL,
-					runtime->rate);
-			audio_tstamp = ns_to_timespec(audio_nsecs);
-		}
-		runtime->status->audio_tstamp = audio_tstamp;
-	}
+	update_audio_tstamp(substream, &curr_tstamp, &audio_tstamp);
 
 	return snd_pcm_update_state(substream, runtime);
 }
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 544f563..5d34e7b 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -707,6 +707,23 @@ int snd_pcm_status(struct snd_pcm_substream *substream,
 	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	snd_pcm_stream_lock_irq(substream);
+
+	snd_pcm_unpack_audio_tstamp_config(status->audio_tstamp_data,
+					&runtime->audio_tstamp_config);
+
+	/* backwards compatible behavior */
+	if (runtime->audio_tstamp_config.type_requested ==
+		SNDRV_PCM_AUDIO_TSTAMP_TYPE_COMPAT) {
+		if (runtime->hw.info & SNDRV_PCM_INFO_HAS_WALL_CLOCK)
+			runtime->audio_tstamp_config.type_requested =
+				SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK;
+		else
+			runtime->audio_tstamp_config.type_requested =
+				SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT;
+		runtime->audio_tstamp_report.valid = 0;
+	} else
+		runtime->audio_tstamp_report.valid = 1;
+
 	status->state = runtime->status->state;
 	status->suspended_state = runtime->status->suspended_state;
 	if (status->state == SNDRV_PCM_STATE_OPEN)
@@ -716,8 +733,15 @@ int snd_pcm_status(struct snd_pcm_substream *substream,
 		snd_pcm_update_hw_ptr(substream);
 		if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) {
 			status->tstamp = runtime->status->tstamp;
+			status->driver_tstamp = runtime->driver_tstamp;
 			status->audio_tstamp =
 				runtime->status->audio_tstamp;
+			if (runtime->audio_tstamp_report.valid == 1)
+				/* backwards compatibility, no report provided in COMPAT mode */
+				snd_pcm_pack_audio_tstamp_report(&status->audio_tstamp_data,
+								&status->audio_tstamp_accuracy,
+								&runtime->audio_tstamp_report);
+
 			goto _tstamp_end;
 		}
 	} else {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v4 09/10] ALSA: hda: replace .wallclock by .get_time_info
  2015-01-30 23:55 [PATCH v4 00/10] audio timestamping evolutions Pierre-Louis Bossart
                   ` (7 preceding siblings ...)
  2015-01-30 23:56 ` [PATCH v4 08/10] ALSA: core: replace .wall_clock by .get_time_info Pierre-Louis Bossart
@ 2015-01-30 23:56 ` Pierre-Louis Bossart
  2015-01-30 23:56 ` [PATCH v4 10/10] ALSA: bump PCM protocol to 2.0.13 Pierre-Louis Bossart
  2015-02-02 11:03 ` [PATCH v4 00/10] audio timestamping evolutions Takashi Iwai
  10 siblings, 0 replies; 22+ messages in thread
From: Pierre-Louis Bossart @ 2015-01-30 23:56 UTC (permalink / raw)
  To: alsa-devel; +Cc: Pierre-Louis Bossart

No real functional change, only take wall clock and system time
in same routine and add accuracy report.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 sound/pci/hda/hda_controller.c | 40 +++++++++++++++++++++++++++++-----------
 1 file changed, 29 insertions(+), 11 deletions(-)

diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index 271f86e..7ecda0e 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -732,17 +732,32 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream)
 			       azx_get_position(chip, azx_dev));
 }
 
-static int azx_get_wallclock_tstamp(struct snd_pcm_substream *substream,
-				struct timespec *ts)
+static int azx_get_time_info(struct snd_pcm_substream *substream,
+			struct timespec *system_ts, struct timespec *audio_ts,
+			struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
+			struct snd_pcm_audio_tstamp_report *audio_tstamp_report)
 {
 	struct azx_dev *azx_dev = get_azx_dev(substream);
 	u64 nsec;
 
-	nsec = timecounter_read(&azx_dev->azx_tc);
-	nsec = div_u64(nsec, 3); /* can be optimized */
-	nsec = azx_adjust_codec_delay(substream, nsec);
+	if ((substream->runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_ATIME) &&
+		(audio_tstamp_config->type_requested == SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK)) {
 
-	*ts = ns_to_timespec(nsec);
+		snd_pcm_gettime(substream->runtime, system_ts);
+
+		nsec = timecounter_read(&azx_dev->azx_tc);
+		nsec = div_u64(nsec, 3); /* can be optimized */
+		if (audio_tstamp_config->report_delay)
+			nsec = azx_adjust_codec_delay(substream, nsec);
+
+		*audio_ts = ns_to_timespec(nsec);
+
+		audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK;
+		audio_tstamp_report->accuracy_report = 1; /* rest of structure is valid */
+		audio_tstamp_report->accuracy = 42; /* 24 MHz WallClock == 42ns resolution */
+
+	} else
+		audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT;
 
 	return 0;
 }
@@ -756,7 +771,8 @@ static struct snd_pcm_hardware azx_pcm_hw = {
 				 /* SNDRV_PCM_INFO_RESUME |*/
 				 SNDRV_PCM_INFO_PAUSE |
 				 SNDRV_PCM_INFO_SYNC_START |
-				 SNDRV_PCM_INFO_HAS_WALL_CLOCK |
+				 SNDRV_PCM_INFO_HAS_WALL_CLOCK | /* legacy */
+				 SNDRV_PCM_INFO_HAS_LINK_ATIME |
 				 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP),
 	.formats =		SNDRV_PCM_FMTBIT_S16_LE,
 	.rates =		SNDRV_PCM_RATE_48000,
@@ -842,10 +858,12 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
 		return -EINVAL;
 	}
 
-	/* disable WALLCLOCK timestamps for capture streams
+	/* disable LINK_ATIME timestamps for capture streams
 	   until we figure out how to handle digital inputs */
-	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
-		runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_WALL_CLOCK;
+	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+		runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_WALL_CLOCK; /* legacy */
+		runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_LINK_ATIME;
+	}
 
 	spin_lock_irqsave(&chip->reg_lock, flags);
 	azx_dev->substream = substream;
@@ -877,7 +895,7 @@ static struct snd_pcm_ops azx_pcm_ops = {
 	.prepare = azx_pcm_prepare,
 	.trigger = azx_pcm_trigger,
 	.pointer = azx_pcm_pointer,
-	.wall_clock =  azx_get_wallclock_tstamp,
+	.get_time_info =  azx_get_time_info,
 	.mmap = azx_pcm_mmap,
 	.page = snd_pcm_sgbuf_ops_page,
 };
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v4 10/10] ALSA: bump PCM protocol to 2.0.13
  2015-01-30 23:55 [PATCH v4 00/10] audio timestamping evolutions Pierre-Louis Bossart
                   ` (8 preceding siblings ...)
  2015-01-30 23:56 ` [PATCH v4 09/10] ALSA: hda: replace .wallclock " Pierre-Louis Bossart
@ 2015-01-30 23:56 ` Pierre-Louis Bossart
  2015-02-02 11:03 ` [PATCH v4 00/10] audio timestamping evolutions Takashi Iwai
  10 siblings, 0 replies; 22+ messages in thread
From: Pierre-Louis Bossart @ 2015-01-30 23:56 UTC (permalink / raw)
  To: alsa-devel; +Cc: Pierre-Louis Bossart

Bump PCM protocol to enable use of STATUS_EXT ioctls, older
apps will still use STATUS and audio timestamp configuration
is not supported (backwards compatible behavior).

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 include/uapi/sound/asound.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h
index acef4e4..3d46e9a 100644
--- a/include/uapi/sound/asound.h
+++ b/include/uapi/sound/asound.h
@@ -140,7 +140,7 @@ struct snd_hwdep_dsp_image {
  *                                                                           *
  *****************************************************************************/
 
-#define SNDRV_PCM_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 12)
+#define SNDRV_PCM_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 13)
 
 typedef unsigned long snd_pcm_uframes_t;
 typedef signed long snd_pcm_sframes_t;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH v4 05/10] ALSA: core: selection of audio_tstamp type and accuracy reports
  2015-01-30 23:55 ` [PATCH v4 05/10] ALSA: core: selection of audio_tstamp type and accuracy reports Pierre-Louis Bossart
@ 2015-01-31  7:37   ` Alexander E. Patrakov
  2015-01-31 20:01     ` Pierre-Louis Bossart
  0 siblings, 1 reply; 22+ messages in thread
From: Alexander E. Patrakov @ 2015-01-31  7:37 UTC (permalink / raw)
  To: Pierre-Louis Bossart, alsa-devel

31.01.2015 04:55, Pierre-Louis Bossart wrote:
> Audio timestamps can be extracted from sample counters, wall clocks,
> PHC clocks (Ethernet AVB), on-demand synchronized snapshots. This
> patch provides the ability to report timestamping capabilities, select
> timestamp types and retrieve timestamp accuracy, if supported.
> Details can be found in Documentations/sound/alsa/timestamping.txt

I think that it is a good idea to add some example ./audio_time output 
on a card that is neither HDAudio nor USB audio (i.e. a card not 
specifically touched by your patches), so that the fallback behavior is 
known.

-- 
Alexander E. Patrakov

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v4 05/10] ALSA: core: selection of audio_tstamp type and accuracy reports
  2015-01-31  7:37   ` Alexander E. Patrakov
@ 2015-01-31 20:01     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 22+ messages in thread
From: Pierre-Louis Bossart @ 2015-01-31 20:01 UTC (permalink / raw)
  To: Alexander E. Patrakov, alsa-devel

On 1/31/15 1:37 AM, Alexander E. Patrakov wrote:
> 31.01.2015 04:55, Pierre-Louis Bossart wrote:
>> Audio timestamps can be extracted from sample counters, wall clocks,
>> PHC clocks (Ethernet AVB), on-demand synchronized snapshots. This
>> patch provides the ability to report timestamping capabilities, select
>> timestamp types and retrieve timestamp accuracy, if supported.
>> Details can be found in Documentations/sound/alsa/timestamping.txt
>
> I think that it is a good idea to add some example ./audio_time output
> on a card that is neither HDAudio nor USB audio (i.e. a card not
> specifically touched by your patches), so that the fallback behavior is
> known.

I didn't change the USB behavior, only fixed the way the trigger_tstamp 
is found, and yes it shows what the fallback is. And the documentation 
is already quite long, I wonder how many people will read it to the end 
without falling into a deep coma ;-)

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v4 02/10] ALSA: core: allow for trigger_tstamp snapshot in .trigger
  2015-01-30 23:55 ` [PATCH v4 02/10] ALSA: core: allow for trigger_tstamp snapshot in .trigger Pierre-Louis Bossart
@ 2015-02-02 10:48   ` Takashi Iwai
  0 siblings, 0 replies; 22+ messages in thread
From: Takashi Iwai @ 2015-02-02 10:48 UTC (permalink / raw)
  To: Pierre-Louis Bossart; +Cc: alsa-devel

At Fri, 30 Jan 2015 17:55:55 -0600,
Pierre-Louis Bossart wrote:
> 
> Don't use generic snapshot of trigger_tstamp if low-level driver or
> hardware can get a more precise value for better audio/system time
> synchronization.
> 
> Also add definitions for delayed updates if actual trigger tstamp
> can be only be provided after a delay due to hardware constraints.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  include/sound/pcm.h     | 2 ++
>  sound/core/pcm_native.c | 4 +++-
>  2 files changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/include/sound/pcm.h b/include/sound/pcm.h
> index cd09c1b..a8b98c5 100644
> --- a/include/sound/pcm.h
> +++ b/include/sound/pcm.h
> @@ -279,6 +279,8 @@ struct snd_pcm_runtime {
>  	/* -- Status -- */
>  	struct snd_pcm_substream *trigger_master;
>  	struct timespec trigger_tstamp;	/* trigger timestamp */
> +	bool trigger_tstamp_latched;     /* trigger timestamp latched in low-level driver/hardware */
> +	bool trigger_tstamp_pending_update; /* trigger timestamp being updated from initial estimate */

I don't see trigger_tstamp_pending_update is used anywhere.  Some code
dropped?

>  	int overrange;
>  	snd_pcm_uframes_t avail_max;
>  	snd_pcm_uframes_t hw_ptr_base;	/* Position at buffer restart */
> diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
> index 7bbc34d..4a97029 100644
> --- a/sound/core/pcm_native.c
> +++ b/sound/core/pcm_native.c
> @@ -810,7 +810,8 @@ static void snd_pcm_trigger_tstamp(struct snd_pcm_substream *substream)
>  	if (runtime->trigger_master == NULL)
>  		return;
>  	if (runtime->trigger_master == substream) {
> -		snd_pcm_gettime(runtime, &runtime->trigger_tstamp);
> +		if (runtime->trigger_tstamp_latched == 0)
> +			snd_pcm_gettime(runtime, &runtime->trigger_tstamp);

A form like "!foo" is preferred for a boolean.

>  	} else {
>  		snd_pcm_trigger_tstamp(runtime->trigger_master);
>  		runtime->trigger_tstamp = runtime->trigger_master->runtime->trigger_tstamp;
> @@ -979,6 +980,7 @@ static int snd_pcm_pre_start(struct snd_pcm_substream *substream, int state)
>  	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
>  	    !snd_pcm_playback_data(substream))
>  		return -EPIPE;
> +	runtime->trigger_tstamp_latched = 0;

Use "false".


thanks,

Takashi

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v4 03/10] ALSA: hda: read trigger_timestamp immediately after starting DMA
  2015-01-30 23:55 ` [PATCH v4 03/10] ALSA: hda: read trigger_timestamp immediately after starting DMA Pierre-Louis Bossart
@ 2015-02-02 10:49   ` Takashi Iwai
  0 siblings, 0 replies; 22+ messages in thread
From: Takashi Iwai @ 2015-02-02 10:49 UTC (permalink / raw)
  To: Pierre-Louis Bossart; +Cc: alsa-devel

At Fri, 30 Jan 2015 17:55:56 -0600,
Pierre-Louis Bossart wrote:
> 
> Make sure wallclock counter and trigger timestamp are read very
> close to each other for better alignment.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  sound/pci/hda/hda_controller.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
> index 0cfc9c8..271f86e 100644
> --- a/sound/pci/hda/hda_controller.c
> +++ b/sound/pci/hda/hda_controller.c
> @@ -657,6 +657,9 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
>  		azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) & ~sbits);
>  	if (start) {
>  		azx_timecounter_init(substream, 0, 0);
> +		snd_pcm_gettime(substream->runtime, &substream->runtime->trigger_tstamp);
> +		substream->runtime->trigger_tstamp_latched = 1;

Better to use "true" for boolean.


Takashi

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v4 04/10] ALSA: usb: update trigger timestamp on first non-zero URB submitted
  2015-01-30 23:55 ` [PATCH v4 04/10] ALSA: usb: update trigger timestamp on first non-zero URB submitted Pierre-Louis Bossart
@ 2015-02-02 10:52   ` Takashi Iwai
  0 siblings, 0 replies; 22+ messages in thread
From: Takashi Iwai @ 2015-02-02 10:52 UTC (permalink / raw)
  To: Pierre-Louis Bossart; +Cc: alsa-devel

At Fri, 30 Jan 2015 17:55:57 -0600,
Pierre-Louis Bossart wrote:
> 
> The first URBs are submitted during the prepare stage. When .trigger is
> called, the ALSA core saves a trigger tstamp that doesn't correspond to
> the actual time when the samples are submitted. The trigger_tstamp is
> now updated when the first data are submitted to avoid any time offsets.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  sound/usb/pcm.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
> index 0d8aba5..7c36fc1 100644
> --- a/sound/usb/pcm.c
> +++ b/sound/usb/pcm.c
> @@ -1464,6 +1464,14 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
>  	subs->last_frame_number = usb_get_current_frame_number(subs->dev);
>  	subs->last_frame_number &= 0xFF; /* keep 8 LSBs */
>  
> +	if (runtime->trigger_tstamp_pending_update == 1) {

Ah I see that trigger_tstamp_pending_update is used here at first.
But then I wonder whether this is specific to USB-audio, if there is
no relevant code in PCM core side?  If so, we don't need to add the
field to snd_pcm_runtime but to snb_usb_usbstream instead.

(BTW, for boolean, avoid use of 0 and 1.)


thanks,

Takashi


> +		/* this is the first actual URB submitted,
> +		 * update trigger timestamp to reflect actual start time
> +		 */
> +		snd_pcm_gettime(runtime, &runtime->trigger_tstamp);
> +		runtime->trigger_tstamp_pending_update = 0;
> +	}
> +
>  	spin_unlock_irqrestore(&subs->lock, flags);
>  	urb->transfer_buffer_length = bytes;
>  	if (period_elapsed)
> @@ -1550,6 +1558,7 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea
>  
>  	switch (cmd) {
>  	case SNDRV_PCM_TRIGGER_START:
> +		substream->runtime->trigger_tstamp_pending_update = 1;
>  	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
>  		subs->data_endpoint->prepare_data_urb = prepare_playback_urb;
>  		subs->data_endpoint->retire_data_urb = retire_playback_urb;
> -- 
> 1.9.1
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v4 00/10] audio timestamping evolutions
  2015-01-30 23:55 [PATCH v4 00/10] audio timestamping evolutions Pierre-Louis Bossart
                   ` (9 preceding siblings ...)
  2015-01-30 23:56 ` [PATCH v4 10/10] ALSA: bump PCM protocol to 2.0.13 Pierre-Louis Bossart
@ 2015-02-02 11:03 ` Takashi Iwai
  2015-02-02 15:52   ` Pierre-Louis Bossart
  10 siblings, 1 reply; 22+ messages in thread
From: Takashi Iwai @ 2015-02-02 11:03 UTC (permalink / raw)
  To: Pierre-Louis Bossart; +Cc: alsa-devel

At Fri, 30 Jan 2015 17:55:53 -0600,
Pierre-Louis Bossart wrote:
> 
> This series of patches was inspired by recent threads on the alsa
> mailing list, as well issues detected with existing and upcoming
> hardware:
> 
> 1. there was a request from the PulseAudio community to get more
> information from drivers to make rewinds safer. While the conclusion
> was that it's nearly impossible for a driver developer to provide this
> information, there are however ways to assess the granularity of the
> hw_ptr updates using timestamping capabilities, and indirectly
> understand how safe rewinds might be.
> 
> 2. There was also a request to add a start_at capability based either
> on system hr timers or a wall clock, which requires a means to expose
> both types of information to applications. Rather than adding new sets
> of timestamps, it is suggested the new start_at functionality relies
> on the new definition provides by these patches
> 
> 3. For new hardware, there is a neeed to let low-level drivers
> handle timestamping instead of having the ALSA core do
> it. Similarly there is a need to let the low-level driver update
> the initial estimate for the trigger timestamp if there are
> delays to start a stream (eg. with USB)
> 
> These patches try to provide an answer to these multiple needs by
> building on the work done two years ago to expose wall clock
> information to applications. The evolution is to let application
> select which audio timestamp they are interested in, track the delay
> and drifts between recurring measurements and get, when possible, an
> idea of the accuracy of the underlying hardware. A backwards compatible mode
> is provided in case userspace doesn't provide any timestamp selection (results
> based on HDAudio wallclock for playback, hw_ptr in all other cases). 
> 
> The first 4 patches are corrections for misses in the way the system
> and trigger timestamps are handled, and the last 6 provide the
> additional audio timestamping selection. A second batch is planned to
> enable hardware capabilities in a low-level drivers.

Thanks for the patches.  They look almost good to me.  There are a few
minor coding-style issues, but the implementation details appear good
enough.

I can merge at least the first four patches as an improvement of the
current code base.  The rest API change needs more reviews.  I'll take
a closer look at them later, but I think the new API design is almost
acceptable as is.


thanks,

Takashi


> 
> A corresponding set of patches is available for alsa-lib.
> 
> V2 changes:
> 
> trigger_tstamp:
> trigger_tstamp_latched, pending redefined as bool
> trigger_tstamp_latched reset in snd_pcm_pre_start()
> 
> audio_ts_config, report:
> keep separate structure but use different bitfields for in and out.
> use u32 instead of __u32, add comments that these structures are internal
> COMPAT backwards compatible mode, uses WALL_CLOCK/LINK for HDAudio
> playback and DEFAULT (hw_ptr) everywhere else
> 
> INFO bits:
> reclaimed 32-bits from hw_params, renamed as info_ext
> moved all timestamp info to info_ext
> 
> snd_pcm_status:
> read only 32-bit audio_tstamp_data, ignore all other fields
> 
> V3/4:
> Addressed feedback from Jaroslav:
> no change to STATUS ioctl, new functionality introduced in STATUS_EXT
> ioctl with r/w params.
> bumped PCM protocol for detection on STATUS_EXT in userspace
> used 32-bit word for accuracy report, no mantissa/exponent packing
> rolled back info_ext changes, all INFO fields remain in same word
> 
> Merged comments from Liam (code simplifications)
> fixed packing
> 
> Added driver_tstamp field in case there is a delay in passing the 
> tstamp and audio_tstamp over IPC.
> 
> 
> 
> Pierre-Louis Bossart (10):
>   ALSA: core: don't override timestamp unconditionally
>   ALSA: core: allow for trigger_tstamp snapshot in .trigger
>   ALSA: hda: read trigger_timestamp immediately after starting DMA
>   ALSA: usb: update trigger timestamp on first non-zero URB submitted
>   ALSA: core: selection of audio_tstamp type and accuracy reports
>   ALSA: core: pass audio tstamp config from userspace
>   ALSA: core: pass audio tstamp config from userspace in compat mode
>   ALSA: core: replace .wall_clock by .get_time_info
>   ALSA: hda: replace .wallclock by .get_time_info
>   ALSA: bump PCM protocol to 2.0.13
> 
>  Documentation/sound/alsa/timestamping.txt | 200 ++++++++++++++++++++++++++++++
>  include/sound/pcm.h                       |  67 +++++++++-
>  include/uapi/sound/asound.h               |  36 +++++-
>  sound/core/pcm_compat.c                   |  36 +++++-
>  sound/core/pcm_lib.c                      |  88 ++++++++-----
>  sound/core/pcm_native.c                   |  58 ++++++++-
>  sound/pci/hda/hda_controller.c            |  43 +++++--
>  sound/usb/pcm.c                           |   9 ++
>  8 files changed, 478 insertions(+), 59 deletions(-)
>  create mode 100644 Documentation/sound/alsa/timestamping.txt
> 
> -- 
> 1.9.1
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v4 00/10] audio timestamping evolutions
  2015-02-02 11:03 ` [PATCH v4 00/10] audio timestamping evolutions Takashi Iwai
@ 2015-02-02 15:52   ` Pierre-Louis Bossart
  2015-02-02 16:06     ` Takashi Iwai
  0 siblings, 1 reply; 22+ messages in thread
From: Pierre-Louis Bossart @ 2015-02-02 15:52 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

Thanks for the review Takashi.

>> The first 4 patches are corrections for misses in the way the system
>> and trigger timestamps are handled, and the last 6 provide the
>> additional audio timestamping selection. A second batch is planned to
>> enable hardware capabilities in a low-level drivers.
>
> Thanks for the patches.  They look almost good to me.  There are a few
> minor coding-style issues, but the implementation details appear good
> enough.

I will resubmit a new patchset for the coding style and true/false 
fixes. ETA end of week.

> I can merge at least the first four patches as an improvement of the
> current code base.  The rest API change needs more reviews.  I'll take
> a closer look at them later, but I think the new API design is almost
> acceptable as is.

You had comments only on patches 2,3 and 4, so I understand that you'd 
merge these four patches after the fixes?
It's fine with me to spend more time on the API changes and deal with 
the patches in separate steps, the first four are really different in 
nature and only internal fixes without impact on userspace.

>
>
> thanks,
>
> Takashi
>
>
>>
>> A corresponding set of patches is available for alsa-lib.
>>
>> V2 changes:
>>
>> trigger_tstamp:
>> trigger_tstamp_latched, pending redefined as bool
>> trigger_tstamp_latched reset in snd_pcm_pre_start()
>>
>> audio_ts_config, report:
>> keep separate structure but use different bitfields for in and out.
>> use u32 instead of __u32, add comments that these structures are internal
>> COMPAT backwards compatible mode, uses WALL_CLOCK/LINK for HDAudio
>> playback and DEFAULT (hw_ptr) everywhere else
>>
>> INFO bits:
>> reclaimed 32-bits from hw_params, renamed as info_ext
>> moved all timestamp info to info_ext
>>
>> snd_pcm_status:
>> read only 32-bit audio_tstamp_data, ignore all other fields
>>
>> V3/4:
>> Addressed feedback from Jaroslav:
>> no change to STATUS ioctl, new functionality introduced in STATUS_EXT
>> ioctl with r/w params.
>> bumped PCM protocol for detection on STATUS_EXT in userspace
>> used 32-bit word for accuracy report, no mantissa/exponent packing
>> rolled back info_ext changes, all INFO fields remain in same word
>>
>> Merged comments from Liam (code simplifications)
>> fixed packing
>>
>> Added driver_tstamp field in case there is a delay in passing the
>> tstamp and audio_tstamp over IPC.
>>
>>
>>
>> Pierre-Louis Bossart (10):
>>    ALSA: core: don't override timestamp unconditionally
>>    ALSA: core: allow for trigger_tstamp snapshot in .trigger
>>    ALSA: hda: read trigger_timestamp immediately after starting DMA
>>    ALSA: usb: update trigger timestamp on first non-zero URB submitted
>>    ALSA: core: selection of audio_tstamp type and accuracy reports
>>    ALSA: core: pass audio tstamp config from userspace
>>    ALSA: core: pass audio tstamp config from userspace in compat mode
>>    ALSA: core: replace .wall_clock by .get_time_info
>>    ALSA: hda: replace .wallclock by .get_time_info
>>    ALSA: bump PCM protocol to 2.0.13
>>
>>   Documentation/sound/alsa/timestamping.txt | 200 ++++++++++++++++++++++++++++++
>>   include/sound/pcm.h                       |  67 +++++++++-
>>   include/uapi/sound/asound.h               |  36 +++++-
>>   sound/core/pcm_compat.c                   |  36 +++++-
>>   sound/core/pcm_lib.c                      |  88 ++++++++-----
>>   sound/core/pcm_native.c                   |  58 ++++++++-
>>   sound/pci/hda/hda_controller.c            |  43 +++++--
>>   sound/usb/pcm.c                           |   9 ++
>>   8 files changed, 478 insertions(+), 59 deletions(-)
>>   create mode 100644 Documentation/sound/alsa/timestamping.txt
>>
>> --
>> 1.9.1
>>
>> _______________________________________________
>> Alsa-devel mailing list
>> Alsa-devel@alsa-project.org
>> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>>
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v4 00/10] audio timestamping evolutions
  2015-02-02 15:52   ` Pierre-Louis Bossart
@ 2015-02-02 16:06     ` Takashi Iwai
  2015-02-02 16:11       ` Pierre-Louis Bossart
  2015-02-02 16:15       ` Jaroslav Kysela
  0 siblings, 2 replies; 22+ messages in thread
From: Takashi Iwai @ 2015-02-02 16:06 UTC (permalink / raw)
  To: Pierre-Louis Bossart; +Cc: alsa-devel

At Mon, 02 Feb 2015 09:52:35 -0600,
Pierre-Louis Bossart wrote:
> 
> Thanks for the review Takashi.
> 
> >> The first 4 patches are corrections for misses in the way the system
> >> and trigger timestamps are handled, and the last 6 provide the
> >> additional audio timestamping selection. A second batch is planned to
> >> enable hardware capabilities in a low-level drivers.
> >
> > Thanks for the patches.  They look almost good to me.  There are a few
> > minor coding-style issues, but the implementation details appear good
> > enough.
> 
> I will resubmit a new patchset for the coding style and true/false 
> fixes. ETA end of week.

Good to hear.  But what about trigger_tstamp_pending_update?  I prefer
avoiding the change in a common header structure unless really needed.

OTOH, if any other drivers need the same flag and it's referred in the
PCM core code *later*, it's fine to add it now.  Just make it clear if
this is the case.

> > I can merge at least the first four patches as an improvement of the
> > current code base.  The rest API change needs more reviews.  I'll take
> > a closer look at them later, but I think the new API design is almost
> > acceptable as is.
> 
> You had comments only on patches 2,3 and 4, so I understand that you'd 
> merge these four patches after the fixes?

Yes.

> It's fine with me to spend more time on the API changes and deal with 
> the patches in separate steps, the first four are really different in 
> nature and only internal fixes without impact on userspace.

Right, that's my intention.

At least, I'd like to have the API changes reviewed by Jaroslav, who
already raised some arguments.


thanks,

Takashi

> 
> >
> >
> > thanks,
> >
> > Takashi
> >
> >
> >>
> >> A corresponding set of patches is available for alsa-lib.
> >>
> >> V2 changes:
> >>
> >> trigger_tstamp:
> >> trigger_tstamp_latched, pending redefined as bool
> >> trigger_tstamp_latched reset in snd_pcm_pre_start()
> >>
> >> audio_ts_config, report:
> >> keep separate structure but use different bitfields for in and out.
> >> use u32 instead of __u32, add comments that these structures are internal
> >> COMPAT backwards compatible mode, uses WALL_CLOCK/LINK for HDAudio
> >> playback and DEFAULT (hw_ptr) everywhere else
> >>
> >> INFO bits:
> >> reclaimed 32-bits from hw_params, renamed as info_ext
> >> moved all timestamp info to info_ext
> >>
> >> snd_pcm_status:
> >> read only 32-bit audio_tstamp_data, ignore all other fields
> >>
> >> V3/4:
> >> Addressed feedback from Jaroslav:
> >> no change to STATUS ioctl, new functionality introduced in STATUS_EXT
> >> ioctl with r/w params.
> >> bumped PCM protocol for detection on STATUS_EXT in userspace
> >> used 32-bit word for accuracy report, no mantissa/exponent packing
> >> rolled back info_ext changes, all INFO fields remain in same word
> >>
> >> Merged comments from Liam (code simplifications)
> >> fixed packing
> >>
> >> Added driver_tstamp field in case there is a delay in passing the
> >> tstamp and audio_tstamp over IPC.
> >>
> >>
> >>
> >> Pierre-Louis Bossart (10):
> >>    ALSA: core: don't override timestamp unconditionally
> >>    ALSA: core: allow for trigger_tstamp snapshot in .trigger
> >>    ALSA: hda: read trigger_timestamp immediately after starting DMA
> >>    ALSA: usb: update trigger timestamp on first non-zero URB submitted
> >>    ALSA: core: selection of audio_tstamp type and accuracy reports
> >>    ALSA: core: pass audio tstamp config from userspace
> >>    ALSA: core: pass audio tstamp config from userspace in compat mode
> >>    ALSA: core: replace .wall_clock by .get_time_info
> >>    ALSA: hda: replace .wallclock by .get_time_info
> >>    ALSA: bump PCM protocol to 2.0.13
> >>
> >>   Documentation/sound/alsa/timestamping.txt | 200 ++++++++++++++++++++++++++++++
> >>   include/sound/pcm.h                       |  67 +++++++++-
> >>   include/uapi/sound/asound.h               |  36 +++++-
> >>   sound/core/pcm_compat.c                   |  36 +++++-
> >>   sound/core/pcm_lib.c                      |  88 ++++++++-----
> >>   sound/core/pcm_native.c                   |  58 ++++++++-
> >>   sound/pci/hda/hda_controller.c            |  43 +++++--
> >>   sound/usb/pcm.c                           |   9 ++
> >>   8 files changed, 478 insertions(+), 59 deletions(-)
> >>   create mode 100644 Documentation/sound/alsa/timestamping.txt
> >>
> >> --
> >> 1.9.1
> >>
> >> _______________________________________________
> >> Alsa-devel mailing list
> >> Alsa-devel@alsa-project.org
> >> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> >>
> > _______________________________________________
> > Alsa-devel mailing list
> > Alsa-devel@alsa-project.org
> > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> >
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v4 00/10] audio timestamping evolutions
  2015-02-02 16:06     ` Takashi Iwai
@ 2015-02-02 16:11       ` Pierre-Louis Bossart
  2015-02-02 16:12         ` Takashi Iwai
  2015-02-02 16:15       ` Jaroslav Kysela
  1 sibling, 1 reply; 22+ messages in thread
From: Pierre-Louis Bossart @ 2015-02-02 16:11 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel


>> I will resubmit a new patchset for the coding style and true/false
>> fixes. ETA end of week.
>
> Good to hear.  But what about trigger_tstamp_pending_update?  I prefer
> avoiding the change in a common header structure unless really needed.
>
> OTOH, if any other drivers need the same flag and it's referred in the
> PCM core code *later*, it's fine to add it now.  Just make it clear if
> this is the case.

Yes, this was added as a generic placeholder but it's really only used 
by USB for now. I can make the change local to usb and deal with the 
more generic part later when other devices need it.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v4 00/10] audio timestamping evolutions
  2015-02-02 16:11       ` Pierre-Louis Bossart
@ 2015-02-02 16:12         ` Takashi Iwai
  0 siblings, 0 replies; 22+ messages in thread
From: Takashi Iwai @ 2015-02-02 16:12 UTC (permalink / raw)
  To: Pierre-Louis Bossart; +Cc: alsa-devel

At Mon, 02 Feb 2015 10:11:21 -0600,
Pierre-Louis Bossart wrote:
> 
> 
> >> I will resubmit a new patchset for the coding style and true/false
> >> fixes. ETA end of week.
> >
> > Good to hear.  But what about trigger_tstamp_pending_update?  I prefer
> > avoiding the change in a common header structure unless really needed.
> >
> > OTOH, if any other drivers need the same flag and it's referred in the
> > PCM core code *later*, it's fine to add it now.  Just make it clear if
> > this is the case.
> 
> Yes, this was added as a generic placeholder but it's really only used 
> by USB for now. I can make the change local to usb and deal with the 
> more generic part later when other devices need it.

Yes, please fold it into the next patch series, too.


thanks,

Takashi

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v4 00/10] audio timestamping evolutions
  2015-02-02 16:06     ` Takashi Iwai
  2015-02-02 16:11       ` Pierre-Louis Bossart
@ 2015-02-02 16:15       ` Jaroslav Kysela
  1 sibling, 0 replies; 22+ messages in thread
From: Jaroslav Kysela @ 2015-02-02 16:15 UTC (permalink / raw)
  To: Takashi Iwai, Pierre-Louis Bossart; +Cc: alsa-devel

Dne 2.2.2015 v 17:06 Takashi Iwai napsal(a):
> 
> At least, I'd like to have the API changes reviewed by Jaroslav, who
> already raised some arguments.

I'll do a review tomorrow. I'm busy with other things today, but from
the first glance, this version seems reasonable in my eyes.

				Thanks,
					Jaroslav

-- 
Jaroslav Kysela <perex@perex.cz>
Linux Kernel Sound Maintainer
ALSA Project; Red Hat, Inc.

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2015-02-02 16:15 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-30 23:55 [PATCH v4 00/10] audio timestamping evolutions Pierre-Louis Bossart
2015-01-30 23:55 ` [PATCH v4 01/10] ALSA: core: don't override timestamp unconditionally Pierre-Louis Bossart
2015-01-30 23:55 ` [PATCH v4 02/10] ALSA: core: allow for trigger_tstamp snapshot in .trigger Pierre-Louis Bossart
2015-02-02 10:48   ` Takashi Iwai
2015-01-30 23:55 ` [PATCH v4 03/10] ALSA: hda: read trigger_timestamp immediately after starting DMA Pierre-Louis Bossart
2015-02-02 10:49   ` Takashi Iwai
2015-01-30 23:55 ` [PATCH v4 04/10] ALSA: usb: update trigger timestamp on first non-zero URB submitted Pierre-Louis Bossart
2015-02-02 10:52   ` Takashi Iwai
2015-01-30 23:55 ` [PATCH v4 05/10] ALSA: core: selection of audio_tstamp type and accuracy reports Pierre-Louis Bossart
2015-01-31  7:37   ` Alexander E. Patrakov
2015-01-31 20:01     ` Pierre-Louis Bossart
2015-01-30 23:55 ` [PATCH v4 06/10] ALSA: core: pass audio tstamp config from userspace Pierre-Louis Bossart
2015-01-30 23:56 ` [PATCH v4 07/10] ALSA: core: pass audio tstamp config from userspace in compat mode Pierre-Louis Bossart
2015-01-30 23:56 ` [PATCH v4 08/10] ALSA: core: replace .wall_clock by .get_time_info Pierre-Louis Bossart
2015-01-30 23:56 ` [PATCH v4 09/10] ALSA: hda: replace .wallclock " Pierre-Louis Bossart
2015-01-30 23:56 ` [PATCH v4 10/10] ALSA: bump PCM protocol to 2.0.13 Pierre-Louis Bossart
2015-02-02 11:03 ` [PATCH v4 00/10] audio timestamping evolutions Takashi Iwai
2015-02-02 15:52   ` Pierre-Louis Bossart
2015-02-02 16:06     ` Takashi Iwai
2015-02-02 16:11       ` Pierre-Louis Bossart
2015-02-02 16:12         ` Takashi Iwai
2015-02-02 16:15       ` Jaroslav Kysela

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.