Mac OS X 虚拟音频驱动程序

Posted

技术标签:

【中文标题】Mac OS X 虚拟音频驱动程序【英文标题】:Mac OS X virtual audio driver 【发布时间】:2013-08-28 21:54:35 【问题描述】:

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

我浏览了我能找到的大多数示例,但是它们仅实现了一项功能,即最多将输出 IOAudioStream 复制到输入。这意味着它仅在选择音频设备作为输出时才将音频转换为输入流。

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

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

【问题讨论】:

您是否设法实现了这样的事情?现在是 2020 年,仍然没有太多关于如何制作的信息 【参考方案1】:

看看开源的WavTap,它是开源的SoundFlower虚拟声卡驱动的一个简化分支。这是一个 .kext,我相信它基本上可以满足您的需求。

作为参考,以下是一些流行的商业闭源选项的工作原理:Rogue Amoeba 的 Audio Hijack Pro - 通过基于开源 SoundFlower .kext 的代码捕获系统音频 - 在启动应用程序时,通过用“补丁”框架替换正常的 CoreAudio.framework 来捕获应用程序的音频 - 在 Unsanity 的 haxie“应用程序增强器”(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 集团的Screenflick - 使用 SoundFlower .kext 捕获系统音频

更新 #1 在阅读了作者的 cmets 之后,似乎基本目标是能够捕获系统声音 将虚拟音频驱动程序作为设备发布(将出现在系统偏好设置的列表中)和 不改变当前的默认输出设备(或至少改变设备的外观)。

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 中找到实现此目的的示例,而且您也不太可能找到实现此目的的开源代码,除非有人感觉非常慷慨的。信息似乎太宝贵了。

【讨论】:

感谢您的回复,我明天会查看 WavTap 并让您知道它是否有效。显然我已经访问过 WavTap repo 链接,所以我认为它是一种可能的解决方案,但是我不记得为什么我认为它不是我需要的。 WavTap 与 SoundFlower 做同样的事情——因为您需要通过 WavTap 设备播放音频才能获得音频。我需要一个类似于 ScreenFlow 使用的虚拟驱动程序,它允许录制音频而无需选择其他设备。 +1 有关其他商业选项如何工作的信息,但这不是我需要的解决方案。 啊,现在我明白你想要完成什么了。我已经更新了我的答案,以阐明商业选项的工作原理。看起来 ScreenFlow 在这种能力方面是独一无二的,即使在其竞争对手中也是如此。 @UpL1nK 我添加了更多信息来尝试帮助您。您可能需要仔细阅读 CoreAudio API 邮件列表档案,尤其是较旧的档案(当 WireTap 和 Audio Hijack 刚进入市场时)。也许你能在那里找到一些东西。 我不能同意更新 1 和更新 2,一般都无法理解为什么 support.apple.com/en-us/HT202000 不适用。您是否能够创建一个使用内部音频输出作为输入并且可以被任何录音机完美使用的新主设备?!【参考方案2】:

经过进一步研究,以下是我想出的一些理论技术,可以帮助您实现目标:

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

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

【讨论】:

【参考方案3】:

适用于最新版本 MacOS 的较新的开源虚拟音频设备是 BlackHole - 它支持多个音频通道和采样率。

它可以用作音频接收器和/或源。作为聚合音频设备的一部分,它也很方便,因此可以听到音频并重新路由 - 例如使用 MacOS 音频 MIDI 设置应用程序

【讨论】:

以上是关于Mac OS X 虚拟音频驱动程序的主要内容,如果未能解决你的问题,请参考以下文章

Mac OS 桌面音频主机应用程序无法加载某些 AVAudioUnit 插件

如何在 Mac OS X 中检测是不是连接了蓝牙音频设备?

如何使用 Mac OS X 的音频 API 函数?

配置 Mac OS X AudioUnit 以提供 SignedInteger 示例

一个简单的 Mac OS X 声音应用程序

mac应用推荐——loopback