Я сделал похожую вещь, «простой» ответ - я создаю очередь последовательной отправки, затем в обратном вызове рендеринга аудиоустройства я собираю данные и использую dispatch_async для передачи новых аудиоданных в последовательную очередь. Я использую вторичную очередь, поскольку аудиоустройства требуют, чтобы вы проводили как можно меньше времени в обратном вызове - также вы не должны выделять память или генерировать прерывания и тому подобное.
здесь 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 означает, что он выполняется в главном потоке, поэтому вы можете выполнять обновления пользовательского интерфейса и тому подобное!