AudioUnit输出缓冲区和输入缓冲区

时间:2018-09-21 17:34:12

标签: core-audio audiounit audiotoolbox avaudioengine superpowered

我的问题是使用实时时间伸展时应该怎么做? 我了解速率的变化将改变输出样本的数量。 例如,如果我以2.0系数拉伸音频,则输出缓冲区更大(两倍)。

那么,如果我创建混响,延迟或实时时间拉伸,该怎么办?

例如,我的输入缓冲区是1024个样本。然后我以2.0系数拉伸音频。现在我的缓冲区是2048个样本。

在这段具有超强音频扩展能力的代码中,一切正常。但是,如果我不更改速率...当我更改速率时-听起来失真而没有实际更改速度。

return ^AUAudioUnitStatus(AudioUnitRenderActionFlags    *actionFlags,
                              const AudioTimeStamp      *timestamp,
                              AVAudioFrameCount         frameCount,
                              NSInteger             outputBusNumber,
                              AudioBufferList           *outputBufferListPtr,
                              const AURenderEvent       *realtimeEventListHead,
                              AURenderPullInputBlock        pullInputBlock ) {

        pullInputBlock(actionFlags, timestamp, frameCount, 0, renderABLCapture);

        Float32 *sampleDataInLeft = (Float32*) renderABLCapture->mBuffers[0].mData;
        Float32 *sampleDataInRight = (Float32*) renderABLCapture->mBuffers[1].mData;

        Float32 *sampleDataOutLeft  = (Float32*)outputBufferListPtr->mBuffers[0].mData;
        Float32 *sampleDataOutRight = (Float32*)outputBufferListPtr->mBuffers[1].mData;


        SuperpoweredAudiobufferlistElement inputBuffer;
        inputBuffer.samplePosition = 0;
        inputBuffer.startSample = 0;
        inputBuffer.samplesUsed = 0;
        inputBuffer.endSample = frameCount;
        inputBuffer.buffers[0] = SuperpoweredAudiobufferPool::getBuffer(frameCount * 8 + 64);
        inputBuffer.buffers[1] = inputBuffer.buffers[2] = inputBuffer.buffers[3] = NULL;

        SuperpoweredInterleave(sampleDataInLeft, sampleDataInRight, (Float32*)inputBuffer.buffers[0], frameCount);

        timeStretch->setRateAndPitchShift(1.0f, -2);
        timeStretch->setSampleRate(48000);
        timeStretch->process(&inputBuffer, outputBuffers);

        if (outputBuffers->makeSlice(0, outputBuffers->sampleLength)) {

            int numSamples = 0;
            int samplesOffset =0;

            while (true) {

                Float32 *timeStretchedAudio = (Float32 *)outputBuffers->nextSliceItem(&numSamples);
                if (!timeStretchedAudio) break;

                  SuperpoweredDeInterleave(timeStretchedAudio, sampleDataOutLeft + samplesOffset, sampleDataOutRight + samplesOffset, numSamples);

                samplesOffset += numSamples;

            };

            outputBuffers->clear();

        }

        return noErr;
    };

那么,当我的输入和输出缓冲区的采样数(混响,延迟或时间拉伸)不同时,如何创建音频单元渲染块?

1 个答案:

答案 0 :(得分:0)

如果您的进程创建的样本多于音频回调输入/输出缓冲区大小所提供的样本,则必须保存这些样本并在以后播放,如果有必要,可以在以后的音频单元回调中与后续输出混合使用。

通常使用循环缓冲区来分离输入,处理和输出采样率或缓冲区大小。