强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

EasyEffects 音频处理教程 / 09 - PipeWire 深度集成

09 - PipeWire 深度集成

深入了解 PipeWire 音频服务器的配置与管理,掌握 WirePlumber 会话管理、设备管理、延迟优化和音频路由。


9.1 PipeWire 架构回顾

┌──────────────────────────────────────────────────────────┐
│                     应用层                                 │
│  Firefox │ Spotify │ Discord │ Ardour │ EasyEffects      │
├──────────────────────────────────────────────────────────┤
│              兼容层 (Compatibility Layer)                  │
│  PulseAudio 兼容 │ JACK 兼容 │ GStreamer 处理              │
├──────────────────────────────────────────────────────────┤
│              PipeWire Daemon (核心守护进程)                 │
│  ┌────────────────────────────────────────────────────┐  │
│  │  Graph Manager (图管理器)                           │  │
│  │  ┌──────┐  ┌──────┐  ┌──────┐  ┌──────┐          │  │
│  │  │Node A│──│Node B│──│Node C│──│Node D│          │  │
│  │  └──────┘  └──────┘  └──────┘  └──────┘          │  │
│  └────────────────────────────────────────────────────┘  │
├──────────────────────────────────────────────────────────┤
│           WirePlumber (会话管理器 / Session Manager)       │
│   设备发现 │ 策略引擎 │ 路由规则 │ 自动连接                  │
├──────────────────────────────────────────────────────────┤
│              ALSA / 硬件层                                  │
│         声卡 │ USB 音频接口 │ 蓝牙设备 │ HDMI 音频           │
└──────────────────────────────────────────────────────────┘

核心组件

组件 进程名 作用
PipeWire Daemon pipewire 核心音频处理引擎
PulseAudio 兼容 pipewire-pulse 提供 PulseAudio API
WirePlumber wireplumber 会话管理和策略引擎
PipeWire Media Session pipewire-media-session 旧版会话管理器(已弃用)

关键概念

概念 说明
Node 音频处理节点(应用、设备、效果器)
Port 节点上的音频端口(输入/输出)
Link 两个端口之间的连接
Graph 所有节点和连接组成的音频图
Session 当前的音频会话状态
Policy 路由和连接策略

9.2 PipeWire 配置

配置文件位置

路径 说明
/usr/share/pipewire/ 系统默认配置(不要修改)
~/.config/pipewire/ 用户级配置(推荐)
/etc/pipewire/ 系统级覆盖配置

创建用户级配置

# 创建配置目录
mkdir -p ~/.config/pipewire/pipewire.conf.d/

# 复制默认配置作为参考
cp /usr/share/pipewire/pipewire.conf ~/.config/pipewire/

核心配置参数

编辑 ~/.config/pipewire/pipewire.conf.d/custom.conf

context.properties = {
    # 采样率
    default.clock.rate = 48000

    # 允许的采样率(可动态切换)
    default.clock.allowed-rates = [ 44100 48000 96000 ]

    # 缓冲区大小(量子值,影响延迟)
    default.clock.quantum = 256

    # 最小/最大量子值
    default.clock.min-quantum = 32
    default.clock.max-quantum = 2048

    # 优先级(-20 = 最高,19 = 最低)
    # 默认值为合理的,通常不需要修改
    # default.clock.priority = {}

    # 日志级别
    log.level = 2  # 0=无, 1=错误, 2=警告, 3=信息, 4=调试, 5=跟踪
}

参数详解

参数 默认值 说明 建议值
default.clock.rate 48000 默认采样率 48000
default.clock.quantum 1024 缓冲区大小 256 (低延迟) / 1024 (稳定性)
default.clock.min-quantum 32 最小缓冲区 32
default.clock.max-quantum 2048 最大缓冲区 2048
default.clock.allowed-rates 48000 允许的采样率 44100, 48000, 96000

延迟计算

延迟(ms) = quantum / rate × 1000

示例:
  quantum=1024, rate=48000 → 21.3ms
  quantum=512,  rate=48000 → 10.7ms
  quantum=256,  rate=48000 → 5.3ms
  quantum=128,  rate=48000 → 2.7ms
  quantum=64,   rate=48000 → 1.3ms

9.3 WirePlumber 配置

WirePlumber 是 PipeWire 的会话管理器和策略引擎。它负责设备发现、路由决策和自动连接。

WirePlumber 配置位置

路径 说明
/usr/share/wireplumber/ 系统默认配置
~/.config/wireplumber/ 用户级配置

核心配置文件

# 查看默认配置文件列表
ls /usr/share/wireplumber/
# main.lua.conf        - 主配置
# policy.lua.conf      - 策略配置
# wireplumber.conf     - 核心配置
# bluetooth.lua.conf   - 蓝牙配置
# alsa.lua.conf        - ALSA 配置

创建自定义 WirePlumber 配置

mkdir -p ~/.config/wireplumber/wireplumber.conf.d/

设置默认音频设备

编辑 ~/.config/wireplumber/wireplumber.conf.d/50-default-config.lua

-- 设置默认音频输出设备
default_config.rules = {
    {
        matches = {
            {
                { "device.name", "equals", "alsa_card.pci-0000_00_1f.3" },
            },
        },
        apply_properties = {
            ["device.profile"] = "output:analog-stereo+input:analog-stereo",
        },
    },
}

禁用自动路由

编辑 ~/.config/wireplumber/wireplumber.conf.d/60-disable-auto-route.lua

-- 禁用设备连接时的自动路由切换
policy.default.pause_on_disconnect = false

9.4 WirePlumber 命令行工具

wpctl — WirePlumber 控制工具

查看状态

# 查看完整的音频状态
wpctl status

输出示例:

PipeWire 'pipewire-0' [0.123.4, user@host, cookie:5678]

 └─ Clients:
        31. EasyEffects                   [0.123.4 user@host pid:1234]
        32. Firefox                        [0.123.4 user@host pid:5678]
        33. wpctl                          [0.123.4 user@host pid:9012]

 └─ Audio:
 ├─ Devices:
 │      42. Built-in Audio                 [alsa]
 │      43. USB Audio Device               [alsa]
 ├─ Sinks:
 │  *   51. Built-in Audio Analog Stereo   [vol: 0.65]
 │      52. EasyEffects Sink                [vol: 1.00]
 │      53. USB Audio Device               [vol: 0.80]
 ├─ Sources:
 │  *   61. Built-in Audio Analog Stereo   [vol: 0.50]
 │      62. EasyEffects Source              [vol: 1.00]
 │      63. USB Audio Device               [vol: 0.70]
 └─ Streams:
         71. Firefox                        [output]
         72. Discord                        [input+output]

关键信息:

  • * 标记默认设备
  • [vol: 0.65] 显示音量设置
  • EasyEffects Sink/Source 是 EasyEffects 注册的虚拟设备

设置默认设备

# 设置默认输出设备(sink)
wpctl set-default 51

# 设置默认输入设备(source)
wpctl set-default 61

调整音量

# 设置音量(0.0 - 1.0)
wpctl set-volume 51 0.8

# 增加音量 5%
wpctl set-volume 51 5%+

# 减少音量 5%
wpctl set-volume 51 5%-

# 静音/取消静音
wpctl set-mute 51 toggle

连接/断开端口

# 查看端口
wpctl inspect 51

# 手动连接端口
pw-link <输出端口> <输入端口>

# 列出所有连接
pw-link -l

9.5 设备管理

查看设备信息

# 列出所有音频设备
wpctl status | grep -A 20 "Devices"

# 查看特定设备详情
wpctl inspect 42

# 使用 pw-dump 获取 JSON 格式信息
pw-dump | jq '.[] | select(.info.props."media.class" == "Audio/Device") | .info.props'

ALSA 设备配置

编辑 ALSA 设备配置

mkdir -p ~/.config/wireplumber/wireplumber.conf.d/

# 编辑 ALSA 设备配置
cat > ~/.config/wireplumber/wireplumber.conf.d/51-alsa-config.lua << 'EOF'
alsa_monitor.rules = {
    {
        matches = {
            {
                { "device.name", "matches", "alsa_card.*" },
            },
        },
        apply_properties = {
            -- 使用更好的 ALSA 驱动参数
            ["api.alsa.period-size"]   = 256,
            ["api.alsa.period-num"]    = 2,
            ["api.alsa.headroom"]      = 1024,
            ["api.alsa.disable-batch"] = true,
        },
    },
}
EOF

ALSA 参数详解

参数 默认值 说明
api.alsa.period-size 1024 ALSA 周期大小(帧)
api.alsa.period-num 2 周期数量
api.alsa.headroom 0 预留缓冲区
api.alsa.disable-batch false 禁用批量传输

USB 音频设备配置

cat > ~/.config/wireplumber/wireplumber.conf.d/52-usb-audio.lua << 'EOF'
alsa_monitor.rules = {
    {
        matches = {
            {
                { "device.name", "matches", "alsa_card.usb-*" },
            },
        },
        apply_properties = {
            -- USB 音频设备通常支持更小的缓冲区
            ["api.alsa.period-size"]   = 128,
            ["api.alsa.period-num"]    = 2,
            ["api.alsa.headroom"]      = 512,
            ["api.alsa.disable-batch"] = true,
            -- 优先使用 USB 设备
            ["device.profile"] = "output:analog-stereo+input:analog-stereo",
        },
    },
}
EOF

9.6 蓝牙设备管理

蓝牙音频编解码器

编解码器 质量 延迟 兼容性
SBC 所有设备
AAC iOS/部分 Android
aptX 高通芯片设备
aptX HD 很高 高通芯片设备
aptX Low Latency 极低 专用设备
LDAC 很高 Sony 设备
LHDC 很高 华为/小米设备

蓝牙配置

cat > ~/.config/wireplumber/wireplumber.conf.d/53-bluetooth.lua << 'EOF'
bluez_monitor.properties = {
    -- 启用的编解码器(按优先级排列)
    ["bluez5.codecs"] = "[ ldac sbc_xq aac aptx_hd aptx ]",

    -- 启用 HFP(免提配置)
    ["bluez5.enable-hfp"] = true,

    -- 启用 A2DP(高级音频分发)
    ["bluez5.enable-a2dp"] = true,
}

bluez_monitor.rules = {
    {
        matches = {
            {
                { "device.name", "matches", "bluez_card.*" },
            },
        },
        apply_properties = {
            -- 优先使用 A2DP
            ["bluez5.profile"] = "a2dp-sink",
        },
    },
}
EOF

蓝牙设备配对与连接

# 使用 bluetoothctl 管理蓝牙设备
bluetoothctl

# 在 bluetoothctl 中:
scan on                    # 扫描设备
pair XX:XX:XX:XX:XX:XX     # 配对
connect XX:XX:XX:XX:XX:XX  # 连接
trust XX:XX:XX:XX:XX:XX    # 信任设备

9.7 延迟优化

延迟的来源

总延迟 = 输入延迟 + 处理延迟 + 输出延迟

输入延迟:
  硬件采样 + ALSA 缓冲 + PipeWire 缓冲

处理延迟:
  EasyEffects 效果链处理

输出延迟:
  PipeWire 缓冲 + ALSA 缓冲 + 硬件输出

延迟测量

# 使用 pw-metadata 查看当前延迟
pw-metadata -n settings

# 输出示例:
# clock.rate        = 48000
# clock.quantum     = 256
# clock.min-quantum = 32

# 使用 jack_delay 测量往返延迟
# 安装 jack2-tools
sudo dnf install jack2-tools  # Fedora
sudo apt install jackd2        # Ubuntu

# 连接回环并测量
jack_iodelay

延迟优化策略

策略一:降低 PipeWire Quantum

# 运行时动态调整
pw-metadata -n settings 0 clock.quantum 128

# 永久配置
cat > ~/.config/pipewire/pipewire.conf.d/low-latency.conf << 'EOF'
context.properties = {
    default.clock.quantum = 128
    default.clock.min-quantum = 32
}
EOF

# 重启 PipeWire
systemctl --user restart pipewire pipewire-pulse wireplumber

策略二:优化 ALSA 参数

cat > ~/.config/wireplumber/wireplumber.conf.d/51-alsa-config.lua << 'EOF'
alsa_monitor.rules = {
    {
        matches = {
            {
                { "device.name", "matches", "alsa_card.*" },
            },
        },
        apply_properties = {
            ["api.alsa.period-size"] = 128,
            ["api.alsa.period-num"]  = 2,
            ["api.alsa.headroom"]    = 256,
        },
    },
}
EOF

策略三:使用 RT 调度

# 确认当前用户在 audio 组中
groups $USER

# 如果不在 audio 组中,添加
sudo usermod -a -G audio $USER

# 编辑 limits.conf
sudo tee -a /etc/security/limits.d/audio.conf << 'EOF'
@audio   -  rtprio     95
@audio   -  memlock    unlimited
EOF

# 重新登录使配置生效

延迟优化总结

优化级别 Quantum 延迟 CPU 占用 稳定性
默认 1024 21.3ms
中等 512 10.7ms
低延迟 256 5.3ms
超低延迟 128 2.7ms
极限 64 1.3ms 很高
不稳定 32 0.7ms 极高 很低

9.8 音频路由

pw-link 用于手动管理 PipeWire 中的音频连接。

列出所有端口

# 列出所有输出端口
pw-link -l | grep output

# 列出所有输入端口
pw-link -l | grep input

查看当前连接

pw-link -l

输出示例:

output:
  Firefox:output_FL
  Firefox:output_FR
  EasyEffects Sink:playback_FL
  EasyEffects Sink:playback_FR
  Built-in Audio Analog Stereo:playback_FL
  Built-in Audio Analog Stereo:playback_FR

input:
  EasyEffects:input_FL
  EasyEffects:input_FR
  EasyEffects Sink:monitor_FL
  EasyEffects Sink:monitor_FR
  Discord:input_FL
  Discord:input_FR

connections:
  Firefox:output_FL ──▶ EasyEffects Sink:playback_FL
  Firefox:output_FR ──▶ EasyEffects Sink:playback_FR
  EasyEffects Sink:monitor_FL ──▶ Built-in Audio:playback_FL
  EasyEffects Sink:monitor_FR ──▶ Built-in Audio:playback_FR

手动连接端口

# 连接 Firefox 左声道到 Discord 左声道
pw-link Firefox:output_FL Discord:input_FL

# 连接右声道
pw-link Firefox:output_FR Discord:input_FR

断开连接

pw-link -d Firefox:output_FL Discord:input_FL

音频路由拓扑

┌─────────────┐    ┌──────────────────┐    ┌─────────────────┐
│   Firefox    │    │   EasyEffects    │    │  Built-in Audio │
│              │    │                  │    │                 │
│ output_FL ──┼───▶│ Sink:playback_FL │───▶│ playback_FL     │
│ output_FR ──┼───▶│ Sink:playback_FR │───▶│ playback_FR     │
└─────────────┘    └──────────────────┘    └─────────────────┘
                   ┌──────────────┐
                   │  效果链处理    │
                   │  EQ → Comp   │
                   └──────────────┘

9.9 PipeWire 调试

查看 PipeWire 状态

# 查看 PipeWire 守护进程状态
systemctl --user status pipewire pipewire-pulse wireplumber

# 查看 PipeWire 日志
journalctl --user -u pipewire -f

# 查看详细日志(设置日志级别)
pw-metadata -n settings 0 log.level 4
journalctl --user -u pipewire -f --no-pager

监控工具

pw-top — 实时监控

pw-top

输出示例:

S  ID  QUANT   RATE    NAME
R  32  256/256 48000   EasyEffects
R  33  256/256 48000   Firefox
R  34  256/256 48000   Built-in Audio

列说明:

说明
S 状态(R=运行, S=空闲, E=错误)
ID 节点 ID
QUANT 缓冲区使用/总大小
RATE 采样率
NAME 节点名称

pw-dump — 完整状态导出

# 导出完整 PipeWire 状态
pw-dump > pipewire-state.json

# 使用 jq 查询特定信息
pw-dump | jq '.[] | select(.info.props."application.name" == "EasyEffects")'

pw-cli — 交互式管理

# 进入交互式模式
pw-cli

# 常用命令:
ls Node           # 列出所有节点
ls Link           # 列出所有连接
info <id>         # 查看节点详情
connect <id1> <id2>  # 连接节点
disconnect <id>   # 断开连接
quit              # 退出

常见问题排查

问题 诊断命令 可能原因 解决方案
无声音 wpctl status 默认设备未设置 wpctl set-default <id>
爆音/卡顿 pw-top xrun(缓冲区溢出) 增大 quantum 值
延迟过大 pw-metadata -n settings quantum 太大 减小 quantum 值
设备未识别 pw-dump | grep device 驱动/固件问题 检查 ALSA 设备
连接丢失 pw-link -l 路由策略冲突 检查 WirePlumber 配置
蓝牙无声 wpctl status 编解码器不支持 检查蓝牙编解码器

9.10 PipeWire JACK 兼容模式

对于需要 JACK 的专业音频应用,PipeWire 提供了兼容层。

启用 JACK 兼容

# 安装 PipeWire JACK 兼容库
# Fedora
sudo dnf install pipewire-jack-audio-connection-kit

# Ubuntu
sudo apt install pipewire-jack

# Arch
sudo pacman -S pipewire-jack

# 验证
pw-jack jack_lsp

使用 JACK 应用

# 通过 pw-jack 运行 JACK 应用
pw-jack ardour
pw-jack hydrogen
pw-jack guitarix
pw-jack Carla

JACK 延迟配置

# 设置 JACK 模式的 quantum
pw-metadata -n settings 0 clock.quantum 128

# 在 JACK 应用中设置缓冲区大小
pw-jack jack_control eps realtime true
pw-jack jack_control ds alsa
pw-jack jack_control dps period 128

9.11 要点回顾

  • PipeWire 由 daemon、pipewire-pulse 和 WirePlumber 三个核心组件组成
  • WirePlumber 负责设备发现、路由策略和自动连接
  • Quantum 值决定延迟:quantum=256 对应 5.3ms,quantum=128 对应 2.7ms
  • wpctl 是管理 PipeWire 设备和音量的主要命令行工具
  • pw-link 用于手动管理音频路由
  • pw-top 用于实时监控 PipeWire 状态
  • PipeWire 提供 JACK 兼容层,无需安装独立 JACK

9.12 注意事项

不要修改系统默认配置: 系统级配置文件位于 /usr/share/pipewire/,应该在 ~/.config/pipewire/ 中创建用户级覆盖。

WirePlumber 优于 pipewire-media-session: WirePlumber 是官方推荐的会话管理器。如果系统仍在使用 pipewire-media-session,建议迁移到 WirePlumber。

低延迟风险: Quantum 值过低会导致 xrun(缓冲区溢出),表现为爆音或音频卡顿。如果遇到问题,增大 quantum 值。

蓝牙延迟: 蓝牙设备本身有 100-200ms 的延迟,PipeWire 的低延迟优化对蓝牙设备效果有限。

JACK 兼容: 大分 JACK 应用可以无缝运行在 PipeWire JACK 兼容模式下,但某些对延迟极度敏感的应用可能仍需要原生 JACK。


9.13 扩展阅读