AudioUnit 输出缓冲区和输入缓冲区
AudioUnit output buffer and input buffer
我的问题是使用实时时间拉伸应该怎么办?
我知道速率的变化会改变输出样本的数量。
例如,如果我用 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;
};
那么,当我的输入和输出缓冲区具有不同数量的样本(混响、延迟或时间拉伸)时,我该如何创建我的音频单元渲染块?
如果您的进程创建的样本多于音频回调 input/output 缓冲区大小提供的样本,则您必须保存这些样本并稍后播放,如有必要,可在稍后的音频单元回调中与后续输出混合.
循环缓冲区通常用于解耦输入、处理和输出采样率或缓冲区大小。
我的问题是使用实时时间拉伸应该怎么办? 我知道速率的变化会改变输出样本的数量。 例如,如果我用 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;
};
那么,当我的输入和输出缓冲区具有不同数量的样本(混响、延迟或时间拉伸)时,我该如何创建我的音频单元渲染块?
如果您的进程创建的样本多于音频回调 input/output 缓冲区大小提供的样本,则您必须保存这些样本并稍后播放,如有必要,可在稍后的音频单元回调中与后续输出混合.
循环缓冲区通常用于解耦输入、处理和输出采样率或缓冲区大小。