2017-08-01 43 views
0

创建第3版AudioUnit的示例代码演示了实现如何返回用于渲染处理的功能块。该块将通过pullInputBlock从链中的前一个 AxudioUnit中获取样本,并向输出缓冲区提供处理后的样本。如果单位下游的单位没有,它也必须提供一些输出缓冲区。下面是代码的AudioUnit子类的摘录:版本3 AudioUnits:internalRenderBlock中的最小frameCount

- (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

回答

0

在iOS的,音频单元回调必须能够处理可变frameCounts。你不能强迫它成为一个常量。

因此,任何需要固定大小缓冲区的处理都应该在音频单元回调之外完成。您可以通过使用无锁循环缓冲区/ fifo或类似的结构将数据传递到处理线程,该结构不需要回调中的内存管理。

通过使用AVAudioSession API设置缓冲区持续时间,可以建议frameCount为特定大小。但是操作系统可以自由地忽略这一点,这取决于系统中的其他音频需求(省电模式,系统声音等)。根据我的经验,音频驱动程序只会增加您的建议尺寸,而不会降低它(超过如果重采样不是2的幂,则将样本耦合)。

+0

感谢您指出我正确的方向,但我也对OSX感兴趣(我不知道这些API对于不同的操作系统来说是如此不同)。任何想法为OSX上运行的应用程序设置此位置? – mondaugen

+0

只需将它放在这里,我就可以了:看起来AUDeferredRenderer可以帮助我。 – mondaugen