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)
我有一个音频信号通过 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)