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

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 扩展阅读