c++ - "Garbled"在 VST 插件中使用 FFTW 的声音

标签 c++ fft fftw ifft vst

我对信号处理还是很陌生,我想创建一种使用 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 computes an unnormalized transform, in that there is no coefficient in front of the summation in the DFT. In other words, applying the forward and then the backward transform will multiply the input by 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++ - "Garbled"在 VST 插件中使用 FFTW 的声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39422564/

相关文章:

c++ - OpenCV 和 14/42 位

python - 使用scipy fft和ifft数值求解常微分方程

c - 使用 FFT 重复计算函数导数时产生的数值误差

fftw - 使用 FFTW 在 2D 矩阵上执行 N 个独立的 1D FFT

c++ - Halide FFT 实现错误?

c++ - 如何使用vc++代码获取系统唯一ID?

c++ - 虚拟基类是可行的和/或有用的功能吗

c++ - 在 C++ 中生成字母组合的函数问题

matlab - Matlab 傅里叶变换

python - 使用 scipy.fftpack 绘制的 fft 图中出现恒定线