使用 Scipy 模拟音频频率均衡器的系统识别/滤波器估计

信息处理 过滤器 频谱 Python 频率响应 转换功能
2022-02-15 19:14:04

在我正在处理的当前问题中,我有两个信号:一个包含音频(语音)的“原始”信号。第二个信号是相同的音频文件,但使用频率均衡器进行了编辑,例如使之间的所有频率更响亮。649677 Hz

我现在想要实现的是“教”一个 SCIPY 过滤器来模仿这种行为。因此,我创建了一个带有两个巴特沃斯过滤器的函数,并尝试curve_fit数据转换为数据。直觉是,像这样系统学习最佳频率间隔来模仿均衡器。显然它没有按预期工作(大多数时候没有曲线拟合。如果我实现曲线拟合并将过滤器应用于原始数据,它根本没有改变)。有什么建议么?xy

import numpy as np
from scipy.optimize import curve_fit
from scipy import signal

xdata = voice_1
ydata = voice_2

# Function to optimize, supposed that two bandpass filters are enough
def func(x, p1,p2,p3,p4):
    b, a = signal.butter(2,[p1,p2],btype="band")
    x = signal.lfilter(b,a,x)
    b, a = signal.butter(2,[p3,p4],btype="band")
    x = signal.lfilter(b,a,x)
    return x

# Optimize function to achieve a curve-fit and therefore get the right frequency response in p1,p2,p3,p4
popt, pcov = curve_fit(func, xdata, ydata,p0=(0.5,0.5,0.5,0.5))

我还尝试过创建一个xsignal包含白噪声的内容,创建一个ysignal我更改了一些频率级别的位置,并将传递函数计算HFFT(ysignal)/FFT(xsignal). 一旦我将此函数应用于白噪声以外的其他数据,结果似乎也是错误的。

1个回答

谢谢你们的评论。我终于在这篇文章中找到了答案并在 python 中实现了它:https ://www.dsprelated.com/freebooks/filters/Time_Domain_Filter_Estimation.html如果你首先找到原始和均衡的传递函数 h(t),它工作得很好白噪声,然后将该函数作为过滤器应用于任何音频数据:

import numpy as np
import scipy

def learn_equalizer(signal_x, signal_y, detail_level):
    # Create Toeplitz Matrix
    padding = np.zeros(detail_level, signal_x.dtype)
    first_col = np.r_[signal_x, padding]
    first_row = np.r_[signal_x[0], padding]
    X = scipy.linalg.toeplitz(first_col, first_row)

    # Implement the formula for finding the optimal solution numerically
    X = X[0:len(X)-detail_level,]
    h = np.dot(X.T,X)
    h = scipy.linalg.inv(h)
    h = np.dot(h,X.T)
    equalizer = np.dot(h,signal_y)

    return equalizer

最后看一下曲线,让我们考虑两张图:一张是原始信号和均衡信号,以显示它们的差异。另一幅图显示了均衡信号和“模拟”均衡器。在这里,您可以看到学习到的滤波器在经过白噪声训练后应用于真实声音时有多好。

信号比较:

信号比较