Mac OS X虚拟音频驱动程序

时间:2013-08-26 12:02:44

标签: macos audio kernel driver

我想创建一个虚拟音频设备,从默认输出(输出IOAudioStream)获取音频数据,并将其转换为输入IOAudioStream。

我浏览了大部分可以找到的示例,但是它们只实现了一个功能,可以将输出IOAudioStream最多复制到输入端。这意味着如果选择音频设备作为输出,它只会将音频转换为输入流。

这应该是可行的,因为ScreenFlow允许通过安装创建虚拟驱动程序的kext来记录计算机音频。

如何从默认输出中访问音频数据并将其发送到我的虚拟驱动程序?

2 个答案:

答案 0 :(得分:46)

看一下开源WavTap,它是开源SoundFlower虚拟声卡驱动程序的简化分支。这是一个.kext,我相信它实际上是你想要的。

供参考,以下是一些流行的商业闭源选项如何工作:
Rogue Amoeba的Audio Hijack Pro
- 通过基于开源SoundFlower .kext的代码捕获系统音频 - 在启动应用程序时,通过将“补丁”框架替换为正常的CoreAudio.framework来捕获应用程序的音频 - 借助来自Unsanity的haxie“Application Enhancer”(APE)帮助暂停已经运行的应用程序的音频

这些功能被标记为“Instant On”功能(InstantOn.kext)。

Ambrosia Software的WireTap Studio
- 通过内部开发的.kext

捕获系统音频和应用程序音频

Telestream的ScreenFlow
- 通过in-house developed .kext.捕获系统音频(版本2.x使用varaudio.kext;版本3.x使用TelestreamAudio.kext)

Macsome的Audio Recorder
- 未知方法

Araelium Group的Screenflick
- 使用SoundFlower .kext

捕获系统音频

更新#1
在阅读了作者的评论之后,看起来基本目标是能够捕获系统声音而不将虚拟音频驱动程序发布为设备(将出现在系统首选项列表中)和没有更改当前的默认输出设备(或至少是设备已更改的外观)。

SoundFlower:安装时将声音设备添加到列表中 WavTap:安装时将声音设备添加到列表中;启动WavTap应用程序时自动选择设备;应用程序关闭时自动取消选择设备并重新选择以前的设备
Audio Hijack Pro:仅在选择默认系统声音的音频捕获时添加声音设备;在不再选择音频捕获时删除声音设备并重新选择以前的设备
WireTap Studio:未知
ScreenFlow:在不更改当前默认输出设备且不将虚拟音频驱动程序发布为设备的情况下捕获系统声音

更新#2
CoreAudio Apple工程师Jeff Moore引用了WireTap和Audio Hijack Pro等应用程序的引用: “系统上没有API可以为您提供任何特定应用程序的输出或整个组合输出到硬件...系统不支持[捕获系统声音],那些人必须是没有什么可以阻止你做同样的事情,除非你愿意弄脏你的手。 事实上,Mac OS X的音频系统首先是为性能而设计的。这导致我们的设计不容易支持您想要的功能而不会造成性能损失。因此,我们选择了更好的性能,代价是无法提供此功能。“

如果您想了解有关该主题的更多信息,请查看CoreAudio API邮件列表中的这些主题:
"WireTap, CoreAudio's API, and system capture, and kexts..."
"Another question on capturing audio played back by a software"
"Capturing currently played audio using CoreAudio on Mac"
"'audio hijack'"
"monitoring system audio output like wire tap"
"Capturing audio output to a file"
"Mirroring Audio Output"
"Recording system audio"

相关的SO问题:
Hide Audio device using codeless kext

长话短说,你不太可能找到Apple实现这一目标的例子,你也不太可能找到能够实现这一目标的开源代码,除非有人感觉非常慷慨。它似乎太有价值了。

答案 1 :(得分:8)

经过进一步的研究,我提出了一些可以让你实现目标的理论技巧:

  1. 与Prosoft Engineering的Hear产品类似,您可以创建HAL插件(用户模式虚拟驱动程序)而不是.kext(内核模式虚拟驱动程序)。 Apple有一个名为"SampleHardwarePlugIn"的示例HAL插件,PulseAudio也有一个。但是,根据他的方法,我认为您无法访问预混合系统声音流。您必须从各种应用程序(必须使用CoreAudio播放声音)中收集所有流,并将它们混合在一起以进行伪系统声音捕获。

  2. 从用户互动中创建隐藏[1] [2]的虚拟音频设备。当用户希望捕获包含隐藏虚拟设备和当前默认声音设备的默认声音programmatically create an aggregate device时。暂时将此聚合设备设置为默认输出。通过这种方式,您可以捕获默认声音并听到它 附注:如果Mac OS X允许将隐藏设备也设置为默认输出设备,那么系统偏好设备将显示为所选设备?如果它将辅助输出设备显示为已选中,那么您会添加一些暗示,即没有任何更改。