![]() |
1
35
有两个问题:使用FFT的方式和特定的过滤器。
滤波传统上是作为卷积在时间域中实现的。你说得对,输入信号和滤波器信号的频谱相乘是等价的。然而,当您使用离散傅立叶变换(DFT)(使用快速傅立叶变换算法实现速度)时,实际上是计算真实频谱的采样版本。这有很多含义,但与过滤最相关的一个含义是时域信号是周期性的。
下面是一个例子。考虑一个正弦输入信号
|
![]() |
2
11
你的主要问题是 在短时间间隔内频率定义不好 . 这对于低频尤其如此,这就是为什么你最注意到问题所在。 因此,当你把很短的片段从声音序列中取出,然后过滤这些片段时,过滤后的片段不会以产生连续波形的方式过滤,你会听到片段之间的跳跃,这就是产生点击的原因。 例如,取一些合理的数字:我从27.5赫兹(钢琴上的a0)的波形开始,在44100赫兹的频率下数字化,它看起来像这样(红色部分长1024个样本): alt text http://i48.tinypic.com/zim802.png 所以首先我们将从40Hz的低通开始。因此,由于原始频率小于40Hz,一个40Hz截止的低通滤波器不应该真的有任何影响,我们将得到一个几乎完全匹配输入的输出。对吗? 错,错,错 “这基本上是你问题的核心。问题是,对于较短的部分, 主意 27.5赫兹的频率定义不清楚,在离散傅立叶变换中不能很好地表示出来。 从下图中的DFT可以看出,27.5赫兹在短段中没有特别的意义。请注意,虽然较长段的dft(黑点)在27.5赫兹时显示峰值,但短段(红点)没有。 alt text http://i50.tinypic.com/14w6luw.png 显然,低于40Hz的滤波只会捕获直流偏移,40Hz低通滤波器的结果显示为绿色。 alt text http://i48.tinypic.com/2vao21w.png 蓝色曲线(采用200赫兹截止频率)开始匹配得更好。但要注意的是,并不是低频率使它匹配得很好,而是包含了高频。直到我们将短段中可能的每一个频率,高达22kHz,我们才最终得到原始正弦波的良好表示。 所有这些的原因是27.5赫兹正弦波的一小部分 不 27.5赫兹正弦波,它的dft与27.5赫兹没有太多关系。 |
![]() |
3
2
您是否将直流频率采样值减至零?在您的示例中,似乎您根本没有减弱它。由于要实现高通滤波器,因此还需要将dc值设置为零。 这可以解释低频失真。如果直流值由于大的跃迁而非零值,那么低频时的频率响应会产生很大的纹波。 下面是matlab/octave中的一个示例,演示可能发生的情况:
frequency response http://www.freeimagehosting.net/uploads/e10109e535.png 注意,在我的代码中,我创建了一个DC值非零的例子,随后突然变为零,然后是一个斜坡。然后我用ifft转换成时间域。然后我对这个时间域信号执行一个零填充的fft(当你传入一个大于输入信号的fft大小时,matlab会自动完成)。时间域中的零填充导致频域中的插值。使用这个,我们可以看到过滤器如何在过滤器样本之间做出响应。 要记住的最重要的一点是,即使通过衰减DFT的输出来设置给定频率下的滤波器响应值,这也不能保证采样点之间发生的频率。这意味着你的变化越突然,样品之间的过冲和振荡就越多。 现在回答您的问题,关于如何进行过滤。有很多方法,但最容易实现和理解的方法之一是窗口设计方法。当前设计的问题是过渡宽度很大。大多数情况下,你会想要尽可能快的过渡,尽可能少的涟漪。 在下一个代码中,我将创建一个理想的过滤器并显示响应:
frequency response http://www.freeimagehosting.net/uploads/c86f5f1700.png 请注意,突然的变化会引起很多振荡。 FFT或离散傅立叶变换是傅立叶变换的采样版本。傅立叶变换适用于连续范围内的信号-无穷大到无穷大,而DFT适用于有限数量的样本。由于我们只处理有限数量的样本,因此在使用dft时,这实际上会导致在时间域中出现方形窗口(截断)。不幸的是,方波的dft是sinc型函数(sin(x)/x)。 在您的过滤器中有一个尖锐的转换(在一个示例中从0快速跳转到1)的问题是,在时间域中有一个非常长的响应,该响应被一个方形窗口截断。为了帮助最小化这个问题,我们可以将时间域信号乘以一个更渐变的窗口。如果我们将汉宁窗乘以线:
服用IFFT后,我们得到以下回复: frequency response http://www.freeimagehosting.net/uploads/944da9dd93.png 因此,我建议尝试实现窗口设计方法,因为它相当简单(有更好的方法,但它们会变得更复杂)。由于您正在实现均衡器,我假设您希望能够即时更改衰减,因此我建议您在参数发生变化时计算并将滤波器存储在频域中,然后您只需将其应用到每个输入音频缓冲区,方法是取输入缓冲区的fft,乘以您的fre。序列域过滤样本,然后执行ifft返回到时间域。这将比您为每个样本所做的所有分支都有效得多。 |
![]() |
4
1
首先,关于规范化:这是一个已知的(非)问题。DFT/IDFT需要一个系数 1 /平方英尺(n) (除了标准的余弦/正弦因子)在每一个(直接一个逆),使他们西米和真正可逆。另一种可能是将它们中的一个(直接或反向)除以 n ,这是一个方便和品味的问题。通常,FFT例程不执行这种规范化,用户应该了解它,并根据自己的喜好进行规范化。 See 第二:在16分的DFT中,你称之为 斌0 与零频率(dc)相对应, 斌1 低频率 斌4 中等频率, 斌8 达到最高频率 垃圾桶9…15 到“负频率”。在你的例子中, 斌1 实际上是低频和中频。除此之外,你的“均衡”在概念上没有任何错误。我不明白你的意思 “信号在低频时失真” . 你怎么观察到的? |
![]() |
rjonnal · 如何缩放基于FFT的互相关,使其峰值等于皮尔逊ρ 7 年前 |
![]() |
Rearden · fftw从r2c(实到复)数据计算分析信号 7 年前 |
![]() |
scord · 如何从FFT中确定频率值[重复] 7 年前 |
![]() |
Harvey Chang · blackfin bf537 LED闪烁 7 年前 |
![]() |
Muhammad Akmal · 构造不同长度的向量 7 年前 |
![]() |
Foad · 如何使用循环缓冲区[复制]将信号移动90度 7 年前 |
![]() |
haleyk · 寻求有关FFT模板的帮助 7 年前 |
![]() |
Peter · 回归技术的MATLAB代码问题 7 年前 |
![]() |
Rickson · Python中卷积后的数据后处理 7 年前 |