使用哪种方法实时读取音频样本

Posted

技术标签:

【中文标题】使用哪种方法实时读取音频样本【英文标题】:Which approach to use for reading audio samples in real-time 【发布时间】:2016-01-19 02:54:43 【问题描述】:

对于一个特定的项目,我需要:

    从麦克风或音频文件中访问单个音频样本, 每 250 毫秒左右从这些值中提取一个属性,然后 在屏幕上实时显示该属性(最多延迟 100 毫秒)。

我研究了各种方法——Audio Units、Audio Graphs、AVAudioEngine、AudioTapProcessor——但不确定哪种方法适合仅针对 ios8 和 iOS9 的 Swift 项目。 AudioTapProcessor 适用于从音频文件访问音频样本,但不确定麦克风输入和 Swift 支持。

哪种方法最适合这些要求?感谢阅读。

更新:我选择了 AVAudioEngine,到目前为止它非常适合。

【问题讨论】:

您想要做的事情相当简单,所以我建议您查看 AudioQueue 服务文档。 【参考方案1】:

我相信具有 kAudioUnitSubType_RemoteIO 的单个音频组件的简约低级方法将在低延迟和 Swift 支持。假设 interface(为方便起见,此处命名)myAudioController 已正确声明和初始化,以下代码 inside 已注册 渲染回调 应该进行实时 I/O 映射(虽然这里是用 C 编写的):

myAudioController *myController = (myAudioController *)inRefCon;

//this would render inNumberFrames of data from audio input...
AudioUnitRender(myController->audioUnit,
                            ioActionFlags,
                            inTimeStamp,
                            bus1,
                            inNumberFrames,
                            ioData);

//from here on, individual samples can be monitored and processed...                           
AudioBuffer buffer = ioData->mBuffers[0]; 

Swift 中的等效代码 sn-p 可能如下所示:

let myController = UnsafeMutablePointer<myAudioController>(inRefCon).memory
AudioUnitRender(myController.audioUnit, 
                            ioActionFlags, 
                            inTimeStamp, 
                            bus1, 
                            inNumberFrames, 
                            ioData)

for buffer in UnsafeMutableAudioBufferListPointer(ioData)  ... 

有关详细信息,请随时查阅 Apple 的参考页面 - 文档非常详细: https://developer.apple.com/library/ios/documentation/AudioUnit/Reference/AUComponentServicesReference/#//apple_ref/c/func/AudioUnitRender

这也可能是一个有价值的网站,其中包含用 Swift 重写的必读教科书中的 C 示例:https://github.com/AlesTsurko/LearningCoreAudioWithSwift2.0

重要的是了解你在做什么。其他一切都应该是不言自明的,不应该涉及太多的工作。希望这可以帮助...

【讨论】:

【参考方案2】:

音频单元和图表将齐头并进。音频单元是组件,图形是将它们连接在一起的机制。使用单位和图表将为您提供最佳的实时(低延迟)性能和选项。我发现 Objective C 更适合核心音频,因为核心音频最初是一个 c api。

我最近回答了一个关于环形缓冲区的问题,并使用this project 作为演示。该项目在从麦克风录制时播放音调,并允许您通过读取戒指中的最新样本来进行处理。这可能是一个很好的起点。如果需要,您可以移除正在播放的音调。

【讨论】:

感谢您提供的示例项目链接。您是否选择了这种方法而不是 AUAudioEngine 来提高性能?

以上是关于使用哪种方法实时读取音频样本的主要内容,如果未能解决你的问题,请参考以下文章

AVAssetReader 读取音频,然后失败

用 dB 表示音乐音频样本? [复制]

PortAudio 用于连续输入流的实时音频处理

iOS 10.2 上的 Swift 3:如何从麦克风订阅单个样本?需要实时处理音频

如何实时读取/写入原始音频数据(使用python)?

在 matlab 中录制时处理音频样本