用 Rust 封装 audio.cpp —— 基于 ggml 的高性能本地音频推理引擎。
audio.cpp 是一个纯 C++ 音频推理框架,基于 ggml,支持 TTS、STT(ASR)、VAD、说话人分离、音源分离、声音克隆、编解码与音乐生成等 135 个模型族(另含 2 个内置 VAD),后端覆盖 CPU / CUDA / HIP / Vulkan / Metal,可加载 GGUF 与 safetensors 模型。完整清单见 模型目录。
| Crate | 说明 |
|---|---|
audio-cpp-sys |
底层 FFI:用 CMake 构建 engine_runtime 静态库,bindgen 生成 C ABI 绑定 |
audio-cpp |
高层安全封装:类型安全的注册表 / 模型 / 会话 API(离线 + 流式)。使用指南见 audio-cpp/README.md |
audio-cpp-rs/
├── audio-cpp-sys/ # 底层绑定 crate
│ ├── build.rs # CMake(Ninja) 构建 engine_runtime + cc 编译 shim + bindgen
│ ├── capi.h # C ABI 头文件(跨边界契约的全部内容)
│ ├── capi.cpp # C++ shim:把 audio.cpp 的异常转换为 C 错误码
│ └── audio.cpp/ # ⚠️ git submodule 引入的上游源码(内容不入库)
├── audio-cpp/ # 高层安全封装 crate
├── docs/ # 文档:模型目录、调研报告、预编译报告等
└── scripts/ # 维护脚本:由上游 model_specs 生成 docs/models.md
上游 audio.cpp 以 git submodule 引入:.gitmodules → https://github.com/0xShug0/audio.cpp.git,内容不提交进本仓库。克隆本项目后需先补齐子模块:
git submodule update --init --recursive跨边界契约固定在 capi.h / capi.cpp:
- 结构化数据一律以 JSON 字符串(UTF-8,
\0结尾)跨过 ABI 边界; - 音频采样以
float数组跨过边界; - 所有权:C++ 侧持有对象,
audiocpp_*返回的句柄 / 字符串 / 采样缓冲都必须用对应的free()释放; - 错误:函数返回 0 成功、非 0 失败,最近一次错误信息可用
audiocpp_last_error()获取;audio.cpp 抛出的异常在 shim 边界被捕获,绝不会泄漏进 C。
Registry(注册表:枚举/加载模型族)
└─ audiocpp_registry_load() → Model(已加载的模型:元数据/能力)
└─ audiocpp_model_create_task_session() → Session(离线/流式任务会话)
├─ Offline: prepare() → run_offline() → TaskResult(JSON)
└─ Streaming: set_event_sink() → start() → process_audio() → finish()
依赖:CMake ≥ 3.20、Ninja、C/C++ 编译器(MSVC 或 GCC/Clang)、(bindgen 需要)LLVM/clang 与 MSVC 环境。
首次构建前先拉取上游源码(见上),随后:
cargo build # 默认:core-models + CPU
cargo build --release可选的 Cargo features:
所有 feature 在两个 crate 上均可使用(
audio-cpp会原样转发给audio-cpp-sys)。
| Feature | audio.cpp 映射 | 作用 |
|---|---|---|
core-models(默认) |
AUDIOCPP_MODEL_SET=core |
最小编译集:引擎核心 + 内置 VAD(silero_vad / marblenet_vad)。内置 VAD 权重随上游 vendored,开箱即用 |
model-<族> |
AUDIOCPP_MODEL_SET=custom |
按需编译单个模型族(最推荐,无需设环境变量) |
custom-models |
AUDIOCPP_MODEL_SET=custom |
按需编译:引擎核心 + 内置 VAD + AUDIOCPP_MODELS 指定的模型族(兜底,配合环境变量使用) |
full-models |
AUDIOCPP_MODEL_SET=full |
全量:audio.cpp 全部 135 个 loader 族(编译极慢、产物很大,权重仍需自行下载) |
按需编译单个模型族:启用对应的 model-<族> feature 即可,无需设置环境变量:
cargo build --features model-qwen3-asr # 只编译 Qwen3 ASR + 内置 VAD
cargo run -p audio-cpp --features model-citrinet-asr --example asr_offline # ASR 示例已内置 91 个专用族 feature(完整列表见各 crate 的 Cargo.toml;“模型族 → feature”对照见 模型目录):
| Feature | 模型族(上游 target/alias) | 用途 |
|---|---|---|
model-qwen3-asr / model-citrinet-asr / model-fun-asr-nano |
对应 asr 族 | ASR(qwen3 / citrinet 已验证) |
model-hviske-asr / model-kroko-asr / model-nemotron-asr / model-parakeet-tdt / model-vibevoice-asr … |
对应 asr 族 | ASR |
model-moss |
moss(moss_tts_nano / moss_tts_local) | TTS(已验证) |
model-qwen3-tts / model-irodori-tts / model-fish-audio / model-fish-drama3 … |
对应 tts 族 | TTS / 声音克隆 |
model-demucs |
demucs(htdemucs / htdemucs_6stems) | 音源分离 |
model-roformer |
roformer(mel_band_roformer / bs_roformer) | 音源分离 |
model-sortformer-diar / model-sortformer-diar-v2 / model-nemotron-3-diar |
对应 diar 族 | 说话人分离 |
- build.rs 会自动收集所有启用的
model-<族>feature(经CARGO_FEATURE_MODEL_*环境变量),并把它们与AUDIOCPP_MODELS环境变量取并集——两者可混用; 新增族 feature 只要在 Cargo.toml 声明名字与上游 target/alias 一致即可,无需改 build.rs。 - 少数族没有专用 feature(如
chatterbox、index_tts2、glm_tts、outetts、pocket_tts、voxcpm2、voxtral_tts等),仍用custom-models+AUDIOCPP_MODELS。ModelFamily枚举覆盖全部上游 loader 族(未知族可用Custom(String)兜底), 未提供 feature 的族仍可用族名加载;完整对照见 模型目录。
$env:AUDIOCPP_MODELS = "citrinet_asr,qwen3_asr,moss_tts_nano"; cargo build --features custom-models
AUDIOCPP_MODELS接受上游 CMake 的 alias/target 名(逗号分隔),引擎核心与 内置 VAD 始终编入。build.rs 对 custom-models 强制 re-configure,切换组合后直接 重新构建即生效,无需 clean。
| Feature | audio.cpp 映射 | 作用 | 前提条件 |
|---|---|---|---|
cuda |
ENGINE_ENABLE_CUDA=ON |
NVIDIA GPU 加速 | 已装 CUDA Toolkit(nvcc/cudart) |
hip |
ENGINE_ENABLE_HIP=ON |
AMD GPU 加速(HIP/ROCm) | 已装 ROCm 工具链;与 cuda 互斥 |
vulkan |
ENGINE_ENABLE_VULKAN=ON |
Vulkan 通用计算后端 | Vulkan SDK 与驱动;跨厂商通用,性能/算子覆盖通常不如专属后端 |
metal |
ENGINE_ENABLE_METAL=ON |
Apple Metal | macOS 默认即开启;win32 上默认关闭,需设 AUDIOCPP_FORCE_METAL 才强制开启 |
openmp |
ENGINE_ENABLE_OPENMP=ON |
多线程并行加速 | OpenMP 运行时(MSVC /openmp、GCC/Clang libgomp);未装则链接期报错,此时应关掉而非忽略 |
native |
ENGINE_ENABLE_NATIVE_CPU=ON |
针对本机 CPU 生成优化指令(AVX2/FMA 等) | 产物不可移植到旧 CPU;目标机与构建机不同时勿开 |
cargo build # 默认 core-models + CPU
cargo build --features core-models,openmp # CPU 多线程
cargo build --features full-models,cuda # 全量模型 + NVIDIA GPU
cargo build --features custom-models,vulkan,openmp| 变量 | 作用 |
|---|---|
BUILD_DEBUG=1 |
开启 build.rs 调试日志(cargo:warning) |
CMAKE_VERBOSE |
开启 CMake 详细输出 |
AUDIOCPP_LIB_PROFILE |
覆盖 CMake 构建 profile(默认 Release) |
GGML_* / CMAKE_* |
透传给 CMake 缓存,微调 ggml 选项 |
全部 135 个模型族(另含 2 个内置 VAD)按任务分类的简要介绍、family_hint、任务 token、
离线/流式、语言与上游状态,见 docs/models.md。
每个条目标注了可直接启用的 model-<族> feature,并链接到上游对应的说明页。
音频模型权重不随本仓库提供(除内置 VAD),需要从 Hugging Face 下载:
- 官方 GGUF 包:
audio-cpp/audio.cpp-gguf—— audio.cpp 官方发布的现成 GGUF 模型(Q8_0 / Q16 / F32 等精度,按Family-GGUF/<name>.gguf组织),大多数模型族开箱即用; - 社区模型包:
mirek190/audio.cpp—— 社区维护的补充模型; - 官方下载工具:上游提供
tools/model_manager_v2.py,按model_specs/*.json下载各模型族的默认包,优先选取现成 GGUF(见上游 docs/model_manager.md); - 内置权重:silero_vad / marblenet_vad 随上游 vendored(
assets/framework/models),无需下载。
各示例头注里均标注了对应模型的下载地址与所需 feature;GGUF 模型加载时须显式 传
family_hint(见audio-cpp/README.md)。想自动下载而非手动点页面:
audio-cpp/examples/download_model示例用 hf-hub(仅示例用 dev-dependency)在本地文件 不存在时直接从 Hugging Face 拉到缓存再加载,详见该示例头注。
audio-cpp-sys/examples/ 提供直接使用 FFI 的端到端演示(已在本机 win32/MSVC 验证运行),audio-cpp/examples/ 则展示安全高层 API:
# 底层 FFI:
# 1) 枚举注册表、设备与错误路径(验证 FFI 链路)
cargo run -p audio-cpp-sys --example inspect
# 2) silero_vad 离线 VAD:对 wav 检测语音片段,输出 JSON
cargo run -p audio-cpp-sys --example vad_offline_ffi -- `
audio-cpp-sys/audio.cpp/assets/framework/models/silero_vad/silero_vad_16k.safetensors `
audio-cpp-sys/audio.cpp/assets/resources/sample_16k.wav
# 高层 API(类型安全,无需手动管理 C 句柄):
# 3) 离线 VAD(silero_vad;marblenet_vad 需传第 3 个 family_hint)
cargo run -p audio-cpp --example vad_offline -- `
audio-cpp-sys/audio.cpp/assets/framework/models/silero_vad/silero_vad_16k.safetensors `
audio-cpp-sys/audio.cpp/assets/resources/sample_16k.wav
# marblenet_vad(NeMo 格式,引擎自动探测易误判,须显式指定模型族)
cargo run -p audio-cpp --example vad_offline -- `
audio-cpp-sys/audio.cpp/assets/framework/models/marblenet_vad/marblenet_vad.safetensors `
audio-cpp-sys/audio.cpp/assets/resources/sample_16k.wav marblenet_vad
# 4) 流式 VAD(事件回调 + 分块 process_audio)
cargo run -p audio-cpp --example vad_streaming -- `
audio-cpp-sys/audio.cpp/assets/framework/models/silero_vad/silero_vad_16k.safetensors `
audio-cpp-sys/audio.cpp/assets/resources/sample_16k.wav
# 5) 离线 ASR(Citrinet GGUF 需自行下载,见 asr_offline.rs 头注)
# 用 feature 方式按需编译(推荐,无需环境变量):
cargo run -p audio-cpp --features model-citrinet-asr --example asr_offline -- `
./citrinet-asr-q8_0.gguf audio-cpp-sys/audio.cpp/assets/resources/sample_16k.wav
# 6) 离线 TTS(MOSS-TTS-Nano GGUF 需自行下载,见 tts_offline.rs 头注)
cargo run -p audio-cpp --features model-moss --example tts_offline -- `
./moss-tts-nano-100m-q8_0.gguf out.wav "Hello from Rust and audio.cpp!"
# 6b) 离线 TTS 声音克隆(Qwen3 TTS base 变体须做 voice-clone,见 tts_offline_qwen3.rs 头注)
cargo run -p audio-cpp --features model-qwen3-tts --example tts_offline_qwen3 -- `
./qwen3-tts-12hz-0.6b-base-q8_0.gguf `
audio-cpp-sys/audio.cpp/assets/resources/sample_16k.wav `
"Some call me nature. Others call me Mother Nature." `
out.wav "Hello from Rust and Qwen3 TTS!"
# 7) 离线说话人分离(SortFormer GGUF 需自行下载并重采样到 16kHz,见 diar_offline.rs 头注)
cargo run -p audio-cpp --features model-sortformer-diar --example diar_offline -- `
./sortformer-diar-4spk-v1-q8_0.gguf ./four_speaker_16k.wav
# 8) 离线音乐源分离(HTDemucs GGUF 需自行下载,输入须 44.1kHz 立体声,见 sep_offline.rs 头注)
cargo run -p audio-cpp --features model-demucs --example sep_offline -- `
./htdemucs-q8_0.gguf ./song.wav ./sep_out
# 9) 流式 ASR(Qwen3 ASR:窗口部分转录 + 最终文本)
cargo run -p audio-cpp --features model-qwen3-asr --example asr_streaming -- `
./qwen3-asr-q8_0.gguf audio-cpp-sys/audio.cpp/assets/resources/sample_16k.wav
# 10) 流式 TTS(VoxCPM2:逐块音频事件 + 合并输出)
$env:AUDIOCPP_MODELS="voxcpm2"; cargo build --features custom-models
cargo run -p audio-cpp --features custom-models --example tts_streaming -- `
./voxcpm2-q8_0.gguf out.wav "你好,我是流式语音合成。"
# 11) 注册表内省(无需下载权重;枚举模型族/loader/设备并校验 ModelFamily 往返)
cargo run -p audio-cpp --example registry_inspect
# 12) 非 WAV 音频输入:用 symphonia 解码 mp3/flac/ogg/m4a 等任意格式喂给引擎
# (symphonia 仅示例用 dev-dependency,不进入库依赖;用户可用任何解码库)
cargo run -p audio-cpp --example load_any_audio -- `
audio-cpp-sys/audio.cpp/assets/framework/models/silero_vad/silero_vad_16k.safetensors `
./song.mp3
# 13) 模型自动下载:本地不存在时用 hf-hub 从 Hugging Face 拉取到缓存再加载
# (hf-hub 仅示例用 dev-dependency;缓存走 HF_HOME,再次运行自动命中)
cargo run -p audio-cpp --example download_model -- `
audio-cpp/audio.cpp-gguf Qwen3-ASR-0.6B-GGUF/qwen3-asr-0.6b-q8_0.gguf- 工作区骨架(workspace、audio-cpp-sys、audio-cpp)
- C ABI 设计与实现(capi.h/capi.cpp)
- 构建脚本(CMake + cc + bindgen)
- 首次端到端构建验证(win32/MSVC,
cargo build --workspace通过) - 示例(inspect、vad_offline_ffi、高层 vad_offline / vad_streaming,均在本机运行验证)
- 高层安全 API(Registry / Model / Session,离线 + 流式)
- 模型族端到端验证(VAD、ASR、TTS、说话人分离、音乐源分离,见 AGENTS.md)
- 内置 VAD 两种模型端到端验证:silero_vad(离线+流式)、marblenet_vad(离线)
- ASR 端到端验证:Citrinet ASR Q8_0 GGUF 离线转录(sample_16k.wav → Nature 台词)
- TTS 端到端验证:MOSS-TTS-Nano-100M Q8_0 GGUF 离线合成(~8s 语音写入 WAV)
- Qwen3 TTS 声音克隆端到端验证:qwen3-tts-12hz-0.6b-base Q8_0 GGUF(sample_16k.wav 做参考 → ~4s 克隆语音)
- C ABI 音频回传:
audio_output.samples携带生成音频的 f32 采样 -
custom-modelsfeature:按需编译指定模型族,避免 full 全量成本 - 说话人分离端到端验证:SortFormer Diar 4spk Q8_0 GGUF(four_speaker_short.wav 重采样到 16kHz)
- 音乐源分离端到端验证:HTDemucs Q8_0 GGUF(44.1kHz 立体声 → drums/bass/other/vocals)
-
ModelFamily枚举族名替代裸字符串 hint(并给出Custom(String)兜底) - 流式 ASR 端到端验证:Qwen3 ASR Q8_0 GGUF(sample_16k.wav → 逐窗口部分转录 + 最终文本)
- 注册表内省示例(registry_inspect)与流式 TTS 示例(tts_streaming,VoxCPM2)
- C ABI 流事件回传:
StreamEvent.named_audio_outputs(流式 TTS 逐块音频) - 非 WAV 音频输入示例(load_any_audio):symphonia 解码 mp3/flac 实测跑通(symphonia 为 dev-dependency,不进入库依赖)
- 模型自动下载示例(download_model):hf-hub 从官方仓库实测下载 citrinet GGUF 并缓存复用(hf-hub 为 dev-dependency,不进入库依赖)
- audio.cpp 官方仓库
- docs/models.md —— 全部模型族按任务分类的简要介绍与 feature 对照
- llama-cpp-rs(utilityai,v2:llama-cpp-sys-2 / llama-cpp-2) —— 本地参考实现(submodule 方式引入上游)
- llama-cpp-rs(eugenehp,v4) —— 新一代 llama-cpp-rs(llama-cpp-rs4)
- docs/research_report.md —— 调研报告
Apache-2.0,完整条款见 LICENSE。
上游 audio.cpp 以 git submodule 引入,同为
Apache-2.0(版权归 ShugoAI LLC,见其仓库 LICENSE);其源码内容不进入本仓库,
也不改变本仓库的许可口径。构建产物同时受 ggml 及其依赖的许可证约束,第三方
分发时请一并保留各上游的版权与许可声明。