語音處理

語音處理（Speech processing），又稱語音訊號處理、人聲處理，是研究語音訊號及其處理方法的學科。通常，這些訊號是以數字形式進行處理的，因此語音處理可以被視為數字訊號處理的一個特殊案例，專門應用於語音訊號。語音處理涉及語音訊號的獲取、操控、儲存、傳輸和輸出等多個方面。不同的語音處理任務包括語音識別、語音合成、說話人分離、語音增強、說話人識別等。

語音的相關常識

1.1 一般聲音檔格式

取樣頻率：22050Hz
單聲道或雙聲道
每筆資料用 8 個 bit 來表示
電腦中沒有經過任何壓縮的聲音檔：*.wav

1.2 聲音的頻率

頻率範圍

人耳可以辨識頻率：20Hz ~ 20000Hz

說話：150~2000Hz

電話系統頻域：小於 3500Hz

電腦音效卡取樣頻率：44100Hz (最新技術可達 192K)(一般用 22050Hz、11025Hz 即可)

超音波 (ultrasound) 與次聲波 (infrasound)

超音波 (ultrasound)：> 20000Hz

次聲波 (infrasound)：>> fs

22050

>>> num_frame

122868

1.2.1 讀取波形與資料

要先 import 相關模組: import numpy as np

strdata = wavefile.readframes (numframe)
wavedata = np.frombuffer (strdata, dtype=np.int16) # 轉成整數型態
wavedata = wavedata /max (abs (wave_data)) # normalization
n_channel = 2
wavedata = np.reshape (wavedata, (numframe, nchannel)) # 若為雙聲道音檔需要做 reshape

1.2.2 畫出音訊波形圖

要先 import 相關模組: import matplotlib.pyplot as plt

time = np.arange (0, num_frame)*1/fs
plt.plot (time, wave_data)
plt.show

1.3 畫出頻譜

要先 import 相關模組: from scipy.fftpack import fft

fftdata = abs (fft (wavedata:,1))/fs # only choose the 1st channel # 注意要乘上 1/fs
n0=int (np.ceil (num_frame/2))
fftdata1=np.concatenate (fftdatan0:numframe,fftdata0:n0) # 將頻譜後面一半移到前面
freq=np.concatenate (range (n0-numframe,0),range (0,n0))*fs/numframe # 頻率軸跟著調整
plt.plot (freq,fft_data1)
plt.xlim (-1000,1000) # 限制頻率的顯示範圍
plt.show

1.4 播放聲音

要先 import 相關模組: import simpleaudio as sa

n_bytes =2 # using two bytes to record a data
wavedata = (215-1)* wavedata # change the range to -215 ~ 215
wavedata = wavedata.astype (np.int16)
playobj = sa.playbuffer (wavedata, nchannel, n_bytes, fs)
playobj.waitdone

1.5 製作音檔

f = wave.open ('testing.wav', 'wb')
f.setnchannels (2) # 設定聲道數
f.setsampwidth (2) # 每個 samples 有幾個位元組
f.setframerate (fs) # 設定取樣頻率
f.writeframes (wave_data.tobytes )
f.close

1.6 錄音

要先 import 相關模組: import pyaudio

import pyaudio

pa=pyaudio.PyAudio

fs = 44100

chunk = 1024

stream = pa.open (format=pyaudio.paInt16, channels=1,rate=fs, input=True, framesperbuffer=chunk)

vocal=

count=0

時頻分析結果分析

2.1 Matlab

2.1.1 畫出時頻分析結果

可採行兩種方式：

使用 mesh 指令畫出立體圖 (但結果不一定清楚，且執行時間較久)
將 amplitude 變為 gray-level，用顯示灰階圖的方法將結果表現出來

假設 y 是時頻分析計算的結果

image (abs (y)/max (max (abs (y)))*C) % C 是一個常數，可以選 C=400

或 image (t, f, abs (y)/max (max (abs (y)))*C)

colormap (gray (256)) % 變成 gray-level 的圖

set (gca,'Ydir','normal') % 若沒這一行，y-axis 的方向是倒過來的

set (gca,'Fontsize',12) % 改變橫縱軸數值的 font sizes

xlabel ('Time (Sec)','Fontsize',12) % x-axis

ylabel ('Frequency (Hz)','Fontsize',12) % y-axis

title ('STFT of x (t)','Fontsize',12) % title

2.1.2 計算程式執行時間的指令

tic (這指令如同按下碼錶)

toc (show 出碼錶按下後已經執行了多少時間)

註：通常程式執行第一次時，由於要做程式的編譯，所得出的執行時間會比較長。程式執行第二次以後所得出的執行時間，是較為正確的結果

2.2 Python

2.2.1 事前安裝模組

pip install numpy
pip install matplotlib

2.2.2 畫出時頻分析結果

假設 y 為時頻分析結果 (應為二維的矩陣數列)，將 y 以灰階方式畫出來

import numpy as np

import matplotlib.pyplot as plt

C = 400

y = np.abs (y) /np.max (np.abs (y)) * C

plt.imshow (y, cmap='gray', origin='lower') # 加上 origin='lower' 避免上下相反

plt.xlabel ('Time (Sec)')

plt.ylabel ('Frequency (Hz)')

plt.show

若要加上座標軸數值 (在 plt.show 之前加上以下程式碼)

x_label = '0', '10', '20', '30' # 橫軸座標值

y_label = '-5', '0', '5' # 縱軸座標值

plt.xticks (np.arange (0, xmax, step=int (xmax/(len (xlabel)-1)), xlabel)

plt.yticks (np.arange (0, ymax, step=int (ymax/(len (ylabel)-1)), ylabel)

語音訊號分類

從中文發音的觀點來說，聲音仍可分為子音與母音，母音和子音可以用兩種方式區分：

發聲方式：一般而言，母音跟嘴唇形狀有關，而且不與鼻腔共振。相對而言，在發出子音時，就會運用到鼻腔配合發聲。
頻譜分析：從頻譜上觀察可以發現子音的訊號頻率較高，持續時間較短，且會在母音之前出現。而母音的頻率較低，持續時間較長，在子音後或獨立出現，另外，母音的能量也會比子音大。

下面列出中文注音符號中的母音、子音及其拼音。

母音：ㄚ ㄛ ㄜ ㄝ ㄞ ㄟ ㄠ ㄡ ㄢ ㄣ ㄤ ㄥ ㄦ 一 ㄨ ㄩ
子音：ㄅ ㄆ ㄇ ㄈ ㄉ ㄊ ㄋ ㄌ ㄍ ㄎ ㄏ ㄐ ㄑ ㄒ ㄓ ㄔ ㄕ ㄖ ㄗ ㄘ ㄙ

語音的架構

要分析語音訊號前，必須先了解其架構，語音的要素從小到大分別是：音素→音節→詞彙→句子→整段話。

音素是聲音的最小單位，例如「呵」這個字的音素，就是「ㄏ」和「ㄜ」，但是音素和注音符號並不相等，例如「鷗」雖然只有「ㄡ」這個母音，但是由於是雙母音，所以會把他拆成兩個音素。音節在中文而言，就是隻一個字，例如：「天天開心」就有四個音節。詞彙是文字組成的有意義片段，各種不同的詞彙集結成句子，最後變成整段話，這就是語音的架構。

語音處理方法

用麥克風或其他裝置收到的類音聲音訊號，經由類比數位轉換裝置，將資料資料化進行處理，最後再經過數位類比轉換裝置輸出。因此，我們在處理時是針對數位訊號，語音訊號是一種離散時間訊號。其訊號處理流程如下：

收取並取樣訊號：利用麥克風或各種收音裝置，收取類比語音訊號，再用 ADC 裝置 (如類比數位轉換卡) 把類比訊號變成數位訊號，接著根據奈奎斯特理論作取樣，若不符合理論則會造成訊號失真。
量化及編碼：由於電腦中的記憶都是 0 和 1，因此要將所收到的資料用一段適合的 0 跟 1 去儲存，這個動作就稱為量化，所使用的 0 與 1 越多，所需的記憶體越多。接著利用編碼器將數值以波形呈現，因此雖然是數位訊號，但是在電腦中所見到的是類比。
訊號標準化：將語音訊號標準化，使其數值都落在同一個範圍。
音框選擇：由於語音訊號是一段很長的訊號，因此會針對想要處理的部分取音框。
端點偵測：端點偵測的目的是使訊號處理的範圍更精確，只要設定一個音量閾值，若訊號小於閾值，則將其視為沒訊號，但是若雜訊過高，則會產生誤差。
去雜訊：由於雜訊多集中在高頻的部分，因此利用簡單的高頻濾波器，就可以去掉部分雜訊。

基本處理方法

語音訊號是屬於離散時間系統，因此會用離散時間的傅立葉轉換去做處理，除此之外，摺積、窗函式都是一定會使用到的處理方法。

離散時間傅立葉轉換：

摺積：

兩訊號做 convolution 等於，兩訊號先做傅立葉轉換，相乘後再做反傅立葉轉換，藉此可以更快速的處理訊號。

語音處理的應用

語音處理主要有兩個目的：

減少訊號雜訊，做出想要的訊號模組。
進行語音辨識，使人可以利用語言與電腦溝通。