我对信号处理还很陌生,我想使用FFTW创建一种示例VST插件(因为我在Rosetta Code上发现的FFT和IFFT似乎运行得太慢),但没有(但毫无用处)适用对每个输入样本进行FFT,然后将IFFT应用于其结果。目的是取回原始声音,但输出(由于缺乏更好的术语来描述声音的质量)似乎是“乱码”。这是processReplacing函数的代码:

void VST_Testing::VST_Testing::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames) {
    resume();
    time = 0;
    float *in1 = inputs[0];
    float *in2 = inputs[1];
    float *out1 = outputs[0]; //L
    float *out2 = outputs[1]; //R
    float *out3 = outputs[2]; //C
    float *out4 = outputs[3]; //RL
    float *out5 = outputs[4]; //RR
    VstInt32 initialFrames = sampleFrames;
    fftw_complex* left = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*sampleFrames);
    fftw_complex* right = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*sampleFrames);
    int i = 0;
    while (--sampleFrames >= 0)
    {
        left[i][0] = *in1++;
        left[i][1] = 0;
        right[i][0] = *in2++;
        left[i][1] = 0;
        i++;
    }
    sampleFrames = initialFrames;

    fftw_complex* l_out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*sampleFrames);
    fftw_complex* r_out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*sampleFrames);

    fftw_plan p_l = fftw_plan_dft_1d(sampleFrames, left, l_out, FFTW_FORWARD, FFTW_MEASURE);
    fftw_plan p_r = fftw_plan_dft_1d(sampleFrames, right, r_out, FFTW_FORWARD, FFTW_MEASURE);

    fftw_execute(p_l);
    fftw_execute(p_r);

    fftw_destroy_plan(p_l);
    fftw_destroy_plan(p_r);

    p_l = fftw_plan_dft_1d(sampleFrames, l_out, left, FFTW_BACKWARD, FFTW_MEASURE);
    p_r = fftw_plan_dft_1d(sampleFrames, r_out, right, FFTW_BACKWARD, FFTW_MEASURE);

    fftw_execute(p_l);
    fftw_execute(p_r);
    i = 0;
    while (--sampleFrames >= 0)
    {
        (*out3++) = 0.5*left[i][0] + 0.5*right[i][0];
        (*out4++) = left[i][0];
        (*out5++) = right[i][0];
        i++;
    }

    fftw_destroy_plan(p_l);
    fftw_destroy_plan(p_r);

    fftw_free(left);
    fftw_free(right);
    fftw_free(l_out);
    fftw_free(r_out);
    }
}


我的期望是,我会从in1in2(预期用途中的左和右输入)输入获得的信号几乎完全相同地返回到out4out5(预期用途中的左后和右后输出) )。我是否在代码中犯了错误,或者我对FFTW的行为期望不正确?

最佳答案

显然,此问题是由FFTW计算未归一化的变换以及复制和粘贴错误引起的。从“ What FFTW really computes”开始


  FFTW计算未归一化的变换,因为DFT中的求和前面没有系数。换句话说,应用前向然后向后的转换会将输入乘以n。


解决此问题的方法是将信号除以initialFrames以便标准化:

while (--sampleFrames >= 0)
{
    (*out3++) = 0.5*(left[i][0]/initialFrames) + 0.5*(right[i][0]/initialFrames);
    (*out4++) = left[i][0]/initialFrames;
    (*out5++) = right[i][0]/initialFrames;
    i++;
}

关于c++ - 在VST插件中使用FFTW发出“刺耳”的声音,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39422564/

10-11 15:22