Change of delay computation by ALSA firewire stack at v6.3 kernel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

Linux kernel v6.3 is out a few days ago, which includes a change to ALSA
firewire stack that addresses an issue affecting user space applications.
Specifically, the change introduces delay compensation with the current
isochronous cycle in IEEE 1394 bus.

In UAPI of sound subsystem, `struct snd_pcm_status` is used to report
status of runtime for PCM substream. User space application read the
`delay` field of structure to obtain the number of PCM frames[1], which is
comprised of two parts; one common to all drivers, and one specific to
individual drivers.

The common part of the delay value reflects the gap between the pointer at
which the application reads/writes PCM frames (applptr) and the pointer at
which the driver receives/transmits the latest audio data frames (hwptr).
The driver can increase this value arbitrarily based on the transmission
method used.

In the current implementation of drivers in ALSA firewire stack, initial
isochronous packets are scheduled to deliver audio data frames equivalent
to the size of PCM buffer configured by user space application as part of
the hardware parameters. In the case of PipeWire, 4,096 frames is used as
a default value at a sample rate of 48.0 kHz for the size of PCM
buffer[2], resulting in 684 initial packets[3] equivalent to 4,104
frames[4].

1394 OHCI hardware enables software to read the current isochronous cycle
with a resolution of 8,000 times per second[5]. The change to ALSA firewire
stack involves using the specific part of delay to report the gap between
the current isochronous cycle and the isochronous cycle at which hwptr is
located[6]. Prior to the change, the gap was not visible to user space
applications, leading to unexpected delay[7].

For capture PCM substream, the gap is zero or a few packets, as 1394 OHCI
hardware enables software to read the payload of isochronous packets
immediately upon their arrival. The delay mostly comes from the common
part, thus it is 4,096 or so as maximum in the case of PipeWire.

For playback PCM substream, the maximum gap is equivalent to 684 initial
packets, resulting in the delay ranging from 4,104 frames to 8,200 frames
(= 4,096 + 4,104) in the case of PipeWire.

Regardless of the driver and its transmission backend, I note that there
is a limiting point beyond which the value of delay field cannot express
true delay between the timing at which the application reads/writes PCM
frames and the timing at which the hardware actually generates audio and
samples audio signal, since the driver is only responsible for transmitting
the audio data frame in the context[8], and cannot account for the
circuit-level details on the board. While a driver that accounts for such
details could result in more accurate delay measurements, such an
implementation would be technically difficult, particularly for devices
with thick implementations between transmission of audio data frames and
audio signal processing (i.e. devices for packet-oriented communication).


[1] include/sound/pcm.h
https://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git/tree/include/sound/pcm.h?h=v6.3#n347
[2] at least pipewire version 0.3.58
[3] 684 = 8,000 * 4,096 / 48,000. You can see the computation at:
https://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git/tree/sound/firewire/amdtp-stream.c?h=v6.3#n2092
[4] 4,104 = 48,000 * 684 / 8000. In IEC 61883-1/6, packet includes
multiple audio data frames.
[5] The drivers can retrieve the cycle since v5.19 or later, by a commit
baa914cd81f5 ("firewire: add kernel API to access CYCLE_TIME register")
https://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git/commit/?id=baa914cd81f5
[6] It was finally done by a commit af13842cad44 ("ALSA: firewire-lib:
compute extra delay for runtime of PCM substream")
https://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git/commit/?id=baa914cd81f5
[7] [pipewire-jack] Systematic delay in recording using REAPER of 0.07 to
0.08 seconds
https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/2790
[8] In the most cases, the transmission itself is executed out of sound subsystem.


Thanks

Takashi Sakamoto



[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Pulse Audio]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux