fangorn/sunshine-qemu
public
ref:0df5aa9286596b92aaa95f53615d1e4902a2cccf
fix(linux): hand the guest's audio to the encoder at the rate it plays
A guest writes its audio in the quantum its own stack uses, usually 10 ms or more, so frames reached the
encoder in bursts: two at once, then a 10 ms gap. The samples are right, so a recording of the stream measures
clean -- 0.01% THD, one discontinuity in three minutes -- while a client crackles the whole time, because its
jitter buffer is fed unevenly. Only measuring when each packet arrived showed it: half of them followed the one
before within a millisecond.
The capture now waits out the rest of each frame's turn before returning it, as a sound card paces a real
capture. Frames go out one per frame interval: 3 of 26289 arrived in bursts instead of 3196 of 6395, with the
p95 gap down from 10.19 ms to 5.33 ms and the samples unchanged. It stops waiting when more than a couple of
frames are queued, so a guest whose clock runs fast drains instead of building up delay.
The e2e client reports the arrival gaps and puts them in its summary, and the audio end-to-end test fails when
more than a quarter of the packets arrive in bursts.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BPNw4PCgkEfhyCjQT19wsb
SHA:
0df5aa9286596b92aaa95f53615d1e4902a2cccf
Author:
Cole Christensen <cole.christensen@gmail.com>
Date:
2026-09-17 21:56
Parents:
03ad9a4
7 files changed
+129
-7
| Type | ||
|---|---|---|
|
|
docs/qemu.md | +7 −0 |
|
||
|
|
src/platform/linux/qemu/audio.cpp | +40 −3 |
|
||
|
|
tests/e2e/moonlight_client/main.cpp | +72 −1 |
|
||
|
|
tests/e2e/qemu/desktop/run_desktop.sh | +1 −1 |
|
||
|
|
tests/e2e/qemu/e2e_stream.sh | +7 −0 |
|
||
|
|
tests/e2e/qemu/run_vm.sh | +1 −1 |
|
||
|
|
tests/e2e/qemu/steamos/run_steamos.sh | +1 −1 |
|
||