版本 3 AudioUnits:internalRenderBlock 中的最小 frameCount
Posted
技术标签:
【中文标题】版本 3 AudioUnits:internalRenderBlock 中的最小 frameCount【英文标题】:Version 3 AudioUnits: minimum frameCount in internalRenderBlock 【发布时间】:2017-08-01 22:22:01 【问题描述】:创建版本 3 AudioUnit 的示例代码演示了实现需要如何返回一个功能块以进行渲染处理。该块都将从前一个中获取样本
AxudioUnit 通过pullInputBlock
在链中,并为输出缓冲区提供处理后的样本。如果更下游的单元没有,它还必须提供一些输出缓冲区。以下是 AudioUnit 子类的代码摘录:
- (AUInternalRenderBlock)internalRenderBlock
/*
Capture in locals to avoid ObjC member lookups.
*/
// Specify captured objects are mutable.
__block FilterDSPKernel *state = &_kernel;
__block BufferedInputBus *input = &_inputBus;
return Block_copy(^AUAudioUnitStatus(
AudioUnitRenderActionFlags *actionFlags,
const AudioTimeStamp *timestamp,
AVAudioFrameCount frameCount,
NSInteger outputBusNumber,
AudioBufferList *outputData,
const AURenderEvent *realtimeEventListHead,
AURenderPullInputBlock pullInputBlock)
...
);
如果处理不需要在调用此块之前知道frameCount
,这很好,但许多应用程序确实需要知道此块之前的frameCount
,以便分配内存、准备处理参数等。
解决此问题的一种方法是累积过去的输出缓冲区,每次调用块时仅输出 frameCount
样本,但这仅在已知最小值 frameCount
时才有效。必须使用大于此帧计数的大小初始化处理才能工作。有没有办法指定或获取frameCount
的最小值或强制它为特定值?
示例代码摘自:https://github.com/WildDylan/appleSample/blob/master/AudioUnitV3ExampleABasicAudioUnitExtensionandHostImplementation/FilterDemoFramework/FilterDemo.mm
【问题讨论】:
【参考方案1】:在 ios 下,音频单元回调必须能够处理可变的 frameCounts。你不能强迫它成为一个常数。
因此,任何需要固定大小缓冲区的处理都应在音频单元回调之外完成。您可以使用无锁循环缓冲区/fifo 或类似结构,在回调中不需要内存管理,将数据传递给处理线程。
您可以通过使用 AVAudioSession API 设置缓冲区持续时间来建议 frameCount 为特定大小。但是操作系统可以随意忽略这一点,具体取决于系统中的其他音频需求(省电模式、系统声音等)。根据我的经验,音频驱动程序只会增加您建议的大小,而不是减少它(超过如果重采样不是 2 的幂,则对样本进行耦合。
【讨论】:
感谢您为我指明了正确的方向,但我也对 OSX 感兴趣(我不知道不同操作系统的 API 如此不同)。知道在哪里为在 OSX 上运行的应用程序设置这个吗? 在我工作的时候把它放在这里:看起来 AUDeferredRenderer 可以帮助我。以上是关于版本 3 AudioUnits:internalRenderBlock 中的最小 frameCount的主要内容,如果未能解决你的问题,请参考以下文章
AudioUnits 和 MPMusicPlayerController