Выходной буфер AudioUnit и входной буфер

Мой вопрос: что мне делать, когда я использую растяжку в реальном времени? Я понимаю, что изменение скорости изменит количество отсчетов для вывода. Например, если я растягиваю звук с коэффициентом 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 ответ

Решение

Если ваш процесс создает больше семплов, чем предусмотрено размером буфера ввода / вывода звукового обратного вызова, вы должны сохранить эти семплы и воспроизвести их позже, смешивая с последующим выводом в более позднем обратном вызове аудиоустройства, если это необходимо.

Часто циклические буферы используются для разделения входной, обрабатывающей и выходной частоты дискретизации или размеров буфера.

Другие вопросы по тегам