ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Background Music深度解析:Core Audio HAL插件如何创建macOS虚拟音频设备

2026/9/21 19:30:40 拓冰建站 浏览量
Background Music深度解析:Core Audio HAL插件如何创建macOS虚拟音频设备 Background Music深度解析Core Audio HAL插件如何创建macOS虚拟音频设备【免费下载链接】BackgroundMusicBackground Music, a macOS audio utility: automatically pause your music, set individual apps volumes and record system audio.项目地址: https://gitcode.com/gh_mirrors/ba/BackgroundMusicBackground Music 是一款 macOS 音频工具它的核心是一个Core Audio HAL 插件负责在系统声音里种入一个名为Background Music的虚拟音频设备。这个虚拟设备既是输入设备、也是输出设备你能录制系统声音、单独调节每个 App 的音量还能在其他程序发声时自动暂停音乐。本文将从架构到数据流完整解析这个用户态 HAL 插件是如何一步步创建并运转这套 macOS 虚拟音频设备的。 先认识 Background Music 的三大核心功能在深入源码之前先看看这个虚拟设备到底为用户做了什么。Background Music 提供三大核心能力自动暂停音乐当第二个音源开始播放时自动暂停你的音乐播放器独立应用音量给每个运行中的 App 单独一个音量滑块录制系统声音把系统正在播放的声音当作麦克风录下来这三个功能的背后其实是同一个虚拟设备在不同环节拦截、处理系统音频的结果。理解了设备就理解了全部功能。️ BGMDriver 与 BGMApp 双项目架构一览整个项目分成两个工程详见 DEVELOPING.md工程角色运行位置BGMDriverCore Audio HAL 插件创建虚拟设备并处理音频用户态coreaudiod进程BGMApp菜单栏 UI 应用把虚拟设备音频转发到真实扬声器用户态应用一句话概括BGMDriver 负责截住系统音频BGMApp 负责播放出来。两者之间通过 HAL 通知 XPC 通信共享代码则放在 SharedSource 目录。 为什么选择用户态 Core Audio HAL 插件很多同类虚拟音频工具走内核扩展路线需要重启系统才能加载而且一个 bug 就可能让系统崩溃。Background Music 选择了更现代的AudioServerPlugIn音频服务器插件方案好处很明显免重启插件被coreaudiod进程托管安装后只需重启音频服务更安全bug 顶多崩溃音频系统不会引发内核恐慌好调试用户态可用 Xcode 正常断点调试项目基于 Apple 官方 SimpleAudio 示例改造入口点定义在 BGM_PlugInInterface.cpp。 如何注册虚拟设备从 Info.plist 到对象模型一个 HAL 插件要注册进系统得先声明自己是合法插件。这一步靠 Info.plist 完成——它通过CFPlugInFactories把插件类型 UUID 指向工厂函数BGM_CreateCFPlugInFactories: C957AD43-DACA-... → BGM_Create当coreaudiod加载插件时会调用工厂函数 BGM_Create它返回一个实现了AudioServerPlugInDriverInterface的接口对象随后BGM_Initialize激活三个设备实例——主设备、UI 声音设备、Null 设备。真正让虚拟设备成型的是 Core Audio 的对象模型。每个对象插件、设备、流、控件都有唯一的AudioObjectID。Background Music 用一组固定 ID 把它们拼成一台完整设备定义在 BGM_Types.h对象 ID角色kObjectID_PlugIn插件根对象kObjectID_Device主虚拟设备kObjectID_Stream_Input输入流供录音kObjectID_Stream_Output输出流kObjectID_Volume_Output_Main音量控件kObjectID_Mute_Output_Main静音控件当 macOS 询问这台设备长什么样时BGM_Device便响应这些属性查询——于是它就和真实扬声器一样出现在「系统设置 声音」里了。 macOS 虚拟音频设备的数据流环形缓冲区如何工作虚拟设备最妙的地方是它实现了一个音频回环loopback。核心逻辑在 BGM_Device.cpp 的 IO 操作中每个 IO 周期 HAL 会按阶段回调WriteMix写入混合系统把所有 App 混好的声音交给插件插件把它存进环形缓冲区ReadInput读取输入需要录音时从缓冲区把声音读出当作麦克风输入ProcessOutput处理输出对每个 App 单独的数据应用独立音量并追踪现在是否有声音在播放这个环形缓冲区是整台虚拟设备的心脏——它让输出的声音能反过来变成输入从而同时实现系统音频的录制与转发。 正因为能看到每个 App 混音前的独立音频流Background Music 才能做到单独调某个 App 的音量。⚡ 实时线程音频驱动的时间红线音频驱动有一条铁律IO 函数必须在极短时间内返回一次都不能超时否则你会听到爆音或卡顿。所以 Background Music 的 IO 代码里不能动态分配内存耗时不可控不能拿可能被其他线程持有的互斥锁耗时操作要丢给 BGM_TaskQueue 派发到实时工作线程这也是它比一般 App 代码更讲究的地方。 安装 BGMDriver把虚拟设备种进 macOS开发阶段BGMDriver 会被打包成Background Music Device.driver安装到系统 HAL 插件目录/Library/Audio/Plug-Ins/HALquick_install.sh 会把它复制过去再重启coreaudiod让系统加载。装好后打开「系统设置 声音」你就能在输入/输出设备列表里看到Background Music了。小结Background Music 用一个用户态 Core Audio HAL 插件优雅地创建出 macOS 虚拟音频设备靠 Info.plist 声明插件身份工厂函数暴露给系统用固定的AudioObjectID对象模型拼出设备、流、音量控件用环形缓冲区打通输出 → 输入回环在每个 App 的独立音频流上做音量与状态处理从种进系统到流转音频整套机制既稳定又免重启——这正是现代 macOS 虚拟音频开发的最佳实践。【免费下载链接】BackgroundMusicBackground Music, a macOS audio utility: automatically pause your music, set individual apps volumes and record system audio.项目地址: https://gitcode.com/gh_mirrors/ba/BackgroundMusic创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考