我正在为各种实时 FX 使用 Superpowered,它们都非常简单。然而,音高变化是另一回事,我认为事实上因为它基于时间拉伸算法,当然必须处理随时间变化的输出,这比应用 EQ 或混响等 FX 复杂得多。但是我只对改变我的麦克风输入的音高感兴趣。
我查看了在 GitHub 上可以找到的唯一示例,并对其进行了微调以适合我的工作:
static bool audioProcessing(void *clientdata,
float **buffers,
unsigned int inputChannels,
unsigned int outputChannels,
unsigned int numberOfSamples,
unsigned int samplerate,
uint64_t hostTime) {
__unsafe_unretained Superpowered *self = (__bridge Superpowered *)clientdata;
SuperpoweredAudiobufferlistElement inputBuffer;
inputBuffer.startSample = 0;
inputBuffer.samplesUsed = 0;
inputBuffer.endSample = self->timeStretcher->numberOfInputSamplesNeeded;
inputBuffer.buffers[0] = SuperpoweredAudiobufferPool::getBuffer(self->timeStretcher->numberOfInputSamplesNeeded * 8 + 64);
inputBuffer.buffers[1] = inputBuffer.buffers[2] = inputBuffer.buffers[3] = NULL;
self->outputBuffers->clear();
self->timeStretcher->process(&inputBuffer, self->outputBuffers);
int samples = self->timeStretcher->numberOfInputSamplesNeeded;
float *timeStretchedAudio = (float *)self->outputBuffers->nextSliceItem(&samples);
if (timeStretchedAudio != 0) {
SuperpoweredDeInterleave(timeStretchedAudio, buffers[0], buffers[1], numberOfSamples);
}
//self->outputBuffers->rewindSlice();
return true;
}
我已经删除了大部分我认为没有必要的代码。例如,有一个似乎处理时间拉伸场景的 while 循环,我只是输出与输入相同的时间。
一些观察:
- 如果我不这样做
clear
,outputBuffers
我的内存使用量就会飙升 - 如果我使用
self->outputBuffers->rewindSlice();
该应用程序变得静音,可能意味着缓冲区被静音覆盖 - 如果我不使用
self->outputBuffers->rewindSlice();
,我可以听到自己的声音回来,但timeStretchedAudio
总是0
第一次除外