零填充奇数长度FFT时的实值振铃


13

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

  1. 均匀长度的响应- 由于模棱两可,因此必须拆分 bin。因此,我复制频谱的负数部分,并在两者之间添加零。Fs/2n*(interp-1)-1
  2. 奇数长的响应-没有 bin,所以只需将正/负频率分开,然后在它们之间插入零。Fs/2n*(interp-1)

可以在此处看到执行零填充的代码

// 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));
    }
}

50μs

50μs

虚通道上的涟漪很小,但差不大:

Fs/2Fs/2


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

@Jason对不起,我以为他们已经链接了,所以我对html进行了调整,以便他们可以立即单击以放大尺寸。
gct

3
您是否有任何代码或示例文件可以用作输入内容?要记住的一件事是DFT假定的边界条件。具体而言,存在一个固有的假设,即感兴趣的信号是周期性的。因此,如果在奇数长度输入中的第一个样本和最后一个样本之间存在不连续性,那么您会看到像观察到的那样振铃。长度均匀的样本从头到尾可能会更连续,因此您看不到这种现象。
杰森R

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

1
您是否尝试过将窗口函数应用于数据?通常,这将减少振铃。
MarkSci 2015年

Answers:


1

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


0

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.