def Formant_Interpolation(u, p, fs): """ 插值法估计共振峰函数 :param u: :param p: :param fs: :return: """ ar, _ = lpc_coeff(u, p) U = np.power(np.abs(np.fft.rfft(ar, 2 * 255)), -2) df = fs / 512 val, loc = local_maxium(U) ll = len(loc) pp = np.zeros(ll) F = np.zeros(ll) Bw = np.zeros(ll) for k in range(ll): m = loc[k] m1, m2 = m - 1, m + 1 p = val[k] p1, p2 = U[m1], U[m2] aa = (p1 + p2) / 2 - p bb = (p2 - p1) / 2 cc = p dm = -bb / 2 / aa pp[k] = -bb * bb / 4 / aa + cc m_new = m + dm bf = -np.sqrt(bb * bb - 4 * aa * (cc - pp[k] / 2)) / aa F[k] = (m_new - 1) * df Bw[k] = bf * df return F, Bw, pp, U, loc
def Formant_Root(u, p, fs, n_frmnt): """ LPC求根法的共振峰估计函数 :param u: :param p: :param fs: :param n_frmnt: :return: """ ar, _ = lpc_coeff(u, p) U = np.power(np.abs(np.fft.rfft(ar, 2 * 255)), -2) const = fs / (2 * np.pi) rts = np.roots(ar) yf = [] Bw = [] for i in range(len(ar) - 1): re = np.real(rts[i]) im = np.imag(rts[i]) fromn = const * np.arctan2(im, re) bw = -2 * const * np.log(np.abs(rts[i])) if fromn > 150 and bw < 700 and fromn < fs / 2: yf.append(fromn) Bw.append(bw) return yf[:min(len(yf), n_frmnt)], Bw[:min(len(Bw), n_frmnt)], U
def pitch_Lpc(x, wnd, inc, T1, fs, p, miniL=10): """ 线性预测法基音周期检测函数 :param x: :param wnd: :param inc: :param T1: :param fs: :param p: :param miniL: :return: """ from scipy.signal import lfilter from chapter3_分析实验.lpc import lpc_coeff y = enframe(x, wnd, inc) fn = y.shape[0] if isinstance(wnd, int): wlen = wnd else: wlen = len(wnd) voiceseg, vsl, SF, Ef = pitch_vad(x, wnd, inc, T1, miniL) lmin = fs // 500 # 基音周期的最小值 lmax = fs // 60 # 基音周期的最大值 period = np.zeros(fn) for k in range(y.shape[0]): if SF[k] == 1: u = np.multiply(y[k, :], np.hamming(wlen)) ar, _ = lpc_coeff(u, p) ar[0] = 0 z = lfilter(-ar, [1], u) E = u - z xx = np.fft.fft(E) b = np.fft.ifft(2 * np.log(np.abs(xx) + 1e-20)) lc = np.argmax(b[lmin:lmax]) period[k] = lc + lmin return voiceseg, vsl, SF, Ef, period
from scipy.signal import filtfilt from chapter2_基础.soundBase import * from chapter3_分析实验.lpc import lpc_coeff plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False data, fs = soundBase('C6_1_y.wav').audioread() N = len(data) time = [i / fs for i in range(N)] # 设置时间 p = 12 ar, g = lpc_coeff(data, p) ar[0] = 0 est_x = filtfilt(-ar, [1], data) plt.subplot(2, 1, 1) plt.plot(time, data, 'k') plt.plot(time, est_x, 'c') plt.title('LPC解码') plt.legend(['信号', '解码信号']) plt.subplot(2, 1, 2) plt.plot(est_x - data) plt.title('误差') plt.savefig('images/LPC解码.png') plt.close()
data /= np.max(np.abs(data)) N = len(data) time = [i / fs for i in range(N)] # 设置时间 p = 12 wlen, inc = 200, 80 msoverlap = wlen - inc y = enframe(data, wlen, inc) fn = y.shape[0] Acoef = np.zeros((y.shape[0], p + 1)) resid = np.zeros(y.shape) synFrame = np.zeros(y.shape) ## 7.2.1 # 求每帧的LPC系数与预测误差 for i in range(fn): a, _ = lpc_coeff(y[i, :], p) Acoef[i, :] = a resid[i, :] = lfilter(a, [1], y[i, :]) # 语音合成 for i in range(fn): synFrame[i, :] = lfilter([1], Acoef[i, :], resid[i, :]) outspeech = Filpframe_OverlapS(synFrame, np.hamming(wlen), inc) plt.subplot(2, 1, 1) plt.plot(data / np.max(np.abs(data)), 'k') plt.title('原始信号') plt.subplot(2, 1, 2) plt.title('还原信号-LPC与误差') plt.plot(outspeech / np.max(np.abs(outspeech)), 'c')