去除布莱克曼哈里斯窗口导致信号高于预期

信息处理 fft C++
2022-01-27 06:38:28

我们正在使用 PX14400 adc 捕获数据。样本是 16 位无符号整数,200M 样本/秒,仅 I 数据。100MHz 带宽。我们有一个 51MHz,-11.4dBm 的 cw 信号。-11.4dBm 由功率计测量,因此包括数字化之前的所有损耗。

问题 1:当我应用 blackman harris 4 term 窗口时,fft 数据计算为 -14dBm,这听起来很合理,因为 bh 损失约为 3dB,但是当我不应用窗口时,fft 数据计算为 -5.3dBm。我本来预计会有 3dB 的跳跃,而不是几乎 9。为什么会有很大的跳跃?

问题 2:下面的代码中是否有任何可能在我的计算中出现的问题。为简洁起见,并未显示所有代码(线程、板初始化等)。

// Initialzied elsewhere in the class
const int fftSize = 8192;         // size of the fft
complex<double> array[fftSize];   // array of complex (r+i)...used post fft
double dData[fftSize];            // array of doubles, used pre and post fft
fftPlan = fftw_plan_dft_r2c_1d(fftSize, dData, reinterpret_cast<fftw_complex*>(array), FFTW_ESTIMATE);

void processNewBuff(uint16_t *rawdata) {

        // convert the samples to V.  This formula is provided by the vendor
        // dData is an array containing the converted to V data (double)
        // rawdata is an array containing the initial adc counts
        // since we only fft the first 8192 values, we effectively throw out the rest of the data
        // we skip the rest of the 10ms sample (200MS/s * .01 = 2MB sample, 8192 is processed the rest is discarded
        double dInputRange = .220;
        for (int x=0; x<fftSize; x++) {
            dData[x] = (-dInputRange)/2 + ((rawdata[x]/65532) * dInputRange);
        }

        // apply blackmanHarris
//        double bhtmp;
//        for (int x=0; x<fftSize; x++) {
//            bhtmp = (double)(2 * 3.1415 * x / fftSize);
//            dData[x] *=(double)(0.35875 - (0.48829*cos(bhtmp)) + (0.14128 * cos(2*bhtmp)) - (0.01168*cos(3*bhtmp)));
//        }

        // do the fft.  fftPlan is a "fftw_plan_dft_r2c_1d", discreet fourier transform, real 2 complex
        // see: http://www.fftw.org/doc/Real_002ddata-DFTs.html
        // after the fft, we throw away the upper half of the fft since we only started with 'I' data
        fftw_execute(fftPlan);

        // normalize the fft for power
        for (unsigned int x = 0; x <(fftSize/2); x++)
            array[x] = array[x] / complex<double>(fftSize, 0);

        // convert the fft to power spectrum
        // I have this separated into 3 distinct lines for readability, final code will be all in a single line
        for (unsigned int x = 0; x <(fftSize/2); x++) {
                dData[x] = sqrt(real( array[x] * conj(array[x]) ));
                dData[x] = ((dData[x]) / 50) * 1000;     // convert to W, then mW
                dData[x] = (20 * log10(dData[x]));
        }
}
1个回答

原因是您没有正确规范化 DFT 样本。除以时域中的样本数仅对矩形窗口有效。对于 DFT 的简单情况,您应该将幅度除以窗口样本的总和:

S=i=0N1wi

这对于 Rectangular Window 显然等于),而对于 Blackman-Harris Window 它大约是,因此相干增益大约是而不是N819229390.361

要阅读有关这个​​有趣主题的更多信息,我向您推荐这些论文(尤其是第一篇):

G. Heinzel 等人- DFT 的频谱和频谱密度估计,包括窗口函数的综合列表和一些新的平顶窗口-特别是第 9 章

FJ Harris - 使用 Windows 进行离散傅里叶变换的谐波分析