如何捕获麦克风数据并将其路由到虚拟麦克风设备?



>最近,我想弄脏Core Audio,所以我开始开发一个简单的桌面应用程序,该应用程序将实时对麦克风数据应用效果(例如回声),然后处理后的数据可以在通信应用程序上使用(例如。Skype,Zoom等)。

为此,我认为我必须创建一个虚拟麦克风,以便能够通过通信应用程序发送处理后的(带有应用的效果)数据。例如,用户需要选择此新麦克风(虚拟)设备作为 Zoom 通话中的输入设备,以便通话中的其他用户可以在处理她的语音时听到她的声音。

我主要担心的是,我需要找到一种方法将从物理麦克风(例如内置麦克风)捕获的语音数据"路由"到虚拟麦克风。我花了一些时间阅读了 Adamson 和 Avira 的《学习核心音频》一书,在第 8 章中,作者解释了如何编写一个应用程序,a) 使用AUHAL从系统的默认输入设备捕获数据,b) 然后使用AUGraph将数据发送到系统的默认输出。因此,按照此示例,我认为我还需要创建一个仅在运行时捕获麦克风数据的应用程序。

所以,到目前为止我所做的:

  1. 我已经创建了虚拟麦克风,为此我遵循了Apple的NullAudio驱动程序示例。
  2. 我创建了捕获麦克风数据的应用程序。

对于上述两个"模块",我确信它们独立地按预期工作,因为我已经用各种方式测试了它们。现在唯一缺少的是如何将物理麦克风与虚拟麦克风"连接"。我需要将物理麦克风的输出与虚拟麦克风的输入连接起来。

所以,我的问题是:

  • 这是书中描述的使用AUGraph方法可以实现的微不足道的事情吗?我是否应该找到正确的方法来配置图形以实现两个设备之间的这种连接?
  • 我找到的唯一相关线程是这个,作者指出路由是由

通过套接字连接将此音频数据发送到驱动程序 因此,从虚拟麦克风请求音频的其他应用程序实际上从同时侦听麦克风的用户空间应用程序获取此音频(因此它应该处于活动状态)

但我不太确定如何开始实施这样的东西。

  • 我从麦克风捕获数据的整个过程似乎很长,我在想是否有更优化的方法。这本书似乎是2012年的,2014年做了一些更正。从那以后,Core Audio 是否发生了巨大变化,只需几行代码即可更轻松地实现此过程?

我认为通过搜索术语"通关"而不是"路由"会得到更多结果。

Adamson/Avila书有一个理想的通过示例,不幸的是,只有当输入和输出由同一设备处理时(例如,大多数Mac笔记本电脑和iPhone/iPad设备上的内置硬件),您才有效。

请注意,还有另一个称为"playthru"的音频设备概念(请参阅kAudioDevicePropertyPlayThru和相关属性),它似乎是单个设备内部路由的一种形式。我希望它是一个允许您设置转发设备的属性,但唉,没有。 关于这一点的一些非正式文件:https://lists.apple.com/archives/coreaudio-api/2005/Aug/msg00250.html

我从未尝试过,但您应该能够在这样的AUGraph上将输入连接到输出。 但是,AUGraph已被弃用,以支持上次我检查时没有很好地处理非默认输入/输出设备的AVAudioEngine

相反,我通过环形缓冲区手动将缓冲区从输入设备复制到输出设备(TPCircularBuffer效果很好)。魔鬼在细节中,大部分工作都在决定你想要什么属性及其后果。一些常见和冲突的示例属性:

  1. 最小延迟
  2. 最小辍学
  3. 无时间失真

就我而言,如果输出落后于输入太多,我会残酷地转储 1 或 2 个缓冲区的所有内容。有一些过时的Apple示例代码称为CAPlayThrough,它可以优雅地加快输出流。你绝对应该检查一下。

如果你找到更简单的方法,请告诉我!

更新
我找到了更简单的方法:

  1. 创建从麦克风捕获的AVCaptureSession
  2. 添加引用虚拟设备的AVCaptureAudioPreviewOutput

从麦克风路由到耳机时,听起来好像有几百毫秒的延迟,但如果AVCaptureAudioPreviewOutput和您的虚拟设备正确处理时间戳,那么这种延迟可能无关紧要。

最新更新