Выходной буфер 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 ответ
Если ваш процесс создает больше семплов, чем предусмотрено размером буфера ввода / вывода звукового обратного вызова, вы должны сохранить эти семплы и воспроизвести их позже, смешивая с последующим выводом в более позднем обратном вызове аудиоустройства, если это необходимо.
Часто циклические буферы используются для разделения входной, обрабатывающей и выходной частоты дискретизации или размеров буфера.