20hz-20000hz巴特沃思滤波爆炸 [英] 20hz-20000hz Butterworth filtering exploding

查看:112
本文介绍了20hz-20000hz巴特沃思滤波爆炸的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想过滤掉20 Hz-20000 Hz之外的所有内容.我正在使用巴特沃思过滤器:

I want to filter out everything outside 20 Hz - 20000 Hz. I'm using a Butterworth filter:

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文件,但不适用于96 khz WAV文件(此处为演示文件)(这不是音频I/O问题):输出为空白(无声)或爆炸(与其他一些输入的wav文件一起).

I've noticed that it works with a 44.1 khz file, but not with a 96 khz WAV file (demo file here) (it's not an audio I/O problem): the output is either blank (silence) or exploding (with some other input wav files).

1)是否有某些因素导致巴特沃思滤波器不适用于带通[b1,b2],其中b2< 0.5?

1) Is there something that makes that the Butterworth filters don't work with a bandpass [b1, b2] where b2 < 0.5 ?

2)更一般地说,如何使用Python/scipy进行滤波以仅保持20-20000Hz?(没有其他外部库)

2) More generally, how would you do a filtering to keep only 20 - 20000Hz with Python / scipy? (no other external library)

推荐答案

scipy.signal.butter正在生成不稳定的过滤器:

scipy.signal.butter is generating an unstable filter:

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

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

对于稳定的过滤器,最大值必须小于1.不幸的是,代码不会对此发出警告.

For a stable filter, that maximum must be less than 1. Unfortunately, the code doesn't warn you about this.

我怀疑问题是b1,而不是b2.在归一化的单位中,您尝试创建一个较低的2.1e-4截止值,该值非常小.例如,如果下限为200.0/nyq,则表明滤波器是稳定的:

I suspect the problem is b1, not b2. In the normalized units, you are trying to create a lower cutoff of 2.1e-4, which is pretty small. If, for example, the lower cutoff is 200.0/nyq, the filter is stable:

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

您可以使用更强大的sos(二阶部分)格式,而不是将(b, a)格式用于过滤器,该格式已添加到scipy版本0.16中.要使用它,请更改这两行

Instead of using the (b, a) format for the filter, you can use the more robust sos (second order sections) format, which was added to scipy version 0.16. To use it, change these two lines

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过滤器不存在不稳定问题.

That SOS filter does not suffer from the instability problem.

这篇关于20hz-20000hz巴特沃思滤波爆炸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆