Yuji
Yuji

Reputation: 166

Processed audio very noisy when Superpowered Reverb used with Audio Graph

I'm using Superpowered Reverb effect with Audio Graph on OS X. I'm doing that by calling reverb->process in the render callback of an output audio unit (tested on kAudioUnitSubType_SystemOutput and kAudioUnitSubType_DefaultOutput).

The reverb effect worked but the resulted audio is very noisy. I've tried different things (adjust the samplerate, use extra and zeroed buffers, etc) but it doesn't seems to help. Are there any ways to solve this? Thx.

Simplified code:

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);
}

Upvotes: 2

Views: 234

Answers (1)

Yuji
Yuji

Reputation: 166

Turns out that in the audio graph, the callback will call multiple times even on the same channel, I made the following changes (using an integer to track current channel) and it work awesomely well now. (below is again simplified code)

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);
}

Upvotes: 1

Related Questions