VST插件:如何在任意大小的音频输入缓冲区上使用FFT?

4

我对编写VST插件产生了兴趣,并且我具备基本的音频DSP和FFT知识。

我想使用VST.Net,我想知道如何实现基于FFT的效果。 代码如下:

public override void Process(VstAudioBuffer[] inChannels, VstAudioBuffer[] outChannels)

如果我没错的话,通常会对输入应用FFT,对FFT的数据进行一些处理,然后通过反向FFT创建处理后的声音缓冲区。

但由于FFT作用于指定的缓冲区大小,这个大小很可能与(任意的)输入/输出样本数量不同,你将如何处理此问题?

1个回答

4

FFT需要使用2的幂次方作为缓冲区大小,但是为了解决这个问题,您可以实现一个内部缓冲区并与其一起工作。例如:

// MyNiftyPlugin.h
#define MY_NUM_CHANNELS 2
#define MY_FFT_BUFFER_SIZE 1024

class MyNiftyPlugin : public AudioEffectX {
  // ... stuff ...
  private:
    float internalBuffer[MY_NUM_CHANNELS][MY_FFT_BUFFER_SIZE];
    long internalBufferIndex;
};

然后在您的处理循环中:

// MyNiftyPlugin.cpp
void process(float **input, float **output, long sampleFrames) {
  for(int frame = 0; frame < sampleFrames; ++frame) {
    for(int channel = 0; channel < MY_NUM_CHANNELS; ++channel) {
      internalBuffer[channel][internalBufferIndex] = inputs[channel][frame];
    }
    if(++internalBufferIndex > MY_FFT_BUFFER_SIZE) {
      doFftStuff(...);
      internalBufferIndex = 0;
    }
  }
}

这将会在你的插件中增加一些延迟,但是通过在编译时知道FFT缓冲区大小所能获得的性能提升是值得的。
此外,这也是针对像FL Studio(又名“Fruity Loops”)这样的宿主环境的一个不错的解决方案,因为该环境每次都会以不同的块大小调用process()。

啊,我刚刚才注意到你在用C#编程,但是我给你的是C++的示例代码。不过没关系,这里的算法非常简单,应该能让你大致明白我的意思。 - Nik Reiman
1
internalBufferIndex 应该被递增吗? - darius
1
我认为if块需要在for循环内部。 - sonofrage

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接