为什么要在音频队列播放代码中调用CFRunLoopRunInMode()?

问题描述 投票:8回答:2

我是按照iOS《音频队列编程指南--播放音频》来做的。在指南的结尾处,有调用了 CFRunLoopRunInMode() 踏踏实实 启动和运行音频队列:

do {                                               // 5
    CFRunLoopRunInMode (                           // 6
        kCFRunLoopDefaultMode,                     // 7
        0.25,                                      // 8
        false                                      // 9
    );
} while (aqData.mIsRunning);
//...

关于第6行的文档中说:"CFRunLoopRunInMode函数运行包含音频队列的线程的运行循环。"但我的方法返回时,那个运行循环不是照样执行吗?上面的代码是在我的应用中按下播放按钮后由主线程执行的。

现在我很难理解这些对 CFRunLoopRunInMode() 是很好的,因为它们的缺点是我的播放按钮不能正确更新(在音频播放的整个过程中,它看起来是被按下的),而且没有积极的效果,也就是说,如果我把do-while-loop从我的代码中删除,同时也把对 CFRunLoopRunInMode() 而不是直接从这个方法中返回.好吧,这指向了一个明显的解决方案,即简单地保持这些调用被删除,因为这不会产生问题。谁能解释一下为什么这段代码会出现在苹果官方指南中关于在iOS中使用音频队列进行音频播放的内容?

编辑一下

我只是看到在Mac OS X中,存在着和iOS上一样的音频队列API,而iOS的指南似乎是复制粘贴的重复。Mac OS指南. 这让我怀疑这些对运行循环的调用只在Mac OS中需要,而在iOS中不再需要,例如,因为否则Mac OS应用程序将退出或类似的东西。谁能验证一下或者排除一下?

ios playback audioqueueservices cfrunloop
2个回答
2
投票

@bunnyhero说的没错。CFRunLoopRunInMode() 通常用于命令行示例

https:/github.comabboodLearning-Core-Audio-Book-Code-SampleblobmasterCH05_PlayerCH05_Playermain.c。

只要您的 AudioQueueRef 不被重新分配,您不必使用 CFRunLoopRunInMode() 在IOS...

我所做的是为音频队列创建一个单独的类,只要我的类指针和 AudioQueueRef 我可以播放、暂停、恢复、停止等。


0
投票

与OP的问题相关,关于AQ封锁UI线程的问题,为了进一步解放AQ用户,使其免于抄袭。所举的CoreAudio AQ例子 盲目地。

我要补充的是,该示例将AQ配置为在主线程中的当前运行循环中运行,即在 Listing 3-11 Creating a playback audio queue:

AudioQueueNewOutput (                                // 1
    &aqData.mDataFormat,                             // 2
    HandleOutputBuffer,                              // 3
    &aqData,                                         // 4
    CFRunLoopGetCurrent (),                          // 5
    kCFRunLoopCommonModes,                           // 6
    0,                                               // 7
    &aqData.mQueue                                   // 8
);

,见参数值 CFRunLoopGetCurrent () 以上。文中解释道

当前的运行循环,也是音频队列回放回调将被调用的循环。

从函数原型来看。

OSStatus AudioQueueNewOutput(
    const AudioStreamBasicDescription *inFormat,   // 2
    AudioQueueOutputCallback inCallbackProc,       // 3
    void *inUserData,                              // 4
    CFRunLoopRef inCallbackRunLoop,                // 5
    CFStringRef inCallbackRunLoopMode,             // 6
    UInt32 inFlags,                                // 7
    AudioQueueRef  _Nullable *outAQ                // 8
);

如果你把#5换成 NULL然后AQ将在CoreAudio内部线程中运行,使你的应用更有效率。

© www.soinside.com 2019 - 2024. All rights reserved.