HOOOS

Looking Glass 虚拟机音频延迟与杂音?用 PipeWire + Scream 共享内存直通彻底解决

0 14 VFIO折腾家 PipeWireScream音频直通
Apple

折腾 KVM 虚拟机 GPU 直通的用户,在享受 Looking Glass 带来的超低延迟画面的同时,大概率都会被它的音频同步问题折磨过。

如果使用 QEMU 默认的 ICH9 或 AC97 模拟声卡,或者走 Spice 协议传输音频,在游戏或高负载场景下,极易出现爆音、杂音、甚至是声音逐渐比画面慢几秒的严重滞后。

要实现音画同步的极致体验,目前最完美的方案是利用 Scream 配合 IVSHMEM(虚拟机间共享内存),将音频数据直接写入内存,并在宿主机通过 PipeWire 进行极低延迟的解码和播放。这套方案不经过虚拟网络栈,延迟几乎为零,且不额外消耗 CPU。

下面是完整的配置实操指南。


准备工作

在开始之前,请确保:

  • 宿主机已安装并正常运行 PipeWire(以及 pipewire-pulse 兼容层)。
  • 虚拟机(Windows)已经配置好 Looking Glass 并且能正常显示画面。

第一步:在宿主机创建共享内存文件

Scream 需要一块共享内存来向宿主机传递音频数据。我们需要在 /dev/shm 下创建一个名为 scream-ivshmem 的临时文件,并赋予当前用户读写权限。

为了保证宿主机每次开机自动创建该文件,建议使用 systemd-tmpfiles

在宿主机上新建或编辑配置文件:

sudo nano /etc/tmpfiles.d/scream-ivshmem.conf

写入以下内容(注意:请将 your_username 替换为你宿主机的实际登录用户名):

# Type Path                     Mode User          Group        Age Argument
f /dev/shm/scream-ivshmem     0660 your_username kvm          -

保存退出后,立即执行以下命令使配置生效并创建文件:

sudo systemd-tmpfiles --create /etc/tmpfiles.d/scream-ivshmem.conf

第二步:在虚拟机 XML 中添加共享内存设备

我们需要把刚才创建的这块内存挂载到虚拟机里。

使用 virsh edit 你的虚拟机名字 或者通过 Virt-Manager 的 XML 编辑器,在 <devices> 标签内添加以下内容:

<shmem name='scream-ivshmem'>
  <model type='ivshmem-plain'/>
  <size unit='M'>2</size>
</shmem>

避坑提示:Scream 只需要 2MB 的共享内存(2M 就足够容纳音频缓冲区)。如果你之前为了 Looking Glass 已经配置了一个共享内存设备(比如 looking-glass),千万不要混用。Scream 必须使用自己独立的 shmem 设备。

保存并启动虚拟机。


第三步:虚拟机(Windows)安装 Scream 驱动

  1. 启动 Windows 虚拟机,打开设备管理器
  2. 你会看到一个带有黄色感叹号的未知 PCI 设备(或者是叫 PCI 标准 RAM 控制器)。这个就是我们刚才添加的 IVSHMEM 设备。
  3. 去 GitHub 下载 Scream 的最新发布版本。注意要下载支持 IVSHMEM 的版本:
    • 访问 Scream GitHub Releases
    • 下载 Scream-DXE-xxxxx.zip(或者寻找专门标注有 ivshmem 驱动的包,解压后会有 Driver\Scream 目录)。
  4. 在设备管理器中,右键点击那个 PCI 设备 -> 更新驱动程序 -> 浏览我的电脑以查找驱动程序
  5. 定位到你解压的 Scream/driver 文件夹,安装该驱动。
  6. 安装成功后,Windows 的声音输出设备中会出现一个名为 Scream (virtual) 的设备。将其设置为默认播放设备

第四步:宿主机配置 PipeWire 接收端

宿主机需要运行一个接收端程序,从 /dev/shm/scream-ivshmem 中读取数据并输入给 PipeWire。

1. 安装编译接收端

在 Arch Linux 上,可以直接通过 AUR 安装:

paru -S scream-git

在 Ubuntu/Debian 上,可以编译安装:

sudo apt install build-essential cmake libpulse-dev
git clone https://github.com/duncanthrax/scream.git
cd scream/Receivers/unix
mkdir build && cd build
cmake ..
make

2. 编写 Systemd 用户服务自启

为了让接收端在用户登录时自动后台运行,我们可以编写一个 Systemd 用户服务。

创建目录(如果不存在):

mkdir -p ~/.config/systemd/user/

创建服务文件:

nano ~/.config/systemd/user/scream.service

写入以下配置:

[Unit]
Description=Scream IVSHMEM Receiver
After=pipewire.service

[Service]
Type=simple
# 强制指定 PulseAudio/PipeWire 延迟环境变量,避免音频断续
Environment=PIPEWIRE_LATENCY="128/48000"
ExecStart=/usr/bin/scream -m /dev/shm/scream-ivshmem
Restart=always
RestartSec=5

[Install]
WantedBy=default.target

注意:如果你是自行编译的 scream 接收端,请将 ExecStart 中的路径替换为你编译出来的二进制文件实际路径(例如 /usr/local/bin/scream)。

保存并退出,然后启用该服务:

systemctl --user daemon-reload
systemctl --user enable --now scream.service

此时,运行 systemctl --user status scream 应该能看到服务处于活动(running)状态。


第五步:消除杂音与不同步的“终极调优”

如果你在完成上述步骤后听到沙沙的杂音、爆音,或者游戏运行一段时间后声音变慢,通常是由于采样率不匹配系统时钟漂移导致的。请按以下步骤调优:

1. 统一采样率(最重要)

Windows 端 Scream 驱动默认输出通常是 48000 Hz(DVD 画质)。
在 Windows 的“声音控制面板”中,双击 Scream 播放设备,切换到“高级”选项卡,确保默认格式设置为 24位/16位,48000 Hz

同时,确保你的 PipeWire 默认工作在 48000 Hz。编辑或创建 /etc/pipewire/pipewire.conf(或用户目录下的 ~/.config/pipewire/pipewire.conf),确保或添加以下配置:

default.clock.rate = 48000
default.clock.allowed-rates = [ 44100 48000 ]

修改后重启 PipeWire:systemctl --user restart pipewire

2. 优化 QEMU 时钟配置

时钟漂移是导致“声音越来越慢”的罪魁祸首。在虚拟机的 XML 配置文件中,找到 <clock> 部分,确保包含以下针对 Windows 优化的计时器:

<clock offset='localtime'>
  <timer name='rtc' tickpolicy='catchup'/>
  <timer name='pit' tickpolicy='delay'/>
  <timer name='hpet' present='no'/>
  <timer name='hypervclock' present='yes'/>
</clock>

hypervclock 能够极大改善 Windows 客户机的计时精度,配合 rtccatchup 策略,可以基本消灭由于虚拟机时钟慢于宿主机导致的音频渐进式延迟。

3. 微调 PipeWire 缓冲区大小

如果你的 CPU 负载极高时偶尔出现“咔哒”一声的爆音,可以适当增大服务文件中的 PIPEWIRE_LATENCY 缓冲区。
编辑 ~/.config/systemd/user/scream.service
PIPEWIRE_LATENCY="128/48000" 改为 PIPEWIRE_LATENCY="256/48000"
数值越大,抗波动能力越强,但延迟会微幅上升(256 采样在 48k 下仅为 5.3 毫秒,肉眼完全无法察觉)。

修改后执行:

systemctl --user daemon-reload
systemctl --user restart scream

享受你那音画完美同步、毫无延迟且纯净无杂音的 Looking Glass 游戏虚拟机吧!

点评评价

captcha
健康