因此,我试图编写一个频域内插器,将信号的频率响应零填充并进行逆变换。我必须处理两种情况:


均匀长度的响应-必须拆分$ F_s / 2 $ bin,因为它模棱两可。因此,我复制了频谱的负部分,并在其中添加了n*(interp-1)-1零。 br />
执行零填充的代码可以在这里看到

// Copy negative frequency components to end of buffer and zero out middle
//  inp    - input buffer of complex floats
//    n    - transform size
//  interp - interpolation amount
void zero_pad_freq(cfloat_t *inp, size_t n, size_t interp) {
    if ((n % 2) == 0) {
        memmove(inp + n*interp - n/2, inp + n/2,     n/2*sizeof(cfloat_t));
        memset (inp + n/2 + 1, 0,       (n*(interp-1)-1)*sizeof(cfloat_t)); // Duplicate Fs/2 so we need one less zero

        inp[n/2]          /= 2.0;
        inp[n*interp-n/2] /= 2.0;
    } else {
        memmove(inp + n*interp - n/2, inp + (n+1)/2, n/2*sizeof(cfloat_t));
        memset (inp + (n+1)/2, 0,         (n*(interp-1))*sizeof(cfloat_t));
    }
}


第一种情况可以正常工作,我正在线性调频信号,并且插值很好,有一点数字噪声,但是它通过FFT来回跳动,所以您可以做什么(信号显示的前$ 50 \ mu s $左右):



问题出在奇数长度变换上,我只在真实样本上得到了令人讨厌的瞬态响应(真实的$ 50 \ mu s $又一次): >

虚通道上有一个小的波纹,但还不至于那么差:



我的$ F_s / 2 $ bin处于奇怪的情况,但是没有$ F_s / 2 $ bin,所以我很困惑。有人有什么想法吗?

评论

由于您的地块已经缩小,因此很难看。

@Jason对不起,我以为他们已经链接了,我对html进行了调整,以便他们可以立即单击以查看完整大小。
您是否有任何代码或示例文件可以用作输入内容?要记住的一件事是DFT假定的边界条件。具体而言,存在一个固有的假设,即感兴趣的信号是周期性的。因此,如果在奇数长度输入中的第一个样本和最后一个样本之间存在不连续性,那么您会看到像观察到的那样振铃。长度均匀的样本可能从头到尾更连续,因此您看不到这种现象。

我没有其他人可以轻松消化的格式的数据,但我认为您是对的。我刚到这里工作,重新编译了代码/重新生成了测试输入(1秒钟内有10Hz-100Hz的线性调频),然后重新运行了代码,但没有听到铃声。我看到了您的评论,并将频率更改为10-100.314,现在看到偶数和奇数变换都响了。

您是否尝试过将窗口函数应用于数据?通常,这会减少铃声。

#1 楼

通过将高频频段归零,您可以有效地将信号频谱与矩形函数相乘。频率的乘积是时间的卷积,矩形的傅立叶对是正弦。因此,您真正要做的是将时域信号与Sinc卷积,而Sinc主瓣的宽度与rect的长度成反比。这就是为什么像Parks-McClellan这样的众多滤波器设计技术会在所谓的“过渡区域”或“过渡”频带中进行设计,以使滤波器的频率响应没有瞬时变化的原因。这些滤波器设计技术非常重要,因为像您使用的“理想”滤波器在时域中会产生不良影响。

#2 楼

频域中的一个阶跃将在时域中显示为波动。如果使用窗函数(例如汉明窗)对频率数据进行平滑处理,应该会大大减少纹波。