iOS:音频处理所需的线程解决方案

时间:2011-12-06 09:21:39

标签: ios multithreading nsoperationqueue nsnotificationcenter

我在remoteIO渲染回调中监听麦克风。

我运行一个简单的算法来检测是否检测到声音信号。

如果是,我开始记录到缓冲区,直到再次沉默。

一旦再次检测到静音,我需要告诉我的应用程序有一个准备好处理的声音缓冲区。然后,应用程序将执行处理。

必须在不同的线程上完成! (无法阻止remoteIO渲染回调线程,它是一个实时线程,它会使系统断断续续。)

我天真地认为我可以从我的渲染回调中发送一个NSNotification,它会在另一个线程上被拾取。但这不会发生!它在SAME线程上执行。

实现这一目标的简洁方法是什么?

我的感觉是我应该产生一个单独的线程。即使在主线程上进行处理似乎也有点毛病......它也可能需要四分之一秒,这足以引起一些用户体验。

1 个答案:

答案 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更新等等!