我对macOS编程比较陌生,但对一般编程不是。我宁愿使用(Objective)C / C ++而不是Swift。我需要打开一个特定的音频设备进行输出,并将音频数据的实时流从网络传输到输出设备。该设备具有一个自定义的音频服务器插件驱动程序,我们已为其提供源。尝试从Apple文档中找出执行这些操作需要调用的内容,我感到非常愚蠢。任何人都可以帮助回答以下问题:
1)用于执行此操作的适当的API有哪些?我以为我需要CoreAudio和AudioQueue,但是我对此一无所知。对类似示例应用的任何引用将不胜感激。推荐书也将不胜感激。
2)如何打开特定的自定义驱动程序进行输出?它是否与我在驱动程序代码中看到的UUID有关,还是通过其他方式识别了驱动程序?我需要我的程序来查找自定义驱动程序,而无需任何人工帮助,例如从选择列表中进行选择。
3)一个愚蠢的问题,因为我在所查看的应用程序示例中尚未看到清晰的示例:我下载了CAPlayThrough应用程序(https://developer.apple.com/library/archive/samplecode/CAPlayThrough/Introduction/Intro.html)并对其有所了解,但我不太理解。如何将我的“推送”内存数据从网络写入输出设备?我是否需要使用某种类型的回调,该回调从写入网络实时流的环形缓冲区读取?
附录:
3/24/2020根据进一步的研究,我已经回答了我的主要问题,但是仍然存在我认为超出范围的问题。我将在下面给出我的答案,并提出一个新问题。
1)可以使用哪些适当的API?
Core Audio API很好。请参见AudioDeviceCreateIOProcID
中的AudioDeviceStart
和CoreAudio/AudioHardware.h
。由于某种原因,Apple文档站点没有适用于他们的文档,因此您必须在头文件中找到它。
或者您可以使用AVAudioEngine
。 (但不是AVAudioEngine
。)
根据您的其他要求,使用GStreamer或VLC之类的现有程序可能会更容易。
对类似示例应用程序的任何引用将不胜感激。
AVAudioPlayer
可能是一个好的开始,但是它使用了CAPlayThrough
,已弃用。我不确定您是否需要它用来调节采样率差异的变速音频单元,但至少可以在没有它的情况下开始使用。
这看起来不使用AUGraph
也会执行类似的操作:AUGraph
如何打开特定的自定义驱动程序进行输出?
驱动程序将发布音频输出设备,它具有名为https://github.com/pje/WavTap/blob/master/App/AudioTee.cpp的属性(请参见kAudioDevicePropertyModelUID
。),并且应具有一个恒定值。您可以通过双击HALLab中的设备进行检查。
您的程序可以使用AudioHardwareBase.h
获取“音频系统对象”(AudioObjectGetPropertyData
)的kAudioHardwarePropertyDevices
属性,然后获取每个设备的kAudioObjectSystemObject
属性。
如果您使用的是C ++,则可能需要使用kAudioDevicePropertyModelUID
来帮助解决此问题。
与我在驱动程序代码中看到的UUID有什么关系,还是通过其他方式识别了驱动程序?
驱动程序由其捆绑软件ID标识。您可以将Public Utility classes属性用于代表驱动程序(即插件)的音频对象的kAudioHardwarePropertyPlugInForBundleID
。您也可以通过插件对象找到设备。
如何将我的“推送”内存数据从网络写入输出设备?我是否需要使用某种类型的回调,该回调从写入网络实时流的环形缓冲区读取?
传递给AudioObjectID
的函数将在每个IO周期被调用,并为该周期的样本填充一个缓冲区。
1)可以使用哪些适当的API?
我确定音频队列服务最适合我的需求。
2)如何打开特定的自定义驱动程序进行输出?
我发现我可以通过将AudioDeviceCreateIOProcID
函数与SetAudioQueueProperty
参数一起使用来设置所需的音频输出设备,如以下片段所示。
kAudioQueueProperty_CurrentDevice
3)如何将我的“推送”内存中数据从网络写入输出设备?
考虑AudioQueues的工作原理,看来我应该执行以下操作:将解码后的流音频发送到从输出AudioQueue回调中拉出的环形缓冲区。