但是,每当我尝试使用未正确排列的数据进行此操作时,就会发生以下两种情况之一:我使用的数学库(Aforge.Math)会拟合,因为我的样本不是两个的幂。如果我尝试对样本进行零填充,以使它们成为二乘幂,则另一端会产生乱码。我也尝试使用DFT,但是它最终变得异常缓慢(这需要实时完成)。
我将如何正确地对FFT数据进行零填充。初始FFT和最后的逆FFT?假设我有一个44.1khz的样本需要达到16khz,我目前正在尝试类似的事情,样本大小为1000。
将输入数据最后填充到1024
执行FFT
将前512个项读入数组(我只需要前362个,但需要^ 2)
执行逆FFT
将前362个项读入音频播放缓冲区
由此,我最后得到了垃圾。进行相同的操作,但由于样本已经是^ 2,而不必在步骤1和3进行填充,可以得出正确的结果。
#1 楼
第一步是验证您的初始采样率和目标采样率均是有理数。由于它们是整数,因此它们自动是有理数。如果其中一个不是一个有理数,仍然可以改变采样率,但这是一个非常不同的过程,而且难度更大。下一步是将两个样本分解费率。在这种情况下,起始采样率是44100,它是$ 2 ^ 2 * 3 ^ 2 * 5 ^ 2 * 7 ^ 2 $的因数。目标采样率16000是$ 2 ^ 7 * 5 ^ 3 $的因数。因此,要从初始采样率转换为目标率,我们必须将$ 3 ^ 2 * 7 ^ 2 $进行抽取,然后将$ 2 ^ 5 * 5 $进行内插。
前面的步骤必须完成无论您想如何对数据进行重新采样。现在让我们谈谈如何使用FFT。使用FFT进行重采样的技巧是选择FFT长度,以使所有工作顺利进行。这意味着选择的FFT长度是抽取率的倍数(在这种情况下为441)。在本例中,让我们选择FFT长度为441,尽管我们可以选择882或1323,或其他任何正整数441。
要了解其工作原理,有助于可视化它。首先,从音频信号开始,在频域中看起来如下图所示。
处理完成后,您想将采样率降低到16 kHz,但您希望失真尽可能小。换句话说,您只希望将上图中的所有内容都保持在-8 kHz至+8 kHz的范围内,并丢弃其他所有内容。结果如下图所示。
请注意,采样率并非按比例缩放,它们只是用于说明概念。
选择为抽取因子倍数的FFT长度的好处在于,您可以简单地通过删除部分FFT结果,然后对剩余的FFT进行逆采样来进行重采样。在我们的示例中,您对441个数据样本进行了FFT,从而在频域中获得了441个复数样本。我们想要抽取441并内插160($ 2 ^ 5 * 5 $),因此我们保留了160个样本,它们代表从-8 kHz到+8 kHz的频率。然后,我们对这些样本进行逆FFT运算并保存!您有160个时域采样,采样频率为16 kHz。
您可能会怀疑,存在一些潜在的问题。我将详细介绍每个方法,并说明如何克服它们。
如果数据不是抽取因子的好倍数,该怎么办?您可以通过在数据末尾填充足够的零以使其成为抽取因子的倍数来轻松克服这一问题。数据在进行FFT处理之前已被填充。
尽管我介绍的方法非常简单,但它也不理想,因为它会在时域中引入振铃和其他令人讨厌的伪影。您可以通过在删除高频数据之前对频域数据进行过滤来避免这种情况。您可以通过对长度为$ l $的过滤器进行FFT运算,并在数据进行FFT运算之前至少填充$ l-1 $零(请注意,数据采样数和填充采样数必须均为抽取因子的正数-您可以增加填充长度以满足此约束),对填充的数据进行FFT,将频域数据与滤波器相乘,然后对高频(> 8 kHz)进行混叠放入低频(<8 kHz)结果之前,先降低高频结果。不幸的是,由于频域中的滤波本身就是一个大话题,因此,我将无法在此答案中更详细地介绍。不过,我要说的是,如果您要过滤并处理多个块中的数据,则需要实现Overlap-and-Add或Overlap-and-Save才能使过滤连续进行。
我希望这对您有帮助。
编辑:频域样本的起始数量与目标频域样本的数量之间的差异必须是偶数,以便您可以从频域样本中删除相同数量的样本。结果的正面作为结果的负面。在我们的示例中,样本的起始数量是抽取率(即441),目标样本的数量是内插率(即160)。两者的差值为279,不是偶数。解决方案是将FFT长度增加一倍至882,这会使目标样本数也增加一倍至320。现在两者之间的差异是偶数,并且可以毫无问题地丢弃适当的频域样本。
评论
$ \ begingroup $
非常好。吉姆,你如何在飞行中做出如此出色的人物?
$ \ endgroup $
–太空
2012年8月3日18:00
$ \ begingroup $
@Mohammad我通常使用Powerpoint。在这种情况下,我使用了Powerpoint的Libre Office版本,我认为它称为“ Impress”。
$ \ endgroup $
–吉姆·克莱(Jim Clay)
2012年8月3日在18:04
$ \ begingroup $
您好,我对您的问题有疑问(2)。您在此步骤中的确切含义是:“ ...然后将高频(> 8 kHz)的结果混叠为低频(<8 kHz)的结果,然后再丢弃高频结果。”我了解之前的步骤。在将f域数据与过滤器的f域相乘之后,那又如何呢?此外,如果您也想对数据进行上采样,此方法是否有效?谢谢。
$ \ endgroup $
– TheGrapeBeyond
2014年10月10日在11:55
$ \ begingroup $
@TheGrapeBeyond在时域中使用别名时,会将所有Nyquist区域加在一起。所有奈奎斯特区的第一个元素加在一起,成为第一个奈奎斯特区的新的第一个元素。所有Nyquist区域的第二个元素加在一起,成为第一个Nyquist区域的新第二个元素,依此类推。
$ \ endgroup $
–吉姆·克莱(Jim Clay)
2014年10月10日12:53
$ \ begingroup $
嗯,我不确定我是否了解您如何进行基于FFT的重采样,因为当我在此处尝试时,会得到非常奇怪的结果。我会问一个问题。
$ \ endgroup $
– TheGrapeBeyond
2014年10月10日13:05
#2 楼
上面的答案确实很完整:要点是:
要对信号进行下采样,它必须是整数。在对信号进行下采样之前,需要对信号进行滤波。
您可以通过先对信号进行上采样/内插来实现合理的数字下采样。<br />上采样只是插入零,然后对信号进行滤波。
因此达到3/4的采样率。通过在每个信号样本之间插入4个零来对信号进行上采样。应用过滤器。然后过滤信号并每4个信号样本中的每3个删除一次。
详细信息:
http://www.ws.binghamton.edu/fowler/fowler%20personal%20page/EE523_files/Ch_14_1%20Subband%20Intro%20&% 20Multirate%20(PPT).pdf
此外:除非绝对必要,否则请不要对FFT进行计算机处理然后再计算IFFT。这是一个极其缓慢的过程,并且被认为不适用于大多数信号处理任务。 FFT通常仅在频域中用于分析问题或应用信号处理。
#3 楼
正如Bjorn Roche所说的那样,为此使用FFT绝对是无效的。但是这里使用频域中的上采样滤波器和下采样方法以非常非常简单的方式进行。1-获取长度为N的期望矢量信号。
2 -执行N点FFT。
3-在FFT向量的中间用160 * N个零对FFT进行零填充。
4-执行IFFT
5-从441个样本中选择一个丢弃另一个440。
您将得到一个长度为N * 160/441的向量,它将作为您的重采样信号。
如您所见,您正在执行许多无意义的计算,因为大多数结果将被丢弃。但是,如果您可以访问执行FFT的代码,则实际上可以对其进行一些调整,以便它仅计算最终将得到的IFFT结果,而不是您将丢弃的结果。
希望对您有所帮助。
评论
FFT确实不是执行此操作的正确方法。您想要一个多相滤波器组以实现最大效率,但是如果您只想解决问题,请先对GCD进行升采样,然后对低通进行升采样,然后进行降采样。嗨,比约恩:什么是“ GCD”?