news 2026/11/2 6:36:28

Audio学习7(PipeWire/PulseAudio)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Audio学习7(PipeWire/PulseAudio)

1 概念

PipeWire 是一个由 Red Hat 主导、目前已成为 Linux 桌面音频/视频服务基座的现代多媒体框架,它在同一套体系内统一处理音频采集与播放、视频/摄像头流以及跨应用的实时信号路由,核心特点是以有向图(graph)方式组织节点和链路,让多个应用可以同时读写同一设备、自由组合输入输出,并天然支持低延迟的 Pro-Audio 实时调度(对比旧方案:它同时取代了 PulseAudio 的"通用混音"与 JACK 的"专业低延迟",且默认与 PulseAudio 和 JACK 兼容,可平滑接管二者的协议与客户端)。相比前辈,PipeWire 的优势在于:图式动态重连、强安全隔离(会话与设备权限由系统策略控制)、低延迟高精度时钟、以及对 Flatpak/Snap 等容器化应用的透明支持。它由 systemd 用户服务管理,现已是 Fedora、Debian、Ubuntu 等主流发行版桌面环境的默认音频服务(常配合 WirePlumber 作为会话管理器)。在具体应用上,若是嵌入式/音频开发者,PipeWire 常用作音视频中继、虚拟设备(如 virtual sink/source)以及连接蓝牙、USB、HDMI 等多路音频的统一枢纽。

核心功能就是:多路音视频流在 CPU 上的统一零拷贝混音/复用、图状路由与低延迟定时调度”。

如下:

可以看到,PipeWire往下其实不止ALSA,还有蓝牙,V4L2等。

具体拆解就是:

  1. 统一混音与复用(Mixing & Compositing):

    • 音频:把多个播放软件(浏览器、播放器、游戏)产生的不同采样率、不同通道数的 PCM 音频流,在 CPU 上统一重采样、格式转换并混音成一路。

    • 视频:把多个应用(如屏幕共享、摄像头捕捉、OBS)的视频 Frame 统一管理和分发(基于 DMA-BUF 零拷贝传输)。

  2. 图状路由(Graph Routing):

    • 在系统内部构建一个动态节点图(Graph)。你可以像接音频电缆一样,任意把应用 A 的音频输出拉线路由给应用 B(比如做录音/效果器处理),再路由给硬件扬声器;或者把某个窗口的视频流路由给会议软件。

  3. 硬件调度输出(Scheduling & Sync):

    • 作为用户态应用与 ALSA(音频驱动)/ V4L2(视频驱动)之间的中介,以极低的延迟(甚至达到毫秒级的专业 RT 实时调度)把混好或路由好的数据包送入硬件缓冲区,并严格保证音画同步(A/V Sync)。

2 安装

环境是之前的树莓派5+WM8960。(Audio学习4(WM8960的bringup)-CSDN博客)

来自:GitHub - mikeroyal/PipeWire-Guide: PipeWire Guide. Learn about how PipeWire gives your Linux system a Professional Audio/Video Processing workflow. · GitHub

Run these three commands as your regular user (not as root):

Check for new service files with:

systemctl --user daemon-reload

Disable and stop the PulseAudio service with:

systemctl --user --now disable pulseaudio.service pulseaudio.socket

Enable and start the new pipewire-pulse service with:

systemctl --user --now enable pipewire pipewire-pulse

下面是运行结果:

tom@raspberrypi:~ $ systemctl --user daemon-reload tom@raspberrypi:~ $ systemctl --user enable --now pipewire.socket pipewire-pulse.socket Created symlink '/home/tom/.config/systemd/user/sockets.target.wants/pipewire.socket' → '/usr/lib/systemd/user/pipewire.socket'. Created symlink '/home/tom/.config/systemd/user/sockets.target.wants/pipewire-pulse.socket' → '/usr/lib/systemd/user/pipewire-pulse.socket'. tom@raspberrypi:~ $ systemctl --user enable --now pipewire.service wireplumber.service pipewire-pulse.service Created symlink '/home/tom/.config/systemd/user/default.target.wants/pipewire.service' → '/usr/lib/systemd/user/pipewire.service'. Created symlink '/home/tom/.config/systemd/user/pipewire.service.wants/wireplumber.service' → '/usr/lib/systemd/user/wireplumber.service'. Created symlink '/home/tom/.config/systemd/user/default.target.wants/pipewire-pulse.service' → '/usr/lib/systemd/user/pipewire-pulse.service'. tom@raspberrypi:~ $ systemctl --user is-active pipewire wireplumber pipewire-pulse active active active

查看运行状态:

tom@raspberrypi:~ $ wpctl status -n PipeWire 'pipewire-0' [1.4.2, tom@raspberrypi, cookie:1359508960] └─ Clients: 33. pipewire [1.4.2, tom@raspberrypi, pid:2099] 35. WirePlumber [1.4.2, tom@raspberrypi, pid:2098] 47. WirePlumber [export] [1.4.2, tom@raspberrypi, pid:2098] 74. wpctl [1.4.2, tom@raspberrypi, pid:2175] Audio ├─ Devices: │ 48. alsa_card.platform-107c701400.hdmi [alsa] │ 49. alsa_card.platform-107c706400.hdmi [alsa] │ 50. alsa_card.platform-soc_107c000000_sound [alsa] │ ├─ Sinks: │ * 71. alsa_output.platform-soc_107c000000_sound.stereo-fallback [vol: 0.40] │ ├─ Sources: │ * 72. alsa_input.platform-soc_107c000000_sound.stereo-fallback [vol: 1.00] │ ├─ Filters: │ └─ Streams: Video ├─ Devices: │ 54. v4l2_device.platform-1000800000.codec [v4l2] │ 55. v4l2_device.platform-1000880000.pisp_be [v4l2] │ 56. v4l2_device.platform-1000880000.pisp_be [v4l2] │ 57. v4l2_device.platform-1000880000.pisp_be [v4l2] │ 58. v4l2_device.platform-1000880000.pisp_be [v4l2] │ 59. v4l2_device.platform-1000880000.pisp_be [v4l2] │ 60. v4l2_device.platform-1000880000.pisp_be [v4l2] │ 61. v4l2_device.platform-1000880000.pisp_be [v4l2] │ 62. v4l2_device.platform-1000880000.pisp_be [v4l2] │ 63. v4l2_device.platform-1000880000.pisp_be [v4l2] │ 64. v4l2_device.platform-1000880000.pisp_be [v4l2] │ 65. v4l2_device.platform-1000880000.pisp_be [v4l2] │ 66. v4l2_device.platform-1000880000.pisp_be [v4l2] │ 67. v4l2_device.platform-1000880000.pisp_be [v4l2] │ 68. v4l2_device.platform-1000880000.pisp_be [v4l2] │ 69. v4l2_device.platform-1000880000.pisp_be [v4l2] │ 70. v4l2_device.platform-1000880000.pisp_be [v4l2] │ ├─ Sinks: │ ├─ Sources: │ ├─ Filters: │ └─ Streams: Settings └─ Default Configured Devices:

这里:

ID对象含义
50DeviceWM8960 这张物理声卡
71Sink应用把声音送到这里,再通过耳机播放
72Source应用从这里获取麦克风录音
*默认标记未指定设备的应用优先使用它

3 基本功能

3.1 录音

pw-record --rate=48000 --channels=2 ~/pipewire-recording.wav

此时观察音频图(watch -n 0.5 'wpctl status -n')

此时查看端口连接:

tom@raspberrypi:~ $ pw-link -l alsa_input.platform-soc_107c000000_sound.stereo-fallback:capture_FL |-> pw-record:input_FL alsa_input.platform-soc_107c000000_sound.stereo-fallback:capture_FR |-> pw-record:input_FR pw-record:input_FL |<- alsa_input.platform-soc_107c000000_sound.stereo-fallback:capture_FL pw-record:input_FR |<- alsa_input.platform-soc_107c000000_sound.stereo-fallback:capture_FR

WM8960:capture_FL → pw-record:input_FL
WM8960:capture_FR → pw-record:input_FR

这里pw-record是应用创建的流节点。

3.2 播放

pplay ~/pipewire-recording.wav

观察结果:

此时查看端口连接:

tom@raspberrypi:~ $ pw-link -l alsa_output.platform-soc_107c000000_sound.stereo-fallback:playback_FL |<- pw-play:output_FL alsa_output.platform-soc_107c000000_sound.stereo-fallback:playback_FR |<- pw-play:output_FR pw-play:output_FL |-> alsa_output.platform-soc_107c000000_sound.stereo-fallback:playback_FL pw-play:output_FR

pw-play:output_FL → WM8960:playback_FL
pw-play:output_FR → WM8960:playback_FR

4 高级应用

4.1 命令行

对于基本功能,看这几个常用的功能就行了。

wpctl status -n 看全局
wpctl inspect 看对象
pw-link -l 看连线
pw-link / -d 连线、断线
pw-record 录音
pw-play 播放

例子1:

应用节点存在时可以没有声音;建立到声卡的连接后,声音才能送出去。

//播放,此时只有播放没有任何路由

pw-play --target=0 ~/pipewire-test-tone.wav

//连接到左声道

pw-link pw-play:output_FL alsa_output.platform-soc_107c000000_sound.stereo-fallback:playback_FL

//查看连接
pw-link -l
alsa_output.platform-soc_107c000000_sound.stereo-fallback:playback_FL
|<- pw-play:output_FL
pw-play:output_FL
|-> alsa_output.platform-soc_107c000000_sound.stereo-fallback:playback_FL

例子2:

混音

//终端1播放

pw-play ~/pipewire-test-long.wav

//终端2播放

pw-play ~/pipewire-recording.wav

//此时能同时听到两个声音。

路径如下:

当两个播放流连接到同一个 Sink 时,PipeWire 会处理格式转换、音量和混音,再把结果送到声卡。此时PipeWire可以针对某一路单独控制。

例子3:

Monitor

//启动一个不自动连接麦克风的录音流

pw-record --target=0 ~/monitor-test.wav

//保持它运行,再把 Sink 的 monitor_FL/FR 分别连到录音程序的 input_FL/FR。此时播放测试音,录音文件就能收到播放链路中的声音。

4.2 图形工具

工具主要用途与已学命令的对应
qpwgraph显示节点、端口和连线,鼠标连接/断开,支持 Patchbay 连接规则类似图形版pw-link
Helvum较简洁的节点连线界面也是图形化音频图
pavucontrol应用音量、静音、输入输出选择、设备配置覆盖部分wpctl操作,通过pipewire-pulse工作

qpwgraph

pavucontrol

4.3 低延迟

这个功能感觉大部分是硬件,不过软件也可以控制一部分。这里以麦克风实时监听为例:

麦克风 → ADC → 驱动缓冲 → PipeWire → 音效处理 → 驱动缓冲 → DAC → 耳机
环节主要由谁决定PipeWire 能做什么
ADC/DAC 转换、芯片内部滤波硬件通常只能间接通过设备支持的参数影响
声卡传输与 DMA 缓冲硬件+驱动通过 ALSA 协商采样率、缓冲等参数
音频图每次处理多少数据PipeWire调整quantum
节点唤醒、执行顺序软件调度+操作系统安排处理顺序、申请实时调度
音效、重采样等处理软件算法管理处理节点,但算法本身也可能引入延迟

这里PipeWire可以控制缓冲大小。 假设采样率为 48 kHz:

一批处理的帧数对应音频时长
102421.33 ms
2565.33 ms
1282.67 ms

基本上硬件决定了能力和下限;PipeWire 决定如何在这些条件下组织处理,在低延迟与稳定性之间取舍。 同一套硬件,用大缓冲和用小缓冲,实际延迟可以相差很大。

在之前的练习中,就尝试了采集麦克风的帧大小(Audio学习2(麦克风和喇叭)-CSDN博客)。

5 APP层的使用

一般来说要使用这一套功能就要用PipeWire的接口。不过PipeWire 在设计之初就考虑到了兼容性,它提供了完备的垫片(Shim/Emulation Library)和透明兼容层。

  • ALSA 应用(直连底层驱动的轻量应用/嵌入式程序): PipeWire 提供了pipewire-alsa插件(libasound_module_pcm_pipewire.so)。应用以为自己是在直接向 ALSA 设备写 PCM 数据,实际数据被偷偷重定向到了 PipeWire 的 Graph 中。

  • PulseAudio 应用(绝大多数桌面应用,如 Chrome、Firefox、网易云音乐): PipeWire 实现了pipewire-pulse服务,提供了一个和 PulseAudio 一模一样的 UNIX Socket 接口。应用发给 PulseAudio 的音频指令和数据,直接由 PipeWire 接管解析。

  • JACK 专业音频应用(如 Ardour、REAPER、FL Studio Linux 版): PipeWire 提供了pipewire-jack替换库。应用调用的libjack.so被替换为 PipeWire 的实现,瞬间获得低延迟的专业路由能力。

直接使用pipewire当然是现在更好的选择,一个简单的播放例子如下:

#include <stdio.h> #include <math.h> #include <spa/param/audio/format-utils.h> #include <spa/pod/builder.h> #include <pipewire/pipewire.h> struct data { struct pw_main_loop *loop; struct pw_stream *stream; float phase; }; // 核心音频处理回调函数:当 PipeWire 需要新数据时会触发此函数 static void on_process(void *userdata) { struct data *data = userdata; struct pw_buffer *b; struct spa_buffer *buf; float *samples; int n_frames, n_channels; int i, c; // 1. 从管道中获取一个可写缓冲区 b = pw_stream_dequeue_buffer(data->stream); if (!b) return; buf = b->buffer; if (!buf->datas[0].data) return; samples = buf->datas[0].data; n_channels = 2; // 双声道(立体声) n_frames = buf->datas[0].maxsize / (sizeof(float) * n_channels); // 2. 实时生成 440 Hz 正弦波填充缓冲区 for (i = 0; i < n_frames; i++) { // 生成幅值为 0.2 的正弦波,防止声音过大 float val = sinf(data->phase) * 0.2f; // 步进相角:2 * pi * 频率 / 采样率 ># ~/.config/wireplumber/wireplumber.conf.d/50-my-card.conf monitor.alsa.rules = [ { matches = [ { node.name = "alsa_output.pci-0000_00_1f.3.analog-stereo" } ] actions = { update-props = { node.description = "我的内置扬声器" node.nick = "Speaker" priority.driver = 100 } } } ]

7 PulseAudio

PulseAudio 是一个运行在应用和 ALSA 之间的音频服务,主要解决桌面上多个应用共享音频设备的问题。

它提供的典型功能包括:

  • 多个应用同时播放并混音。
  • 每个应用独立调音量、静音。
  • 选择默认麦克风和输出设备。
  • 将应用声音切换到耳机、HDMI、蓝牙等设备。
  • 通过输出的 Monitor 录制系统声音。

不过目前PipeWire 覆盖的场景更广,又能承接原来的应用生态。所以基本上都升级到PipeWire了。这里也就不重点看了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/2 6:36:11

自用-牛客网-华为机试编程模拟题4-python

单向链表import sysdef solve():data list(map(int, sys.stdin.buffer.read().split()))idx 0n data[idx]; idx 1h data[idx]; idx 1nxt {h: None}for _ in range(n - 1):a data[idx]; idx 1b data[idx]; idx 1nxt[a] nxt.get(b, None)nxt[b] ak data[idx]; idx …

作者头像 李华
网站建设 2026/11/2 6:34:47

微软砸钱做云,WPS靠本地化追:同样叫365,背后竟是这般算计?

说起办公软件&#xff0c;你可能会想到Office 365&#xff0c;毕竟它背靠国际大厂微软&#xff0c;功能多&#xff0c;用的人也多。而WPS 365名气就没有那么大&#xff0c;但用起来还是挺顺手的&#xff0c;毕竟更符合我们国人的操作习惯。这里普及一个小知识像这类办公软件&am…

作者头像 李华
网站建设 2026/11/2 6:34:02

华为OD机试真题 新系统 2026-10-28 PythonJS【AI推理任务并行额度】

目录 题目 思路 Code 题目 题目内容: 有 n 个 AI 推理任务按顺序排队,第 i 个任务需占用 vram[i] GB 显存;调度器可选定一个任务 i 为基准,向左右连续合并相邻任务(即连续子数组),合并条件是被合并任务的显存占用不低于 vram[i]。 已知任务的并行执行额度值 = vr…

作者头像 李华
网站建设 2026/11/2 6:34:00

CISP-PTE 爆破篇

本文为 CISP-PTE 备考学习笔记&#xff0c;所有操作仅在官方授权靶场、本地自建靶场环境完成。 文中 Payload 仅用于原理学习、靶场练习。严禁直接套用在任何未授权公网业务系统。未经授权对网站进行注入、扫描属于违法行为&#xff0c;请遵守《网络安全法》。 本文目的&#x…

作者头像 李华
网站建设 2026/11/2 6:32:35

前期论文阅读

1.GIT-BO: High-Dimensional Bayesian Optimization Using Tabular Foundation Models降维操作利用TabPFN对所有候选点进行计算目标函数的预测均值U和方差&#xff0c;利用TabPFN的预测均值构建预测均值梯度的二阶矩阵H()&#xff0c;算法选择 H 的前 r 个特征向量作为梯度引导…

作者头像 李华
网站建设 2026/11/2 6:30:45

UmedPT与生存分析杂谈———医学影像人工智能

医学影像人工智能与生存分析的交叉研究正变得越来越深入。 一、UMedPT&#xff1a;一个用1%数据达到95%性能的多任务基础模型 论文《Overcoming data scarcity in biomedical imaging with a foundational multi-task model》提出了一个名为 UMedPT 的基础多任务模型&#xff0…

作者头像 李华