基于倒谱法和线性预测法估计基音频率(MATLAB和Python)
倒谱法基音检测在python中实现
一帧信号的基音频率估计
wlen = 256
inc = 128
pitch = []
x1, Fs = librosa.load("a9.wav",sr=None)
plt.subplot(2,1,1)
# plt.plot(x1) # 画一段语音波形
signal = enframe(x1, wlen, inc)
# 取一帧
framedata = signal[15]
plt.plot(framedata)
f_b = pitch_cep(framedata, Fs)
plt.show()
一帧信号估计出来的基音频率是296.29Hz,与matlab求出的296.29Hz是一致的。
一段语音引号的基音频率估计
def pitch_cep(x, Fs):
'''
用倒谱法求基音频率
:param x: 分帧后的数据
:param Fs: 采样率
:return: f_b该帧的基音频率
'''
x2 = fftpack.fft(x)
amp = 20 * np.log10(abs(x2) + 0.0000001)
x3 = abs(fftpack.fft(amp))
x3[0:27] = 0
x3[115:256] = 0
y = max(x3)
x = x3.tolist().index(y)
f_b = Fs / (x - 1.0)
# print('基音频率:', f_b, 'Hz')
return f_b
wlen = 256
inc = 128
pitch = []
x1, Fs = librosa.load("a9.wav",sr=None)
plt.subplot(2,1,1)
plt.plot(x1)
signal = enframe(x1, wlen, inc)
# 取一帧
for i in signal:
framedata = i
f_b = pitch_cep(framedata, Fs)
pitch.append(f_b)
plt.subplot(2,1,2)
plt.plot(pitch)
plt.show()
和MATLAB(下图)作对比,画出的结果是一致的。
LPC估计基音频率
线性预测分析是通过矩阵的特殊性质来解包含p个未知数的p个线性方程。自相关解法是的原理是在整个时间范围内使误差最小,即设 s ( n ) s(n) s(n)在 0 ⩽ n ⩽ N − 1 0 \leqslant n \leqslant N-1 0⩽n⩽N−1以外的值都是零,等同于假设了 s ( n ) s(n) s(n)经过了有限长度的矩形窗、海宁窗或者汉宁窗,就可以用p个方程来解有p个未知数的方程组了。
通常 s ( n ) s(n) s(n)的加窗自相关函数定义为:
r ( j ) = ∑ n = 0 N − 1 s ( n ) s ( n − j ) , ( 1 ⩽ j ⩽ p ) (1) r(j)=\sum_{n=0}^{N-1}s(n)s(n-j),(1\leqslant j \leqslant p) \tag1 r(j)=n=0∑N−1s(n)s(n−j),(1⩽j⩽p)(1)
由于 ϕ ( j , i ) \phi(j,i) ϕ(j,i)等效于 r ( j − i ) r(j-i) r(j−i),由于自相关是偶函数,所以有:
ϕ ( j , i ) = r ( ∣ j − i ∣ ) (2) \phi(j,i)=r(|j-i|) \tag2 ϕ(j,i)=r(∣j−i∣)(2)
因此式
φ ( j , 0 ) = ∑ i = 1 p a i φ ( j , i ) , ( 1 ⩽ j ⩽ p ) (3) \varphi(j,0)=\sum_{i=1}^{p}a_i\varphi(j,i),(1\leqslant j \leqslant p)\tag3 φ(j,0)=i=1∑paiφ(j,i),(1⩽j⩽p)(3)
可以表示为:
r ( j ) = ∑ i = 1 p a i r ( ∣ j − i ∣ ) , ( 1 ⩽ j ⩽ p ) (4) r(j)=\sum_{i=1}^pa_ir(|j-i|),(1\leqslant j \leqslant p) \tag4 r(j)=