复数N信号的IFFT - 输出:长度为2N的实信号

时间:2011-03-05 17:25:14

标签: audio performance signal-processing fft

在他们的书“数字信号处理”Proakis& Manolakis描述了一种使用长度为N的FFT计算长度为2N的实信号的FFT的方法。这基本上是通过将信号分成奇数和偶数部分来完成的。偶数部分是FFT实部的输入,奇数部分是虚数。两种信号都是使用有时被称为“两个价格为一个”http://www.engineeringproductivitytools.com/stuff/T0001/PT10.HTM

的技术从FFT输出中提取的。

之后,使用时间FFT抽取的最后阶段来计算频域中的信号。我已经实现了,我想我也理解了这种方法是如何工作的。但是,我以类似的方式陷入IFFT。

我有一个长度为2N的频域信号。由于它是真实信号的频域表示,因此其左侧和右侧是对称的。我现在想要使用信号的前半部分,并使用长度为N的IFFT来计算该信号的时域表示。昨晚我花了很多时间试图弄清楚它是如何工作的并试图实现它,但是我从来没有得到我应该得到的数字。我提到的页面是我发现的唯一来源,它模糊地解释了类似的东西应该如何工作,但这对理解它没有多大帮助。

为了将长度为2N的复杂对称频域信号转换为长度为2N的实时域表示,我需要做什么才能使用长度为N的IFFT?

2 个答案:

答案 0 :(得分:1)

实信号的FFT具有复共轭对称性。如果你的频域矢量与虚部的全零相对应,那么你可能正在寻找的是长度为N的IDCT形式,因为真实信号只有余数为N的余弦成分。

增加:

如果你有一个长度为2N的前向实数据FFT,你应该能够以相反的顺序进行计算步骤,反转每一步,将每一步后的数据与正向版本进行比较,找出你的错误。 (例如,如果在正向过程中使用长度为N的FFT,则在反向进行处理时,长度为N的IFFT应具有与原始FFT的输出和输入相同的输入和输出(减去数字舍入效果)如果没有,那就是你的错误。)

答案 1 :(得分:0)

如果有人和我有同样的问题,这里是我在C中的未经优化的源代码。希望我有时会抽出时间来补充一些解释。 (代码使用2 * n的信号作为实数,2 * n + 1作为虚部)注意,保持复杂频谱的数组需要长度为realInputSignal + 2才能保持DC偏移。但是,可以将最后一个实际值存储在第一个复数值的位置(因为它未使用),并且您不必将另外两个样本添加到数组中。但是,你的DFT也必须意识到这一点。

N = lData/2;

double X1R = 0.5*(outData[0] + outData[N*2]);
double X1I = 0.0;
double X2Ra = 0.5*(outData[0] - outData[N*2]);
double X2Ib =0.0;//

double wr = cos((double)0 * M_PI / (double)N);
double wi = -sin((double)0 * M_PI / (double)N);
double X2R = (X2Ra*wr + X2Ib*wi)/(wr*wr + wi*wi);
double X2I = (X2Ib*wr - X2Ra*wi)/(wr*wr + wi*wi);
outData2[0*2] = X1R - X2I;
outData2[0*2+1] = X1I + X2R;


for (int i=1; i<N; i++){

    double X1R = 0.5*(outData[i*2] + outData[N*2-2*i]);
    double X1I = 0.5*(outData[i*2+1] - outData[N*2-2*i+1]);
    double X2Ra = 0.5*(outData[i*2] - outData[N*2-2*i]);
    double X2Ib = 0.5*(outData[i*2+1] + outData[N*2-2*i+1]);
    double wr = cos((double)i * M_PI / (double)N);
    double wi = -sin((double)i * M_PI / (double)N);
    double X2R = (X2Ra*wr + X2Ib*wi)/(wr*wr + wi*wi);
    double X2I = (X2Ib*wr - X2Ra*wi)/(wr*wr + wi*wi);
    outData2[i*2] = X1R - X2I;
    outData2[i*2+1] = X1I + X2R;

}

ifft(outData2);