内核vs用户空间音频设备驱动程序在macOS



我需要为系统音频捕获开发一个音频设备驱动程序(基于Soundflower)。但是很快就出现了一个问题,ioaudioffamily堆栈似乎在OSX 10.10和更高版本中被弃用了。查看IOAudioDeviceIOAudioEngine头文件,似乎苹果现在推荐使用运行在用户空间的<CoreAudio/AudioServerPlugIn.h> API。但是我找不到很多关于这个用户空间设备驱动程序主题的信息。似乎唯一的资源是来自https://developer.apple.com/library/prerelease/content/samplecode/AudioDriverExamples/Introduction/Intro.html
的Apple提供的示例设备。通过这些示例,我发现开发一个用户空间驱动程序而不是基于I/O Kit内核的驱动程序要困难得多。那么问题来了,在用户空间而不是内核空间中开发设备驱动程序的动机是什么?

SimpleAudioDriver"例子有点命名不当。它几乎展示了API的每一个特性。如果您确实需要使用这些特性,这是一个方便的参考。它的结构也可能比必要的更复杂一些。

对于虚拟设备,NullAudioDriver可能是一个更好的基础,并且更容易理解(如果我没记错的话,是单个源文件)。SimpleAudioDriver在处理热插拔、相同设备的多个实例等问题时更有用。

如你所说,

IOAudioEngine已弃用,并且自OS X 10.10以来一直存在。预计它最终会消失,所以如果你用它来构建你的驱动程序,你可能需要重写它,而不是创建一个基于核心音频服务器插件的驱动程序。

测试和调试音频驱动程序都很尴尬(由于时间敏感),但我想说用户空间的处理稍微不那么令人沮丧。你仍然需要在不同的机器上进行测试,而不是在你的开发Mac上,因为如果coreaudiod崩溃或挂起,应用程序通常也会开始锁定,所以只需ssh登录,删除插件并杀死coreaudiod就很方便了。当然比重新启动要快。

(顺便说一下,我已经发布了内核和用户空间OS X音频驱动程序,我花了很多时间在kext上。)

macOS 12和13的更新:

macOS 12增加了对AudioDriverKit的支持,它本质上是围绕IOAudio…内核api的沙箱IPC包装。苹果说:

    这个API应该用于任何物理设备的音频驱动程序。
  1. 这个API应该不用于虚拟设备驱动程序,继续使用音频服务器插件。

关于系统音频捕获,macOS 13在(可能令人困惑的名称)ScreenCaptureKit中添加了对此的本地支持。除了流式显示内容(或单个窗口)外,还可以流式传输/记录系统音频,因此不需要自定义驱动程序。

关于这个主题有一本很棒的书,可以在这里免费获得:

http://free-electrons.com/doc/books/ldd3.pdf

请参阅第37页,了解为什么您可能需要一个用户空间驱动程序,为方便起见复制到这里:

用户空间驱动程序的优点是:

  • 完整的C库可以链接到。驱动程序可以执行许多奇特的任务,而无需求助于外部程序(实用程序)实现通常分布的使用策略的程序
  • 程序员可以在驱动程序代码上运行一个常规的调试器,而不必通过扭曲来调试正在运行的内核。
  • 如果一个用户空间驱动挂起,你可以简单地杀死它。驱动程序的问题不太可能挂起整个系统,除非硬件被控制是不礼貌的行为。
  • 用户内存是可交换的,不像内核内存。一个不经常使用的带有巨大驱动程序的设备不会占用其他程序可能占用的RAM 一个设计良好的驱动程序仍然可以像内核空间驱动程序一样,允许并发访问设备。
  • 如果您必须编写一个闭源驱动程序,用户空间选项使您更容易避免模棱两可的许可情况和更改内核接口的问题。

相关内容

最新更新