RustAudio/cpal

GitHub: RustAudio/cpal

一个用 Rust 编写的跨平台低级音频输入输出库,为开发者提供统一的音频设备访问和音频流控制接口。

Stars: 3814 | Forks: 513

# CPAL - 跨平台音频库 [![Actions 状态](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/5e540412db121338.svg)](https://github.com/RustAudio/cpal/actions) [![Crates.io](https://img.shields.io/crates/v/cpal.svg)](https://crates.io/crates/cpal) [![docs.rs](https://docs.rs/cpal/badge.svg)](https://docs.rs/cpal/) 用于音频输入和输出的低级库,使用 Rust 编写。 如果需要更高层次的音频播放和捕获,请考虑使用 [Rodio](https://github.com/RustAudio/rodio) 或类似的库。 ## 支持的功能 - 枚举音频宿主、设备及其支持的流配置。 - 通过稳定的 ID 或默认的输入/输出角色查找设备。 - 检查设备元数据:名称、制造商、类型和总线类型。 - 使用编译时或运行时采样格式构建输入和输出流。 - 播放、暂停以及查询流的缓冲区大小和时钟。 ## 支持的平台 | 平台 | 默认后端 | 可选后端 | | -------- | --------------- | ----------------- | | Android | AAudio | - | | BSD | ALSA | JACK, PipeWire, PulseAudio | | iOS | CoreAudio | - | | Linux | ALSA | JACK, PipeWire, PulseAudio | | macOS | CoreAudio | JACK | | tvOS | CoreAudio | - | | WebAssembly | Web Audio API | Audio Worklet | | Windows | WASAPI | ASIO, JACK | ## Linux 构建依赖 在 Linux 上,构建 cpal 需要 ALSA 开发文件:Debian 和 Ubuntu 上为 `libasound2-dev`,Fedora 上为 `alsa-lib-devel`。 即使使用 JACK、PipeWire 或 PulseAudio,也依然需要 ALSA。 可选的 `realtime-dbus` 功能额外需要 `libdbus-1-dev` (Debian/Ubuntu) 或 `dbus-devel` (Fedora)。请参阅 [ALSA 实时优先级提升](#alsa-real-time-priority-promotion)。 ## 最低支持版本 最低 Rust 版本 (MSRV) 以及最低操作系统 / 运行时版本均取决于您所使用的音频后端和功能,因为每个平台具有不同的依赖项: | 后端 | 平台 | MSRV | 最低 OS / 运行时 | | ------- | --------- | ---- | -------------------- | | AAudio | Android | 1.85 | Android 8.0 (API 26) | | ALSA | Linux, BSD | 1.85 | — | | CoreAudio | macOS | 1.85 | macOS 14.2(环回录制需要 14.6+) | | CoreAudio | iOS | 1.85 | — | | CoreAudio | tvOS | nightly | — | | JACK | Linux, BSD, macOS, Windows | 1.85 | — | | PipeWire | Linux, BSD | 1.85 | PipeWire 0.3.53 | | PulseAudio | Linux, BSD | 1.88 | — | | WASAPI / ASIO | Windows | 1.85 | Windows 8 | | WASM (`wasm32-unknown`) | WebAssembly | 1.85 | — | | WASM (`wasm32-wasip1`) | WebAssembly | 1.85 | — | | WASM (`audioworklet`) | WebAssembly | nightly | — | `audioworklet` 后端额外需要启用了 atomics 支持的 `-Zbuild-std`。 ## 可选功能 | 功能 | 平台 | 描述 | | ------- | -------- | ----------- | | `asio` | Windows | 用于低延迟音频的 ASIO 后端,绕过 Windows 音频堆栈。需要 ASIO 驱动程序和 LLVM/Clang。请参阅 [ASIO 设置指南](#compiling-for-asio)。 | | `audioworklet` | WebAssembly (`wasm32-unknown-unknown`) | Audio Worklet 后端,提供比默认 Web Audio API 更低延迟的 Web 音频,在专用线程上运行音频。需要 atomics 支持 (`RUSTFLAGS="-C target-feature=+atomics,+bulk-memory,+mutable-globals"`) 以及用于 `SharedArrayBuffer` 的 `Cross-Origin` 标头。请参阅 `audioworklet-beep` 示例。 | | `custom` | 所有 | 用户定义的后端实现,适用于 CPAL 原生不支持的其他音频系统。请参阅 `examples/custom.rs`。 | | `jack` | Linux, BSD, macOS, Windows | 用于专业音频路由和应用程序间连接的 JACK Audio Connection Kit 后端。需要 `libjack-jackd2-dev` (Debian/Ubuntu) 或 `jack-devel` (Fedora)。 | | `pipewire` | Linux, BSD | PipeWire 媒体服务器后端。需要 `libpipewire-0.3-dev` (Debian/Ubuntu) 或 `pipewire-devel` (Fedora)。 | | `pulseaudio` | Linux, BSD | PulseAudio 声音服务器后端。需要 `libpulse-dev` (Debian/Ubuntu) 或 `pulseaudio-libs-devel` (Fedora)。 | | `realtime` | Linux, BSD, Windows, Android | 将音频回调线程提升至实时或高优先级调度,以降低延迟。在 Linux/BSD 上,除非同时启用了 `realtime-dbus`,否则需要在 `limits.conf` 中授予 `rtprio` 权限(例如 `@audio - rtprio 95`)。 | | `realtime-dbus` | Linux, BSD | 在 Linux/BSD 桌面系统上通过 D-Bus 使用 `rtkit` 进行 RT 调度,免去了手动设置 `limits.conf` 的需要。意味着在所有平台上均启用 `realtime`。在 Linux/BSD 上需要 `libdbus-1-dev`。 | | `wasm-bindgen` | WebAssembly (`wasm32-unknown-unknown`) | 用于基于浏览器的音频的 Web Audio API 后端;这是支持任何 WebAssembly 音频所必需的。请参阅 `wasm-beep` 示例。 | 请参阅 [beep 示例](examples/beep.rs) 了解如何在运行时选择后端。 ## 为 ASIO 编译 ### 定位 ASIO SDK 通过设置 `CPAL_ASIO_DIR` 环境变量向 CPAL 暴露 ASIO SDK 的位置。 构建脚本将按以下步骤依次尝试查找 ASIO SDK: 1. 检查是否设置了 `CPAL_ASIO_DIR`,如果已设置,则使用该路径指向 SDK。 2. 检查 ASIO SDK 是否已安装在临时目录中,如果已安装,则使用它并将 `CPAL_ASIO_DIR` 的路径设置为 `std::env::temp_dir().join("asio_sdk")` 的输出。 3. 如果 ASIO SDK 尚未安装,请从 下载并将其安装到临时目录。`CPAL_ASIO_DIR` 的路径将被设置为 `std::env::temp_dir().join("asio_sdk")` 的输出。 在理想情况下,您无需为此步骤操心。 ### 准备构建环境 1. **安装 LLVM/Clang**:`bindgen`(用于生成 C++ SDK 绑定的库)需要 clang。从 的“Pre-Built Binaries”部分下载并安装 LLVM。 2. **设置 LIBCLANG_PATH**:将 LLVM 的 `bin` 目录添加到 `LIBCLANG_PATH` 环境变量中。如果您将 LLVM 安装到了默认目录,以下命令在命令提示符中应该可以正常运行: setx LIBCLANG_PATH "C:\Program Files\LLVM\bin" 3. **安装 ASIO 驱动程序**(对于测试是可选的):如果您没有任何可用的 ASIO 设备或驱动程序,可以从 下载并安装 ASIO4ALL。请确保在安装过程中启用“offline”功能。 4. **Visual Studio**:构建脚本假定已安装 Microsoft Visual Studio。它将尝试找到 `vcvarsall.bat` 并使用正确的主机和目标架构执行它。如有需要,您可以手动执行它: "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64 有关更多信息,请参阅 [vcvarsall.bat 文档](https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line)。 ### 在您的应用程序中使用 ASIO 1. 在您的 `Cargo.toml` 中**启用该功能**: cpal = { version = "*", features = ["asio"] } 2. 在您的代码中**选择 ASIO 后端**: let host = cpal::host_from_id(cpal::HostId::Asio) .expect("failed to initialise ASIO host"); ### 交叉编译 当 Windows 同时作为宿主和目标 OS 时,构建脚本支持 MSVC 编译器支持的所有交叉编译目标。 也可以在 Linux 和 macOS 上使用 MinGW-w64 工具链编译具有 ASIO 支持的 Windows 应用程序。 **要求:** - 在您的 `CPLUS_INCLUDE_PATH` 环境变量中包含 MinGW-w64 的 include 目录 - 在您的 `CPLUS_INCLUDE_PATH` 环境变量中包含 LLVM 的 include 目录 **macOS 上的示例**(目标为 `x86_64-pc-windows-gnu`,通过 brew 安装了 `mingw-w64`): ``` export CPLUS_INCLUDE_PATH="$CPLUS_INCLUDE_PATH:/opt/homebrew/Cellar/mingw-w64/11.0.1/toolchain-x86_64/x86_64-w64-mingw32/include" ``` ## 为 WebAssembly 编译 如果您有兴趣将 CPAL 与 WebAssembly 结合使用,请查阅我们 Wiki 中的[此指南](https://github.com/RustAudio/cpal/wiki/Setting-up-a-new-CPAL-WASM-project),其中详细介绍了如何从头开始设置新项目。本仓库中的一些示例也提供了可供参考的有效配置。 ## 故障排除 ### 没有可用的默认设备 如果您收到关于没有默认输入或输出设备的错误: - **Linux/PipeWire:** 检查 PipeWire 是否正在运行:`pw-cli info` - **Linux/PulseAudio:** 检查 PulseAudio 是否正在运行:`pulseaudio --check` - **macOS:** 在“系统偏好设置”>“声音”中检查可用设备 - **移动设备 (iOS/Android):** 确保您的应用具有麦克风/音频权限 - **Windows:** 在“声音设置”中验证您的音频设备是否已启用 ## ALSA、PipeWire 和 PulseAudio 当 PipeWire 或 PulseAudio 正在运行时,它会独占 ALSA 的 `default` 设备。如果第二个流试图通过 ALSA 宿主打开它,将会失败并报 `DeviceBusy` 错误。要通过 ALSA 将音频路由至声音服务器,请使用桥接设备 `pipewire` 或 `pulse`,而不是 `default`。更好的做法是使用 `pipewire` 或 `pulseaudio` cpal 功能进行原生集成。 在没有声音服务器的目标上,直接使用 `hw:` 或 `plughw:` 寻址设备。 ### 缓冲区大小问题 `BufferSize::Default` 使用系统配置的设备默认值,在 **ALSA** 上,这个值的范围可能从 PipeWire 量子(通常为 1024 帧)一直到配置错误或特殊硬件上的 `u32::MAX`。极深的缓冲区会导致样本的消耗速度远快于可听的播放速度,使得音频听起来像是在实际输出之前快进。 请配置系统和/或在您的应用程序中请求一个固定的大小: | 系统 | 文件 | 设置 | | ------ | ---- | ------- | | ALSA | `~/.asoundrc` 或 `/etc/asound.conf` | `buffer_size`, `periods` * `period_size` | | PipeWire | `~/.config/pipewire/pipewire.conf.d/` | `default.clock.quantum` | | PulseAudio | `~/.config/pulse/daemon.conf` | `default-fragments` * `default-fragment-size-msec` | ``` config.buffer_size = cpal::BufferSize::Fixed(1024); ``` 查询 `device.default_output_config()?.buffer_size()` 以获取有效范围。较小的缓冲区会减少延迟,但会增加 CPU 负载和出现故障的风险。 ### ALSA 实时优先级提升 RT 提升仅会针对白名单中的 PCM 类型尝试进行:直接硬件 PCM (`hw:`) 和纯格式转换插件(linear、A-law、mu-law、ADPCM、float、IEC 958)。 只有在尝试进行提升但失败时,才会在错误回调中发出 `RealtimeDenied`,这种情况通常发生在进程缺乏获取 `SCHED_FIFO` 的资源限制时。虽然 RT 优先级对于低延迟来说是理想的,但流仍将以默认的调度优先级继续播放。 启用 `realtime-dbus` 功能后,`rtkit` 将在典型的桌面系统上通过 D-Bus 安排必要的限制。仅启用普通的 `realtime` 功能时,您必须自行确保已授予 `rtprio` 权限。将以下内容添加到 `/etc/security/limits.d/audio.conf` 中,并确保该用户是 `audio` 组的成员: ``` @audio - rtprio 95 ``` 然后将用户添加到 `audio` 组(`usermod -aG audio "$USER"`)并重新登录。在那些没有通过 `logind` 自动配置 `udev` 以授予 ALSA 设备文件访问权限的系统上,无论如何都可能需要相同的组。 ### 构建错误 如果您无法构建该库: - 确认您已经如上文所述安装了所需的开发库 **Windows 上的 ASIO:** 确认已设置 `CPAL_ASIO_DIR` 和 `LIBCLANG_PATH` 并且已安装 LLVM ## 示例 CPAL 在 `examples/` 目录中提供了几个示例。 使用以下命令运行示例: ``` cargo run --example beep ``` 要启用特定平台的功能,请启用相关功能: ``` cargo run --example beep --features asio # Windows ASIO backend cargo run --example beep --features jack # JACK backend cargo run --example beep --features pipewire # PipeWire backend cargo run --example beep --features pulseaudio # PulseAudio backend ``` ## 资源 - **文档:** [docs.rs/cpal](https://docs.rs/cpal) - **示例:** 本仓库中的 [examples/](examples/) 目录 - **更高层次的播放和捕获:** [Rodio](https://github.com/RustAudio/rodio) 或类似的库 - **Discord:** 加入 [#cpal 频道](https://discord.gg/vPmmSgJSPV) 进行提问和讨论 - **GitHub:** [报告问题](https://github.com/RustAudio/cpal/issues) 和 [查看源代码](https://github.com/RustAudio/cpal) - **RustAudio:** 属于 [RustAudio 组织](https://github.com/RustAudio) 的一部分 ## 许可证 在 Apache License, Version 2.0 下授权。详情请参阅 [LICENSE](LICENSE)。
标签:Rust, 可视化界面, 多媒体, 底层库, 网络流量审计, 通知系统, 音频处理, 音频输入输出