butter过滤后的音频缓冲区有限错误(Scipy)

Audio buffer finite error after butter filtering (Scipy)

我有一个音频信号通过 butter 带通滤波器:

def bandpass_filter(y, sr, lowcut, highcut):
  # Setup parameters.
  nyquist_rate = sr / 2.
  filter_order = 1001
  normalized_low = lowcut / nyquist_rate
  normalized_high = highcut / nyquist_rate

  b, a = butter(filter_order, [normalized_low, normalized_high], btype='bandpass')

  y = lfilter(b, a, y)
  return y

然后我使用这个返回的、过滤后的信号使用名为 Librosa 的库检测一些音高。

当我打电话时:

  pitches, magnitudes = librosa.piptrack(y=y, sr=sr, fmin=fmin, fmax=fmax)

其中 y 是过滤后的音频信号,我得到这个错误:

librosa.util.exceptions.ParameterError
ParameterError: Audio buffer is not finite everywhere

基本上来自这个检查:

if not np.isfinite(y).all():
    raise ParameterError('Audio buffer is not finite everywhere')

为什么会这样?

您正在尝试创建阶数为 1001 的 Butterworth filter (which is an IIR 滤波器,使用传递函数系数 (b, a) 表示。传递函数是有理函数,是两个多项式的比值,高阶多项式的计算很容易出现数值误差。你想做的事注定要失败。

一些建议:

  • 重新考虑阶数为 1001 的过滤器的必要性。您为什么要尝试创建阶数如此之高的过滤器?
  • 如果您对滤波器使用 SOS(二阶部分)格式而不是传递函数 (b, a),您将获得更好的数值行为。

尝试使用 much 低阶,并尝试使用 scipy.signal.sosfilt 过滤信号:

sos = butter(filter_order, [normalized_low, normalized_high], btype='bandpass', output='sos')
y = sosfilt(sos, y)