【问题标题】:Get macOS Output Device Audio Buffers in Realtime实时获取 macOS 输出设备音频缓冲区
【发布时间】:2021-03-25 02:21:14
【问题描述】:

我正在尝试在 macOS 上点击当前选择的输出音频设备,所以我基本上有一个直通监听器,可以监视当前正在输出的音频流而不影响它。

我想将这些数据实时复制到环形缓冲区,以便单独对其进行操作。

Apple 文档和(过时?)SO 答案的组合令人困惑,我是否需要编写一个 hacky 内核扩展,可以为此使用 CoreAudio,还是需要与 HAL 交互?

如果可能的话,我想在 Swift 中工作。

非常感谢

(ps.我一直在看thisthis

【问题讨论】:

    标签: objective-c swift macos audio core-audio


    【解决方案1】:

    我不了解内核扩展——它们使用特殊的“呼叫我们”签名证书或关闭 SIP 的必要性阻碍了随意探索。

    但是你可以结合使用 CoreAudio 和 HAL AudioServer 插件来做你想做的事,而且你甚至不需要自己编写插件,有几个开源版本可供选择。

    CoreAudio 不提供从(或“点击”)输出设备录制的方法 - 您只能从输入设备录制,因此解决此问题的方法是创建一个虚拟“直通”设备(AudioServerPlugin ),与任何硬件无关,将输出复制到输入,然后将此传递设备设置为默认输出并从其输入记录。我已经使用开源 AudioServer 插件完成了这项工作,例如 BackgroundMusicBlackHole [TODO: add more]。

    要从生成的设备点击/录制,您只需向其添加AudioDeviceIOProc 回调或将设备设置为kAudioUnitSubType_HALOutput AudioUnitkAudioOutputUnitProperty_CurrentDevice

    上述虚拟直通设备方式存在两个问题:

    1. 您再也听不到输出了,因为它正在被直通设备消耗
    2. 更改默认输出设备将离开您的设备,并且点击将静音。

    如果 1. 有问题,那么一个简单的方法是创建一个包含直通设备和一个真实输出设备的多输出设备(参见屏幕截图)并将其设置为默认输出设备。音量控制停止工作,但您仍然可以在Audio MIDI Setup.app 中更改实际输出设备的音量。

    对于2.你可以给默认输出设备添加一个监听器,当它改变时更新上面的多输出设备。

    您可以在 swift 中完成上述大部分操作,但对于从缓冲区传递回调中进行环形缓冲区存储,您必须使用 C 或其他可以respect the realtime audio rules 的语言(无锁、无内存分配等)。您可以尝试AVAudioEngine 进行点击,但IIRC 更改输入设备是vale of tears

    【讨论】:

    • 这是一个非常全面的概述,谢谢。这个怎么样: 1.在程序启动时,我检测到当前的默认输出设备。 2. 以编程方式将当前默认输出设备更改为虚拟 AU,它只是原始默认输出设备的代理。 3. 将侦听器绑定到输出设备更改事件并更改代理委托给的内容 4. 在程序运行时(无论何时更改)始终强制输出设备成为代理。我的另一种选择是使用 Blackhole 并让用户选择特定应用程序作为音频源,例如 Spotify 或 Skype 等?
    • 没错。您确定 blackhole 可以重新路由来自单个应用程序的音频吗?这听起来更像是 RA 的环回。
    • 是的,公平点,我已经安装了 Loopback,所以我把这两者混为一谈了!
    • 如果您有环回,则将其设备配置为只有一个来源:应用程序,然后使用答案中的方法从设备进行记录。我没有在答案中提到环回。我相信它使用了完全不同的方法。
    • 是的,我不能在解决方案中使用 Loopback 的原因主要是我想将这个应用程序分发给其他用户,并且不能保证他们会有 Loopback 或设置它的知识。我仍在考虑你写的东西,因为我认为使用多输出设备会有一个很好的折衷
    猜你喜欢
    • 1970-01-01
    • 2011-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-24
    • 2014-11-14
    相关资源
    最近更新 更多