2016-12-29 82 views
1

我想滤除20 Hz - 20000 Hz以外的所有信号。我使用的是巴特沃斯滤波器:20hz-20000hz巴特沃斯滤波爆炸

from scipy.io import wavfile 
from scipy import signal 
import numpy 

sr, x = wavfile.read('sweep.wav') 
nyq = 0.5 * sr 
b, a = signal.butter(5, [20.0/nyq, 20000.0/nyq], btype='band') 

x = signal.lfilter(b, a, x) 
x = numpy.float32(x) 
x /= numpy.max(numpy.abs(x)) 
wavfile.write('b.wav', sr, x) 

我注意到,它的工作原理与44.1 kHz的文件,但不具有96kHz WAV文件demo file here)(它不是一个音频I/O问题):输出是空白(静音)或爆炸(与其他一些输入wav文件)。

1)是否有某件事使Butterworth滤波器不能用带通[b1,b2]工作,其中b2 < 0.5?

2)更一般地说,你将如何做一个过滤,以保持与Python/scipy只有20 - 20000Hz?(没有其他外部库)

+0

错误的堆栈。尝试dsp.stackexchange.com。 – wwii

+0

Scipy是一个外部库。 – wwii

回答

4

scipy.signal.butter正在产生一个不稳定的滤波器:

In [17]: z, p, k = signal.tf2zpk(b, a) 

In [18]: np.max(np.abs(p)) 
Out[18]: 1.0005162676670694 

对于一个稳定的过滤器,即最大必须小于1。不幸的是,代码不会就此发出警告。

我怀疑问题是b1,而不是b2。在标准化单位中,您试图创建一个2.1e-4的较低截止点,这非常小。如果,例如,下截止是200.0/nyq,滤波器是稳定的:

In [13]: b, a = signal.butter(5, [200.0/nyq, 20000.0/nyq], btype='band') 

In [14]: z, p, k = signal.tf2zpk(b, a) 

In [15]: np.max(np.abs(p)) 
Out[15]: 0.99601892668982284 

除了使用(b, a)格式用于过滤器的,则可以使用更强大的sos(二阶区段)的格式,其中加入到scipy版本0.16。要使用它,这两条线

b, a = signal.butter(5, [20.0/nyq, 20000.0/nyq], btype='band') 
x = signal.lfilter(b, a, x) 

改变

sos = signal.butter(5, [20.0/nyq, 20000.0/nyq], btype='band', output='sos') 
x = signal.sosfilt(sos, x) 

这SOS过滤器不会从不稳定问题的困扰。

+0

谢谢!我们应该在这里添加一个[警告通知](https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.signal.butter.html)关于不稳定性,因为没有提及。其他的东西:你怎么知道我们应该使用'sos'?这听起来像对我来说很神奇:)'sos'没有记录在这里:https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.signal.butter.html。它与'zpk'类似吗? – Basj

+0

顺便说一句,我完全随机选择了巴特沃斯,你会用什么解决方案来过滤20-20000Hz以外的一切?我在这里开始了一个DSP.se问题:http://dsp.stackexchange.com/questions/36564/filtering-everything-outside-20-20000-hz – Basj

+0

*“sos在这里没有记录:[...]”*你给了scipy 0.14文档的链接。第一个SOS代码在版本0.16中添加到scipy中。 –