我在remoteIO渲染回调中监听麦克风。
我运行一个简单的算法来检测是否检测到声音信号。
如果是,我开始记录到缓冲区,直到再次沉默。
一旦再次检测到静音,我需要告诉我的应用程序有一个准备好处理的声音缓冲区。然后,应用程序将执行处理。
必须在不同的线程上完成! (无法阻止remoteIO渲染回调线程,它是一个实时线程,它会使系统断断续续。)
我天真地认为我可以从我的渲染回调中发送一个NSNotification,它会在另一个线程上被拾取。但这不会发生!它在SAME线程上执行。
实现这一目标的简洁方法是什么?
我的感觉是我应该产生一个单独的线程。即使在主线程上进行处理似乎也有点毛病......它也可能需要四分之一秒,这足以引起一些用户体验。
答案 0 :(得分:2)
我做了类似的事情,'简单'的答案是我创建了一个串行调度队列,然后在音频单元渲染回调中我抓取数据并使用dispatch_async将新的音频数据传递给串行队列。我使用辅助队列,因为音频单元要求你在回调中花费尽可能少的时间 - 你也不应该使用malloc内存或生成中断等。
这里lockData和unlockData抓取预先分配的NSMutableData对象,然后存储在一个锁定/未锁定的数组中。
//在你的init方法中
self.captureQueue = dispatch_queue_create("AudioCaptureQueue", NULL);
渲染回调中的:
__block NSMutableData * audiodata = [audioIO lockData];
status = AudioUnitRender(audioIO.audioUnit,
ioActionFlags,
inTimeStamp,
inBusNumber,
inNumberFrames,
&auBufferList);
dispatch_async(audioIO.captureQueue, ^{
[audioIO.sampleCaptureDelegate audioComponent:audioIO
hasSampleBuffer:audiodata];
[audioIO unlockData:audiodata];
});
在串行队列中,我对音频数据进行了所有数据处理,然后当串行队列检测到它寻找的东西时可以使用
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:kAPPAudioQueueDidDetect
object:nil];
});
dispatch_get_main_queue表示它在主线程上执行,因此您可以进行UI更新等等!