2016-12-29 49 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中。 –