用于创建版本3 AudioUnit的示例代码演示了实现如何返回用于渲染处理的功能块。该块将从前一个获取样本
通过pullInputBlock
在链中的AxudioUnit,并为输出缓冲区提供已处理的样本。它还必须提供一些输出缓冲区,如果链上的单元没有。以下是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
指定或获取最小值或强制它为特定值?
答案 0 :(得分:0)
在iOS下,音频单元回调必须能够处理变量frameCounts。你不能强迫它成为常数。
因此,任何需要固定大小缓冲区的处理都应在音频单元回调之外完成。您可以使用无锁循环缓冲区/ fifo或在回调中不需要内存管理的类似结构将数据传递到处理线程。
您可以通过使用AVAudioSession API设置缓冲区持续时间来建议frameCount为特定大小。但操作系统可以随意忽略这一点,具体取决于系统中的其他音频需求(省电模式,系统声音等)。根据我的经验,音频驱动程序只会增加您的建议尺寸,而不是减少它(超过一个如果重新采样不是2的幂,那么情侣样本。