基于倒谱法和线性预测法估计基音频率(MATLAB和Python)

本文介绍了使用倒谱法和线性预测法(LPC)在MATLAB和Python中估计基音频率的方法。通过实例展示了在Python中一帧和一段语音的基音频率估计,并与MATLAB结果进行对比,验证了算法的正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于倒谱法和线性预测法估计基音频率(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 0nN1以外的值都是零,等同于假设了 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=0N1s(n)s(nj),(1jp)(1)
由于 ϕ ( j , i ) \phi(j,i) ϕ(j,i)等效于 r ( j − i ) r(j-i) r(ji),由于自相关是偶函数,所以有:
ϕ ( j , i ) = r ( ∣ j − i ∣ ) (2) \phi(j,i)=r(|j-i|) \tag2 ϕ(j,i)=r(ji)(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=1paiφ(j,i),(1jp)(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)=

是一种常用的基频提取方,它通过对音频信号的频率特性进行数学转换,在域上突出显示周期性的特征。利用该方可以有效地估计出语音或其他声音信号中的基本频率(F0)。以下是基于Python实现的具体步骤说明及代码实例: ### 实现过程概述: 1. **读取音频数据**:从WAV文件加载原始数字音频样本。 2. **预加重处理**:增强高频分量以便于后续分析。 3. **加窗分割**:将连续信号分为若干帧便于局部化运算。 4. **快速傅里叶变换(FFT)** :把时间序列转化为频域表示形式。 5. **对数幅度构建** : 取其幅值再求自然对数形成新的向量组。 6. **离散余弦变换(DCT)**: 将上述所得映射至空间得到最终结果即所谓的“梅尔频率系数”MFCC的一部分亦或是直接作为我们关心的目标——低阶代表了潜在的基本振动模式即基频。 下面是完整的 Python 示例程序片段: ```python import numpy as np from scipy.io import wavfile import matplotlib.pyplot as plt def read_wav(filename): """Read a .wav file.""" rate, signal = wavfile.read(filename) if len(signal.shape) > 1: print("Warnning: Multiple channels detected! Using only first channel.") signal = signal[:,0] return rate, signal.astype(float) def pre_emphasis(signal, coeff=0.97): """Pre-emphasize the input speech signal""" emphasized_signal = np.append(signal[0], signal[1:] - coeff * signal[:-1]) return emphasized_signal # ... 省略部分中间函数 ... if __name__ == '__main__': FILENAME = 'test.wav' RATE, SIG = read_wav(FILENAME) EMP_SIG = pre_emphasis(SIG) frames = split_frames(EMP_SIG, FRAME_LEN, HOP_SIZE) spec_mags = fft_transform(frames).mean(axis=-1) log_spec = apply_log(spec_mags + EPSILON) ceps = dct(log_spec.T, type=2, norm='ortho').T f0_candidates = find_peaks(-ceps[:,:PEAK_LIMIT]) # 寻找负号的最大峰值索引对应的位置就是候选f0 times = [(i+OVERLAP)*FRAME_STEP/RATE for i in range(len(f0_candidates))] fig, ax = plt.subplots(figsize=(8,6)) ax.plot(times,f0_candidates,'.-',color="blue",label="Detected F0") ax.set_xlabel('Time (seconds)') ax.set_ylabel('Frequency (Hz)') ax.legend(loc='best') plt.show() ```
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值