我正在尝试在macOS上“拦截”当前选定的输出音频设备,因此我基本上有一个通过监听器,可以监视当前正在输出的音频流而不影响它。 我希望实时将这些数据复制到环形缓冲区,以便我可以对其进行单独操作。 苹果文档和过时的SO答案的组合使我困惑,是否需要编写hacky内核扩展程序,可以利用CoreAudio进行此操作,还是需要与HAL接口? 如果可能的话,我想用Swift来工作。 非常感谢 (附:我一直在查看这个和这个)
我不了解内核扩展——它们使用特殊的“呼叫我们”签名证书或关闭SIP的必要性会阻碍非正式探索。但是,您可以使用CoreAudio和HAL AudioServer插件的组合来实现您想要的功能,而且您甚至不需要编写插件自己,有几个开源版本可供选择。CoreAudio没有提供一种从输出设备录制(或“窃听”)的方法——您只能从输入设备录制,因此解决此问题的方法是创建一个虚拟的“通过”设备(AudioServerPlugin),不与任何硬件相关联,将输出复制到输入,然后将该通过设备设置为默认输出并从其输入进行录制。我使用开源AudioServer插件如BackgroundMusic和BlackHole [TODO:添加更多]来完成这项工作。为了从生成的设备中录制音频,您可以简单地向其添加一个AudioDeviceIOProc回调,或将该设备设置为kAudioUnitSubType_HALOutputAudioUnit的kAudioOutputUnitProperty_CurrentDevice。上述虚拟直通设备方法存在两个问题:1. 您听不到输出声音,因为它被直通设备消耗掉了。 2. 更改默认输出设备将切换到您的设备,直通将变得无声。如果第一种方法是问题,则简单的解决方法是创建一个包含直通设备和实际输出设备(请参见截图)的多输出设备,并将其设置为默认输出设备。音量控件停止工作,但仍然可以在Audio MIDI Setup.app中更改实际输出设备的音量。对于第二个问题,您可以在默认输出设备上添加一个监听器,并在更改时更新上面的多输出设备。你可以使用Swift完成上述大部分操作,但是对于从缓冲区交付回调中存储环形缓冲区,你需要使用C或其他能够遵守实时音频规则(无锁,无内存分配等)的语言。你可以尝试使用AVAudioEngine来进行点击操作,但如果我没记错的话,更改输入设备会是一场痛苦的经历。