首页 > 解决方案 > 没有输出缓冲区时的 AudioUnit 噪声

问题描述

我正在尝试实现通过套接字播放从远程服务器接收到的 pcm 音频。这是我之前的问题链接。这很好用,因为我使用循环缓冲区始终输入传入缓冲区。

但是我有一个问题,如果我没有为我的输出提供缓冲区,则会产生巨大的噪音。当我开始使用 AudioOutputUnitStart(_audioUnit) 并且没有缓冲区可以播放时,就会发生这种情况。

我怀疑我必须在下面的 OutputRenderCallback 函数中解决这个问题,或者可能还有其他事情需要做:

static OSStatus OutputRenderCallback(void                        *inRefCon,
                                     AudioUnitRenderActionFlags  *ioActionFlags,
                                     const AudioTimeStamp        *inTimeStamp,
                                     UInt32                      inBusNumber,
                                     UInt32                      inNumberFrames,
                                     AudioBufferList             *ioData){


    Test *output = (__bridge Test*)inRefCon;


    TPCircularBuffer *circularBuffer = [output outputShouldUseCircularBuffer];
    if( !circularBuffer ){
        SInt32 *left  = (SInt32*)ioData->mBuffers[0].mData;
        for(int i = 0; i < inNumberFrames; i++ ){
            left[  i ] = 0.0f;
        }
        return noErr;
    };

    int32_t bytesToCopy = ioData->mBuffers[0].mDataByteSize;
    SInt16* outputBuffer = ioData->mBuffers[0].mData;

    uint32_t availableBytes;
    SInt16 *sourceBuffer = TPCircularBufferTail(circularBuffer, &availableBytes);

    int32_t amount = MIN(bytesToCopy,availableBytes);
    memcpy(outputBuffer, sourceBuffer, amount);

    TPCircularBufferConsume(circularBuffer,amount);

    return noErr;
}

我非常感谢你的帮助。谢谢。

标签: iosmacosaudiounitcircular-buffer

解决方案


音频单元回调要求您始终将请求数量的样本放入 AudioBufferList 缓冲区。如果数量(来自可用的循环缓冲区)较少,则您的代码不会这样做。

所以总是在输出缓冲区中放入一些东西,就像你的代码在没有循环缓冲区时所做的那样。

顺便说一句:调用方法:

[output outputShouldUseCircularBuffer]

回调内部违反了 Apple 的实时音频规则。


推荐阅读