《語音信號處理試驗教程》(梁瑞宇等)的代碼主要是Matlab實現的,現在Python比較熱門,所以把這個項目大部分內容寫成了Python實現,大部分是手動寫的。使用CSDN博客查看幫助文件:
Python語音基礎操作–2.1語音錄製,播放,讀取
Python語音基礎操作–2.2語音編輯
Python語音基礎操作–2.3聲強與響度
Python語音基礎操作–2.4語音信號生成
Python語音基礎操作–3.1語音分幀與加窗
Python語音基礎操作–3.2短時時域分析
Python語音基礎操作–3.3短時頻域分析
Python語音基礎操作–3.4倒譜分析與MFCC係數
Python語音基礎操作–4.1語音端點檢測
Python語音基礎操作–4.2基音週期檢測
Python語音基礎操作–4.3共振峯估計
Python語音基礎操作–5.1自適應濾波
Python語音基礎操作–5.2譜減法
Python語音基礎操作–5.4小波分解
Python語音基礎操作–6.1PCM編碼
Python語音基礎操作–6.2LPC編碼
Python語音基礎操作–6.3ADPCM編碼
Python語音基礎操作–7.1幀合併
Python語音基礎操作–7.2LPC的語音合成
Python語音基礎操作–10.1基於動態時間規整(DTW)的孤立字語音識別試驗
Python語音基礎操作–10.2隱馬爾科夫模型的孤立字識別
Python語音基礎操作–11.1矢量量化(VQ)的說話人情感識別
Python語音基礎操作–11.2基於GMM的說話人識別模型
Python語音基礎操作–12.1基於KNN的情感識別
Python語音基礎操作–12.2基於神經網絡的情感識別
Python語音基礎操作–12.3基於支持向量機SVM的語音情感識別
Python語音基礎操作–12.4基於LDA,PCA的語音情感識別
代碼可在Github上下載:busyyang/python_sound_open
語音合成主要可分爲波形合成法,參數合成法,規則合成法。
- 波形合成法
- 波形編碼合成,直接把需要合成的語音通過編碼的形式進行存儲,稱爲PCM合成。
- 波形編輯合成,通過在音庫中採取語音的合成單元波形,對這些波形進行編輯拼接後輸出。
- 參數合成法
- 分析法:提取語音參數,壓縮存儲量,然後人工控制這些參數的生成。
- 規則法
- 通過語音學規則產生語音。系統中最小語音單位的聲學參數,以及由音素組成音節,由音節組成詞,由詞組成句子。
幀合併
分幀處理後,需要將多個幀合併起來,涉及的操作有去創函數和去交疊操作。方法爲:
- 通過IFFT把一幀頻域數據轉化爲時域數據。
- 將一組激勵脈衝通過一個濾波器。
常用的三種數據疊加方法爲重疊相加法,重疊存儲法,線性比例重疊相加法。
重疊相加法
假設信號長度爲,窗函數的長度爲,每幀的信號長度爲,將每幀信號與窗函數後面補零,使得長度都爲,得到和。計算和的卷積結果,可以使用FFT和IFFT來計算結果。卷積結果的長度爲N+M-1,把重疊部分相加,與不重疊部分共同構成輸出。把重疊相加推廣到時域,信號是分幀的,每幀爲:
與有M個樣點重疊,重疊部分爲,輸出爲:
重疊存儲法
重疊存儲法是分幀數據在前面補零達到N+M-1的長度。FFT後只取後面M個樣本點,輸出到輸出序列上。
線性比例重疊相加
如果前一幀和下一幀的變化較大,那麼用重疊相加法就不合適了。可以將重疊部分進行比例計權後相加。假設重疊部分長度爲M,兩個斜三角的窗函數和,。
如果前一幀的重疊部分爲,後一幀的重疊部分爲。那麼。
import numpy as np
def Filpframe_OverlapA(x, win, inc):
"""
基於重疊相加法的信號還原函數
:param x: 分幀數據
:param win: 窗
:param inc: 幀移
:return:
"""
nf, slen = x.shape
nx = (nf - 1) * inc + slen
frameout = np.zeros(nx)
x = x / win
for i in range(nf):
start = i * inc
frameout[start:start + slen] += x[i, :]
return frameout
def Filpframe_OverlapS(x, win, inc):
"""
基於重疊存儲法的信號還原函數
:param x: 分幀數據
:param win: 窗
:param inc: 幀移
:return:
"""
nf, slen = x.shape
nx = (nf - 1) * inc + slen
frameout = np.zeros(nx)
x = x / win
for i in range(nf):
frameout[slen + (i - 1) * inc:slen + i * inc] += x[i, slen - inc:]
return frameout
def Filpframe_LinearA(x, win, inc):
"""
基於比例重疊相加法的信號還原函數
:param x: 分幀數據
:param win: 窗
:param inc: 幀移
:return:
"""
nf, slen = x.shape
nx = (nf - 1) * inc + slen
frameout = np.zeros(nx)
overlap = len(win) - inc
x = x / win
w1 = [i / overlap for i in range(overlap)]
w2 = [i / overlap for i in range(overlap - 1, -1, -1)]
for i in range(nf):
if i == 0:
frameout[:slen] = x[i, :]
else:
M = slen + (i - 1) * inc
y = frameout[M - overlap:M] * w2 + x[i, :overlap] * w1
xn = x[i, overlap:]
yy = np.hstack((y, xn))
frameout[M - overlap:M - overlap + slen] += yy
return frameout
from chapter2_基礎.soundBase import *
from chapter7_語音合成.flipframe import *
from chapter3_分析實驗.C3_1_y_1 import enframe
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
data, fs = soundBase('C7_1_y.wav').audioread()
wlen = 256
wnd = np.hamming(wlen)
overlap = 100
f = enframe(data, wnd, overlap)
plt.figure(figsize=(14, 12))
# 7.1.1
fn_overlap = Filpframe_OverlapA(f, wnd, overlap)
plt.subplot(3, 2, 1)
plt.plot(data / np.max(np.abs(data)), 'k')
plt.title('原始信號')
plt.subplot(3, 2, 2)
plt.title('還原信號-重疊相加法')
plt.plot(fn_overlap / np.max(np.abs(fn_overlap)), 'c')
# 7.1.2
fn_s = Filpframe_OverlapS(f, wnd, overlap)
plt.subplot(3, 2, 3)
plt.plot(data / np.max(np.abs(data)), 'k')
plt.title('原始信號')
plt.subplot(3, 2, 4)
plt.title('還原信號-重疊存儲法')
plt.plot(fn_s / np.max(np.abs(fn_s)), 'c')
# 7.1.3
fn_l = Filpframe_LinearA(f, wnd, overlap)
plt.subplot(3, 2, 5)
plt.plot(data / np.max(np.abs(data)), 'k')
plt.title('原始信號')
plt.subplot(3, 2, 6)
plt.title('還原信號-線性疊加法')
plt.plot(fn_l / np.max(np.abs(fn_l)), 'c')
plt.savefig('images/flipframe.png')
plt.close()