当Superpowered Reverb与Audio Graph一起使用时,处理后的音频非常嘈杂

时间:2017-07-19 22:03:18

标签: macos core-audio objective-c++ audiounit superpowered

我在OS X上使用Superpowered Reverb效果和Audio Graph。 我是通过在输出音频单元的渲染回调中调用reverb->process(在kAudioUnitSubType_SystemOutputkAudioUnitSubType_DefaultOutput上测试)来实现的。

混响效果有效但产生的音频非常嘈杂。我尝试了不同的东西(调整采样率,使用额外和零点缓冲区等),但它似乎没有帮助。有什么方法可以解决这个问题吗? THX。

简化代码:

SuperpoweredReverb* reverb;

OSStatus callback(void * inComponentStorage,
                  AudioUnitRenderActionFlags * __nullable flags,
                  const AudioTimeStamp * inTimeStamp,
                  UInt32 busNumber,
                  UInt32 framesCount,
                  AudioBufferList * ioData)
{
    for (int i = 0; i < ioData->mNumberBuffers; ++i)
    {
        if (ioData->mBuffers[i].mData)
            reverb->process(static_cast<float*>(ioData->mBuffers[i].mData),
                            static_cast<float*>(ioData->mBuffers[i].mData),
                            framesCount);
    }

    return noErr;
}

void setupReverb(unsigned int sampleRate, AudioUnit unit)
{
    reverb = new SuperpoweredReverb(sampleRate);
    reverb->enable(true);
    reverb->setMix(0.5);
    AudioUnitAddRenderNotify(unit, callback, nullptr);
}

1 个答案:

答案 0 :(得分:1)

事实证明,在音频图中,即使在同一个频道上,回调也会多次调用,我做了以下更改(使用整数来跟踪当前频道),现在它的工作效果非常好。 (下面再次简化代码)

SuperpoweredReverb* reverbUnit;
int spliter = 0;

OSStatus callback(void * inComponentStorage,
                  AudioUnitRenderActionFlags * __nullable flags,
                  const AudioTimeStamp * inTimeStamp,
                  UInt32 busNumber,
                  UInt32 framesCount,
                  AudioBufferList * ioData)
{
    spliter++;
    for (int i = 0; i < ioData->mNumberBuffers; ++i)
    {
        if (ioData->mBuffers[i].mData) {
            if (!(spliter % ioData->mBuffers[i].mNumberChannels))
                reverbUnit->process(static_cast<float*>(ioData->mBuffers[i].mData),
                                    static_cast<float*>(ioData->mBuffers[i].mData),
                                    framesCount);
        }
    }

    return noErr;
}

void setupReverb(unsigned int sampleRate, AudioUnit unit)
{
    reverbUnit = new SuperpoweredReverb(sampleRate);
    reverbUnit->enable(true);
    reverbUnit->setWet(0.7);
    AudioUnitAddRenderNotify(unit, callback, nullptr);
}