AudioUnit inputCallback 与 AudioUnitRender -> audioBufferList.mBuffers[0].mDataByteSize 之间不匹配!= in

Posted

技术标签:

【中文标题】AudioUnit inputCallback 与 AudioUnitRender -> audioBufferList.mBuffers[0].mDataByteSize 之间不匹配!= inNumberFrames【英文标题】:AudioUnit inputCallback with AudioUnitRender -> mismatch between audioBufferList.mBuffers[0].mDataByteSize != inNumberFrames 【发布时间】:2019-09-09 10:40:39 【问题描述】:

我们正在使用 AudioUnits 输入回调来处理传入缓冲区。音频单元设置主要来自

https://github.com/robovm/apple-ios-samples/blob/master/aurioTouch/Classes/AudioController.mm

我在音频回调中添加了一些健全性检查。看起来是这样的

/// The audio input callback
static OSStatus audioInputCallback(void __unused *inRefCon,
                                   AudioUnitRenderActionFlags *ioActionFlags,
                                   const AudioTimeStamp *inTimeStamp,
                                   UInt32  __unused inBusNumber,
                                   UInt32 inNumberFrames,
                                   AudioBufferList __unused *ioData)

    OSStatus err = noErr;
    if(!*callbackData.audioChainIsBeingReconstructed)
    
        // we are calling AudioUnitRender on the input bus of AURemoteIO
        // this will store the audio data captured by the microphone in cd.audioBufferList
        err = AudioUnitRender(callbackData.audioUnit, ioActionFlags, inTimeStamp, kInputBus, inNumberFrames, &callbackData.audioBufferList);

        // check if the sample count is set correctly
        assert(callbackData.audioBufferList.mBuffers[0].mDataByteSize == inNumberFrames * sizeof(float));
        // Assert that we only received one buffer
        assert(callbackData.audioBufferList.mNumberBuffers == 1);

        // Copy buffer
        TPCircularBufferCopyAudioBufferList(callbackData.buffer, &callbackData.audioBufferList, inTimeStamp, kTPCircularBufferCopyAll, NULL);

    
    return err;

现在有时语句 assert(callbackData.audioBufferList.mBuffers[0].mDataByteSize == inNumberFrames * sizeof(float)); 会失败,因为缓冲区不同。

有人对这种现象有解释吗?

【问题讨论】:

【参考方案1】:

这是 iOS 上的正常行为。 iOS 音频单元回调可以更改缓冲区大小中提供的帧数,使其与原始缓冲区大小不同。当操作系统状态发生变化、音频硬件状态发生变化或可用的硬件格式与您的音频格式请求不完全匹配时,就会发生这种情况。

因此,必须编写所有音频单元回调来处理来自请求值或先前回调值的可变数量的 inNumberFrames。

【讨论】:

所以我认为inNumberFrames 只是一个指示实际请求了多少帧的指标。音频缓冲区大小是真正生成的帧吗? 这是否意味着样本的真实值在audioBufferList.mBuffers[0].mDataByteSize内部

以上是关于AudioUnit inputCallback 与 AudioUnitRender -> audioBufferList.mBuffers[0].mDataByteSize 之间不匹配!= in的主要内容,如果未能解决你的问题,请参考以下文章

将 AudioUnit 回调与 NSOutputStream 同步

混音器 AudioUnit 到 RemoteIO AudioUnit

AudioUnit - 在 Swift 中控制左声道和右声道输出

AudioUnit播放PCM问题

在 AudioUnit 播放回调中从 AudioBuffer->mdata 播放音频

AudioUnit:从 CocoaView 访问 ComponentKernel 属性