An extremely low latency KVMFR (KVM FrameRelay) implementation for guests with VGA PCI Passthrough.
Go to file
Chris Spencer dd2d84a080 [client] audio: adjust playback speed to match audio device clock
This change is based on the techniques described in [1] and [2].

The input audio stream from Spice is not synchronised to the audio playback
device. While the input and output may be both nominally running at 48 kHz,
when compared against each other, they will differ by a tiny fraction of a
percent. Given enough time (typically on the order of a few hours), this
will result in the ring buffer becoming completely full or completely
empty. It will stay in this state permanently, periodically resulting in
glitches as the buffer repeatedly underruns or overruns.

To address this, adjust the speed of the received data to match the rate at
which it is being consumed by the audio device. This will result in a
slight pitch shift, but the changes should be small and smooth enough that
this is unnoticeable to the user.

The process works roughly as follows:
1. Every time audio data is received from Spice, or consumed by the audio
   device, sample the current time. These are fed into a pair of delay
   locked loops to produce smoothed approximations of the two clocks.
2. Compute the difference between the two clocks and compare this against
   the target latency to produce an error value. This error value will be
   quite stable during normal operation, but can change quite rapidly due
   to external factors, particularly at the start of playback. To smooth
   out any sudden changes in playback speed, which would be noticeable to
   the user, this value is also filtered through another delay locked loop.
3. Feed this error value into a PI controller to produce a ratio value.
   This is the target playback speed in order to bring the error value
   towards zero.
4. Resample the input audio using the computed ratio to apply the speed
   change. The output of the resampler is what is ultimately inserted into
   the ring buffer for consumption by the audio device.

Since this process targets a specific latency value, rather than simply
trying to rate match the input and output, it also has the effect of
'correcting' latency issues. If a high latency application (such as a media
player) is already running, the time between requesting the start of
playback and the audio device actually starting to consume samples can be
very high, easily in the hundreds of milliseconds. The changes here will
automatically adjust the playback speed over the course of a few minutes to
bring the latency back down to the target value.

[1] https://kokkinizita.linuxaudio.org/papers/adapt-resamp.pdf
[2] https://kokkinizita.linuxaudio.org/papers/usingdll.pdf
2022-01-27 18:03:11 +11:00
.github [all] ci: libdecor-dev is now libdecor-0-dev 2022-01-04 10:48:13 +11:00
client [client] audio: adjust playback speed to match audio device clock 2022-01-27 18:03:11 +11:00
cmake [all] cmake: fail if wrong submodule version is checked out 2021-12-02 22:08:03 +11:00
common [common] ringbuffer: add unbounded mode 2022-01-27 18:03:11 +11:00
contrib/redhat [meta] Add SELinux policy 2017-12-14 22:22:44 +11:00
doc [doc] build: Add source comment for listing deps 2022-01-20 17:49:35 +11:00
host [host] linux: allow getting system version 2022-01-27 05:47:53 +11:00
module [module] fix compile on 5.16 2022-01-14 12:14:21 +11:00
obs [obs] allow for the larger KVMFR header size now 2022-01-05 21:57:49 +11:00
profile [all] refresh copyright dates 2022-01-05 19:42:46 +11:00
repos [client] spice: update the submodule to fix invalid header errors 2022-01-22 18:23:33 +11:00
resources [res] added LG logo vector graphics 2021-02-21 10:31:48 +11:00
vendor [vendor] directx: add d3d12sdklayers.h 2022-01-17 15:12:54 +11:00
.gitattributes [git] added vcxproj files to crlf exceptions 2017-10-31 20:19:52 +11:00
.gitignore [all] gitignore: ignore __pycache__ and *.py[co] 2021-12-26 09:46:31 +11:00
.gitmodules [repos] added cimgui @ version 1.82 2021-07-17 21:09:51 +10:00
AUTHORS [client] audio/pw: don't discard playback data 2022-01-11 09:45:30 +11:00
CONTRIBUTORS Fixed typo in word wish 2018-05-31 13:28:36 +10:00
gl-check [client] add gl-check script to check GL function calls 2021-10-01 10:12:40 +10:00
LICENSE added licensing to sources 2017-10-31 19:07:16 +11:00
README.md [docs] all: Switch to sphinx-readthedocs-theme 2021-12-26 12:46:23 +11:00
refresh-copyright [host] dxgi: add d3d12.h from latest MinGW 2022-01-10 14:45:51 +11:00
version.cmake [version.cmake] Add reminder to synchronize git-describe with docs/lgrelease.py 2021-12-28 19:18:42 +11:00

Looking Glass

An extremely low latency KVMFR (KVM FrameRelay) implementation for guests with VGA PCI Passthrough.

Documentation

IMPORTANT

This project contains submodules that must be checked out if building from the git repository! If you are not a developer and just want to compile Looking Glass, please download the source archive from the website instead:

https://looking-glass.io/downloads

Source code for the documentation can be found in the /doc directory.

You may view this locally as HTML by running make html with python3-sphinx and python3-sphinx-rtd-theme installed.