当前位置: 首页 > 面试题库 >

在连续的时间帧上应用IIR滤波器时的连续性问题

姚实
2023-03-14
问题内容

我想 每个 连续 1024个样本的 块/时间帧上 应用FIR或IIR滤波器(例如:低通滤波器)。

可能的应用:

  • 实时 音频处理,例如EQing。在一个精确的时间,缓冲区中只有接下来的1024个样本。下一个要处理的样本尚不可用(实时)。

  • 如答案所示,通过将输入信号分成多个块来制作一个时变截止滤波器。

我在这里尝试过:

import numpy as np
from scipy.io import wavfile
from scipy.signal import butter, lfilter, filtfilt, firwin

sr, x = wavfile.read('input.wav')
x = np.float32(x)
y = np.zeros_like(x)

N  = 1024  # buffer block size = 23ms for a 44.1 Khz audio file
f = 1000  # cutoff
pos = 0  # position

while True:
    b, a = butter(2, 2.0 * f / sr, btype='low')
    y[pos:pos+N] = filtfilt(b, a, x[pos:pos+N])
    pos += N
    f -= 1   # cutoff decreases of 1 hz every 23 ms, but the issue described here also present with constant cutoff!
    print f
    if pos+N > len(x):
        break

y /= max(y)  # normalize

wavfile.write('out_fir.wav', sr, y)

我试过了:

  • 既可以使用Butterworth滤波器也可以使用FIR(用替换之前的行b, a = firwin(1000, cutoff=f, fs=sr), 1.0

  • 都与lfilterfiltfilt(后者向前和向后应用过滤器的优势,这能解决问题阶段),

但这是问题所在:

**在每个时间帧输出的边界处,存在连续性问题,这会使音频信号严重失真。

如何解决这个不连续性问题? 我考虑过windowing + OverlapAdd方法,但是肯定有一种更简单的方法。

在此处输入图片说明


问题答案:

正如@sobek在评论中提到的那样,当然需要指定初始条件以允许连续性。这是通过的zi参数完成的lfilter

通过更改主循环可以解决此问题:

while True:
    b, a = butter(2, 2.0 * f / sr, btype='low')
    if pos == 0:
        zi = lfilter_zi(b, a)
    y[pos:pos+N], zi = lfilter(b, a, x[pos:pos+N], zi=zi)
    pos += N
    f -= 1 
    if pos+N > len(x):
        break

即使每次迭代都修改了过滤器的截止时间(并因此修改了ab),这似乎仍然有效。



 类似资料:
  • 我需要实施一个连续的任务时间表, 我通过Quartz通过,接下来的三次执行 但我希望02:45:00之后的下一次行刑是在03:30:00而不是03:00:00 有什么办法能做到吗

  • 我有ISO8601格式的持续时间值,我将其转换为时间值为整数秒,如下所示: ISO8601格式的持续时间值=“P1Y”。 我将该值存储在“时间-单位-秒”中。因此,当我检索的值将是在int,我想转换回ISO8601持续时间格式,所以我应该得到“P1Y”转换后回来。 有没有快速的方法可以做到这一点?或者我必须把时间的int值转换成float,然后通过某种方法把它转换成ISO8601持续时间。

  • 我有一个结构 如果我有并且希望计算值的总和,这两种方法中哪一种是最快的? A[2]被声明为结构A的两个连续块,如下所示: 编辑 我已将大小从更改为,因为显然不理解我指的是一般情况

  • 我试图在Oracle 11g中运行一个sql查询,它将下面给定的数据集转换为下一个数据集。 这样做的逻辑是start date1和end date1将是连续的。另外start_date2和end date2需要是连续的。如果在某些时候end date2与下一个start date2不匹配,那么需要添加一个具有相同id并且具有enddate2作为下一个start date1的新行。 非常感谢您的帮助

  • 我已经为我的计划问题调整了课程时间安排示例......但我不知道如何确保连续或形容词周期。我的日程计划有活动,每个活动都有一个持续时间,我已将其转换为周期。例如......一个活动大约是120分钟,而时间段大约是30分钟,所以我创建了4个时隙活动。这种方式似乎很容易使活动适应不同的时期......但我找不到一种简单的方法来确保所有这些时隙活动必须是连续的。关于如何实现这一点有什么想法吗? 提前感谢

  • 编译源代码只是整个过程的一个方面,更重要的是,你要把你的软件发布到生产环境中来产生商业价值,所以,你要运行测试,构建分布、分析代码质量、甚至为不同目标环境提供不同版本,然后部署。整个过程进行自动化操作是很有必要的。 整个过程可以参考下图: 整个过程可以分成以下几个步骤: 编译源代码 运行单元测试和集成测试 执行静态代码分析、生成分析报告 创建发布版本 部署到目标环境 部署传递过程 执行冒烟测试和自