使用python对音频样本应用过滤器

时间:2017-10-12 21:00:32

标签: python matlab numpy audio scipy

我正在尝试将 Matlab 代码迁移到 Python 上,但我在使用过滤功能方面遇到了一些麻烦。

以下是上下文:

我通过调用以下函数创建了一个butterworth过滤器( fc 是带通中心频率, q 它的品质因数和 n 它的顺序):

def bandpass(fc, q, n):
    bw = fc / q
    low = fc - bw/2
    high = fc + bw/2
    return butter(N=n, Wn=[low, high], btype='band', analog=True)

我从音频信号中检索数据(单声道,采样 fs = 48000,采用16位整数)。当我绘制滤波器的频率响应或音频样本的振幅频谱时,两者都给出了我期望的结果。

以下是代码:

# Imports
import numpy as np
import matplotlib.pyplot as plt
import scipy.io.wavfile as sw
from scipy import signal
from scipy.signal import butter, lfilter

# Read audio file
fs, y = sw.read(file)
# Nb of samples and time scale
N = len(y)
t = np.linspace(0, N/fs, N)
# Plot amplitude spectrum
plt.plot(t, y/max(y))

# Filter creation
b, a = bandpass(1000, 5, 2)
w, h = signal.freqs(b, a, np.logspace(0, 5, 20000))
# Plot frequential response
plt.semilogx(w, 20 * np.log10(abs(h)));

# Apply filter on audio signal
lfilter(b, a, y) # < Give unexepected results

然后是我陷入困境的部分:我正在尝试在音频样本上应用butterworth滤镜,但它似乎不起作用,因为滤波后的信号偏向无穷大并最终在中结束NaN 值的原因不明。我认为尽管遵循了文档但我错过了一步。我也试过 filtfilt(),因为它出现在我做的一些研究中,但它也没有用。

这是我用Matlab得到的expected result,我试图复制。

我错过了什么?

感谢您的回答:)

额外问题:如何在Matlab中绘制3d viewview(-45,65))?

1 个答案:

答案 0 :(得分:1)

您有一个采样(即离散时间)信号。要对其进行过滤,您必须使用离散过滤器,因此butteranalog参数必须为False(这是默认值)。

要分析数字滤镜的频率响应,请使用freqz,而不是freqs

有关带通滤波器的相关问题和答案,请参阅How to implement band-pass Butterworth filter with Scipy.signal.butter