2019/12/30

MFCC 梅爾倒頻譜係數

MFCC是Mel-Frequency Cepstral Coefficients 梅爾頻率倒譜係數的縮寫,它是在1980年由 S.B. Davis和 Paul Mermelstein 提出來的,在語音辨識(Speech Recognition)和語者辨識(Speaker Recognition)方面,最常用到的語音特徵就是「梅爾倒頻譜係數」,此參數考慮到人耳對不同頻率的感受程度,因此特別適合用在語音辨識。

MFCC特徵提取包含兩個關鍵步驟:梅爾頻率分析和倒譜分析

在訊號處理(Signal Processing)中,梅爾倒頻譜(Mel-Frequency Cepstrum, MFC)係一個可用來代表短期音訊的頻譜,其原理根基於以非線性的梅爾刻度(mel scale)表示的對數頻譜(spectrum)及其線性餘弦轉換(linear cosine transform)之上。

梅爾倒頻譜係數 (Mel-Frequency Cepstral Coefficients, MFCC)是一組用來建立梅爾倒頻譜的關鍵係數。由音樂訊號當中的片段,我們可以得到一組足以代表此音樂訊號之倒頻譜,而梅爾倒頻譜係數即是從這個倒頻譜中推得的倒頻譜(也就是頻譜的頻譜)。與一般的倒頻譜不同 ,梅爾倒頻譜最大的特色在於,於梅爾倒頻譜上的頻帶是均勻分布於梅爾刻度上的,也就是說,這樣的頻帶會較一般我們所看到、線性的倒頻譜表示方法,和人類非線性的聽覺系統(audio system)更為接近。在音訊壓縮的技術中,常常使用梅爾倒頻譜來處理。

在語音識別(Speech Recognition)和話者識別(Speaker Recognition)方面,最常用到的語音特徵就是梅爾倒譜系數(Mel-scale Frequency Cepstral Coefficients,簡稱MFCC)。

人類聽覺特性

人耳對不同強度、不同頻率聲音的聽覺範圍稱為聲域。在人耳的聲域範圍內,聲音聽覺心理的主觀感受主要有響度、音高、音色等特徵和掩蔽效應、高頻定位等特性。其中響度、音高、音色可以在主觀上用來描述具有振幅、頻率和相位三個物理量的任何複雜的聲音,故又稱為聲音「三要素」;而在多種音源場合,人耳掩蔽效應等特性更重要,它是心理聲學的基礎。

  1. 響度

    又稱聲強或音量,它表示的是聲音能量的強弱程度,主要取決於聲波振幅的大小。聲音的響度一般用聲壓(達因/平方釐米)或聲強(瓦特/平方釐米)來計量,聲壓的單位為帕(Pa),它與基準聲壓比值的對數值稱為聲壓級,單位是分貝(dB)。對於響度的心理感受,一般用單位宋(Sone)來度量,並定義lkHz、40dB的純音的響度為1宋。響度的相對量稱為響度級,它表示的是某響度與基準響度比值的對數值,單位為口方(phon),即當人耳感到某聲音與1kHz單一頻率的純音同樣響時,該聲音聲壓級的分貝數即為其響度級。

    正常人聽覺的強度範圍為0dB—140dB(也有人認為是-5dB—130dB)。固然,超出人耳的可聽頻率範圍(即頻域)的聲音,即使響度再大,人耳也聽不出來(即響度為零)。在人耳的可聽頻域內,若聲音弱到或強到一定程度,人耳同樣是聽不到的。當聲音減弱到人耳剛剛可以聽見時,此時的聲音強度稱為「聽閾」。一般以1kHz純音為準進行測量,人耳剛能聽到的聲壓為0dB(通常大於0.3dB即有感受)、聲強為10-16W/cm2 時的響度級定為0口方。而當聲音增強到使人耳感到疼痛時,這個閾值稱為「痛閾」。仍以1kHz純音為準來進行測量,使 人耳感到疼痛時的聲壓級約達到140dB左右。

    人耳對3kHz—5kHz聲音最敏感,幅度很小的聲音信號都能被人耳聽到,而在低頻區(如小於800Hz)和高頻區(如大於5kHz)人耳對聲音的靈敏度要低得多。響度級較小時,高、低頻聲音靈敏度降低較明顯,而低頻段比高頻段靈敏度降低更加劇烈,一般應特別重視加強低頻音量。通常200Hz--3kHz語音聲壓級以60dB—70dB為宜,頻率範圍較寬的音樂聲壓以80dB—90dB最佳。

  2. 音高

    也稱音調,表示人耳對聲音調子高低的主觀感受。客觀上音高大小主要取決於聲波基頻的高低,頻率高則音調高,反之則低,單位用赫茲(Hz)表示。主觀感覺的音高單位是「美」,通常定義響度為40方的1kHz純音的音高為1000美。赫茲與「美」同樣是表示音高的兩個不同概念而又有聯繫的單位。

    人耳對響度的感覺有一個從聞閾到痛閾的範圍。人耳對頻率的感覺同樣有一個從最低可聽頻率20Hz到最高可聽頻率別20kHz的範圍。響度的測量是以1kHz純音為基準,同樣,音高的測量是以40dB聲強的純音為基準。

    實驗證明,音高與頻率之間的變化並非線性關係,除了頻率之外,音高還與聲音的響度及波形有關。音高的變化與兩個頻率相對變化的對數成正比。不管原來頻率多少,只要兩個40dB的純音頻率都增加1個倍頻程(即1倍),人耳感受到的音高變化則相同。在音樂聲學中,音高的連續變化稱為滑音,1個倍頻程相當於樂音提高了一個八度音階。根據人耳對音高的實際感受,人的語音頻率範圍可放寬到80Hz--12kHz,樂音較寬,效果音則更寬。

  3. 音色

    又稱音品,由聲音波形的諧波頻譜和包絡決定。聲音波形的基頻所產生的聽得最清楚的音稱為基音,各次諧波的微小振動所產生的聲音稱泛音。單一頻率的音稱為純音,具有諧波的音稱為複音。每個基音都有固有的頻率和不同響度的泛音,藉此可以區別其它具有相同響度和音調的聲音。

人耳的掩蔽效應

一個較弱的聲音(被掩蔽音)的聽覺感受被另一個較強的聲音(掩蔽音)影響的現象稱為人耳的「掩蔽效應」。被掩蔽音單獨存在時的聽閾分貝值,或者說在安靜環境中能被人耳聽到的純音的最小值稱為絕對聞閾。實驗表明,3kHz—5kHz絕對聞閾值最小,即人耳對它的微弱聲音最敏感;而在低頻和高頻區絕對聞閾值要大得多。在800Hz--1500Hz範圍內聞閾隨頻率變化最不顯著,即在這個範圍內語言可儲度最高。在掩蔽情況下,提高被掩蔽弱音的強度,使人耳能夠聽見時的聞閾稱為掩蔽聞閾(或稱掩蔽門限),被掩蔽弱音必須提高的分貝值稱為掩蔽量(或稱閾移)。

純音對純音、噪音對純音的掩蔽效應結論如下:

  • 純音間的掩蔽

    • 對處於中等強度時的純音最有效的掩蔽是出現在它的頻率附近。
    • 低頻的純音可以有效地掩蔽高頻的純音,而反過來則作用很小。
  • 噪音對純音的掩蔽噪音是由多種純音組成,具有無限寬的頻譜

若掩蔽聲為寬頻噪聲,被掩蔽聲為純音,則它產生的掩蔽門限在低頻段一般高於噪聲功率譜密度17dB,且較平坦;超過500Hz時大約每十倍頻程增大10dB。若掩蔽聲為窄帶噪聲,被掩蔽聲為純音,則情況較複雜。其中位於被掩蔽音附近的由純音份量組成的窄帶噪聲即臨界頻帶的掩蔽作用最明顯。

當我們改變窄頻帶聲音刺激(narrowband sound stimulus)時,其聲音成分若跨越某一頻率,則聽覺上會感到有差異,而在一頻率範圍內,則感覺不到差異,這個頻率範圍稱臨界頻帶(Critical Band)

  • 在人類聽覺範圍內 20Hz--16kHz範圍,可以分成24個臨界頻帶

根據人耳聽覺機理的研究發現,人耳對不同頻率的聲波有不同的聽覺敏感度。從200Hz到5000Hz的語音訊號對語音的清晰度影響對大。兩個響度不等的聲音作用於人耳時,則響度較高的頻率成分的存在會影響到對響度較低的頻率成分的感受,使其變得不易察覺,這種現象稱為掩蔽效應。當某個純音位於掩蔽聲的臨界頻帶之外時,掩蔽效應仍然存在。


掩蔽類型

  • 低頻的聲音傾向於遮蔽高頻的聲音

​ 掩蔽聲與被掩蔽聲同時作用時發生掩蔽效應,又稱同時掩蔽。這時,掩蔽聲在掩蔽效應發生期間一直起作用,是一種較強的掩蔽效應。通常,頻域中的一個強音會掩蔽與之同時發聲的附近的弱音,弱音離強音越近,一般越容易被掩蔽;反之,離強音較遠的弱音不容易被掩蔽。例如,—個1000Hz的音比另一個900Hz的音高18dB,則900Hz的音將被1000Hz的音掩蔽。而若1000Hz的音比離它較遠的另一個1800Hz的音高18dB,則這兩個音將同時被人耳聽到。若要讓1800Hz的音聽不到,則1000Hz的音要比1800Hz的音高45dB。一般來說,低頻的音容易掩蔽高頻的音;在距離強音較遠處,絕對聞閾比該強音所引起的掩蔽閾值高,這時,噪聲的掩蔽閾值應取絕對聞閾。

  • 聲音在聽覺器官中,傳遞時間延遲所造成的遮蔽現象,稱時間遮蔽

由於頻率較低的聲音在內耳蝸基底膜上行波傳遞的距離大於頻率較高的聲音,故一般來說,低音容易掩蔽高音,而高音掩蔽低音較困難。在低頻處的聲音掩蔽的臨界頻寬較高頻要小。

時域掩蔽是指掩蔽效應發生在掩蔽聲與被掩蔽聲不同時出現時,又稱異時掩蔽。異時掩蔽又分為導前掩蔽和滯後掩蔽。若掩蔽聲音出現之前的一段時間內發生掩蔽效應,則稱為導前掩蔽;否則稱為滯後掩蔽。產生時域掩蔽的主要原因是人的大腦處理信息需要花費一定的時間,異時掩蔽也隨著時間的推移很快會衰減,是一種弱掩蔽效應。一般情況下,導前掩蔽只有3ms—20ms,而滯後掩蔽卻可以持續50ms—100ms。

所以,人們從低頻到高頻這一段頻帶內按臨界頻寬的大小由密到疏安排一組帶通濾波器,對輸入訊號進行濾波。將每個帶通濾波器輸出的訊號能量作為訊號的基本特徵,對此特徵經過進一步處理後就可以作為語音的輸入特徵。

梅爾刻度是一種基於人耳對等距的音高(pitch)變化的感官判斷而定的非線性頻率刻度。當在梅爾刻度上面上是均勻分度的話,對於的赫茲之間的距離將會越來越大。梅爾刻度的濾波器組在低頻部分的解析度高,跟人耳的聽覺特性是相符的,這也是梅爾刻度的物理意義所在。

由於這種特徵不依賴於訊號的性質,對輸入訊號不做任何的假設和限制,又利用了聽覺模型的研究成果。因此,這種引數比基於聲道模型的LPCC相比具有更好的魯邦性,更符合人耳的聽覺特性,且信噪比降低時仍然具有較好的識別效能。

梅爾刻度與頻率的關係可用下式近似表示, f 為頻率,單位為 Hz。

\(Mel(f) = 2595 * log(1 + \frac{f}{700}) = 1125*ln(1+\frac{f}{700})\)

MFCC 的計算過程

  1. 預強調(Pre-emphasis):將語音訊號 s(n) 通過一個高通濾波器:\(H(z)=1-a*z^{-1}\) 其中 a 介於 0.9 和 1.0 之間。若以時域的運算式來表示,預強調後的訊號 \(s_2(n)\) 為 \(s_2(n) = s(n) - a*s(n-1)\) 。這個處理目的就是為了消除發聲過程中聲帶和嘴唇的效應,來補償語音信號受到發音系統所壓抑的高頻部分。(另一種說法則是要突顯在高頻的共振峰。)

    經過了預強調之後,聲音變的比較尖銳清脆,但是音量也變小了

  2. 音框化(Frame blocking):先將 N 個取樣點集合成一個觀測單位,稱為音框(Frame),通常 N 的值是 256 或 512,涵蓋的時間約為 20~30 ms 左右。為了避免相鄰兩音框的變化過大,所以我們會讓兩相鄰因框之間有一段重疊區域,此重疊區域包含了 M 個取樣點,通常 M 的值約是 N 的一半或 1/3。通常語音辨識所用的音訊的取樣頻率為 8 KHz或 16 KHz,以 8 KHz 來說,若音框長度為 256 個取樣點,則對應的時間長度是 256/8000*1000 = 32 ms。

  3. 漢明窗(Hamming window):將每一個音框乘上漢明窗,以增加音框左端和右端的連續性(請見下一個步驟的說明)。假設音框化的訊號為 \(S(n), n = 0,…N-1\)。那麼乘上漢明窗後為 \(S'(n) = S(n)*W(n)\),此 W(n) 形式如下:

    \(W(n, a) = (1 - a) - acos(2pn/(N-1)),0≦n≦N-1\)

    不同的 a 值會產生不同的漢明窗

    一般都取 a = 0.46

  4. 快速傅利葉轉換(Fast Fourier Transform, or FFT):由於訊號在時域(Time domain)上的變化通常很難看出訊號的特性,所以通常將它轉換成頻域(Frequency domain)上的能量分佈來觀察,不同的能量分佈,就能代表不同語音的特性。所以在乘上漢明窗後,每個音框還必需再經過 FFT 以得到在頻譜上的能量分佈。

    乘上漢明窗的主要目的,是要加強音框左端和右端的連續性,這是因為在進行 FFT 時,都是假設一個音框內的訊號是代表一個週期性訊號,如果這個週期性不存在,FFT 會為了要符合左右端不連續的變化,而產生一些不存在原訊號的能量分佈,造成分析上的誤差。當然,如果我們在取音框時,能夠使音框中的訊號就已經包含基本週期的整數倍,這時候的音框左右端就會是連續的,那就可以不需要乘上漢明窗了。但是在實作上,由於基本週期的計算會需要額外的時間,而且也容易算錯,因此我們都用漢明窗來達到類似的效果。

  5. 三角帶通濾波器(Triangular Bandpass Filters):將能量頻譜能量乘以一組 20 個三角帶通濾波器,求得每一個濾波器輸出的對數能量(Log Energy)。必須注意的是:這 20 個三角帶通濾波器在「梅爾頻率」(Mel Frequency)上是平均分佈的,而梅爾頻率和一般頻率 f 的關係式如下:

    \(Mel(f) = 2595 * log(1 + \frac{f}{700}) = 1125*ln(1+\frac{f}{700})\)

    梅爾頻率代表一般人耳對於頻率的感受度,由此也可以看出人耳對於頻率 f 的感受是呈對數變化的。

    • 在低頻部分,人耳感受是比較敏銳
    • 在高頻部分,人耳的感受就會越來越粗糙

    三角帶通濾波器有兩個主要目的:

    • 對頻譜進行平滑化,並消除諧波的作用,突顯原先語音的共振峰。(因此一段語音的音調或音高,是不會呈現在 MFCC 參數內,換句話說,以 MFCC 為特徵的語音辨識系統,並不會受到輸入語音的音調不同而有所影響。)
    • 降低資料量
  6. 離散餘弦轉換(Discrete cosine transform, or DCT):將上述的 20 個對數能量 Ek帶入離散餘弦轉換,求出 L 階的 Mel-scale Cepstrum 參數,這裡 L 通常取 12。

    離散餘弦轉換公式如下:\(C_m=\sum_{k=1}^{N}cos[m*(k-0.5)*p/N]*E_k, m=1,2, ..., L\) 其中 \(E_k\) 是由前一個步驟所算出來的三角濾波器和頻譜能量的內積值,N 是三角濾波器的個數。由於之前作了 FFT,所以採用 DCT 轉換是期望能轉回類似 Time Domain 的情況來看,又稱 Quefrency Domain,其實也就是 Cepstrum。又因為之前採用 Mel- Frequency 來轉換至梅爾頻率,所以才稱之Mel-scale Cepstrum。

  7. 對數能量(Log energy):一個音框的音量(即能量),也是語音的重要特徵,而且非常容易計算。因此我們通常再加上一個音框的對數能量(定義為一個音框內訊號的平方和,再取以 10 為底的對數值,再乘以 10),使得每一個音框基本的語音特徵就有 13 維,包含了 1 個對數能量和 12 個倒頻譜參數。(若要加入其他語音特徵以測試辨識率,也可以在此階段加入,這些常用的其他語音特徵,包含音高、過零率、共振峰等。)

  8. 差量倒頻譜參數(Delta cepstrum):雖然已經求出 13 個特徵參數,然而在實際應用於語音辨識時,我們通常會再加上差量倒頻譜參數,以顯示倒頻譜參數對時間的變化。它的意義為倒頻譜參數相對於時間的斜率,也就是代表倒頻譜參數在時間上的動態變化,公式如下:

    \(△C_m(t) = \frac{𝜕 C_m(t)}{𝜕t} = [\sum_{t=-M}^{M}C_m(t+t)t] / [\sum_{t=-M}^{M}t^2] \)

    這裡 M 的值一般是取 2 或 3。因此,如果加上差量運算,就會產生 26 維的特徵向量;如果再加上差差量運算,就會產生 39 維的特徵向量。

    一般在 PC 上進行的語音辨識,就是使用 39 維的特徵向量。

References

梅爾倒頻譜 wiki

語音特徵引數MFCC提取過程詳解

聲學特徵提取:梅爾頻率倒譜係數MFCC

Kaldi的MFCC特徵提取代碼分析

梅爾倒頻譜係數.ppt

聲音聽覺理論概述

chap11 speaker identification

Audio Signal Processing and Recognition (音訊處理與辨識) Roger Jang (張智星)

MFCC

語音處理中MFCC(Mel頻率倒譜系數)對應的物理含義是什麼?它計算出的那幾個系數能反映什麼樣特徵?

語音特徵參數MFCC提取過程詳解

聲學特徵(二) MFCC特徵原理

Day 25:自動語音識別(Automatic Speech Recognition) -- 觀念與實踐

Building a Dead Simple Speech Recognition Engine using ConvNet in Keras

2019/12/23

praat

praat 是一款跨平台的多功能語音學專業軟體,主要用於對數位化的語音信號進行分析、標註、處理及合成等實驗,同時生成各種語圖和文字報表。

Praat的主要功能是對自然語言的語音信號進行採集、分析和標註,並執行包括變換和濾波等在內的多種處理任務。作為分析結果的文字報表和語圖,不但可以輸出到 PC 檔案中和終端顯示器上,更能夠輸出為精緻的向量圖或位圖,供寫作和印刷學術論文與專著使用。此外,Praat還可用於合成語音或聲音、統計分析語言學數據、輔助語音教學測試。

基本功能

錄音

在 Praat Objects -> 上面的選單 New -> Record mono sound -> (預設 sample rate 為 44100 Hz) -> Record -> (Play 可播放剛剛路的聲音 ) -> Save to list

View & Edit

  • 上面是 wav 的波形,中間是聲譜 (spectrum),代表聲音在每一個頻率的能量大小,越黑代表越強。在上面選單 Spectrum -> Show spectrum 可選擇要不要顯示 spectrum
  • 藍色線條就是 Pitch 音高 (代表聲帶震動的快慢,震動越快,音高會越高。) 在上面 Pitch -> Show pitch 可以將 pitch 關掉
  • Intensity 強度、音量,在選單 Intensity -> Show intensity 可顯示黃色線條 intensity
  • Formant 共振峰 是用來描述聲學共振現象的一種概念,在語音科學及語音學中,描述的是人類聲道中的共振情形。

note:

  • 音量(Volume):代表聲音的大小,可由聲音訊號的震幅來類比,震幅越大,代表此聲音波形的音量越大。音量又稱為能量(Energy)或強度(Intensity)等。
  • 音高(Pitch):代表聲音的高低,可由基本頻率(Fundamental Frequency)來類比,這是基本週期(Fundamental Period)的倒數。聲音的基本頻率越高,代表音高越高;反之,聲音的基本頻率越低,代表音高越低。
  • 音色(Timbre):代表聲音的內容(例如英文的母音),可由每一個波形在一個基本週期的變化來類比。不同的音色即代表不同的音訊內容,例如不同的字母有不同的發音,都是由於音色不同而產生。

如果是用人聲來說明,這些語音特徵的物理意義如下:

  • 音量:代表肺部壓縮力量的大小,力量越大,音量越大。
  • 音高:代表聲帶震動的快慢,震動越快,音高會越高。
  • 音色:代表嘴唇和舌頭的位置和形狀,不同的位置和形狀,就會產生不同的語音內容。

選取後,點中間灰色區塊的秒數長度的部分,就可以播放聲音。點 "Visible part" 或 "Total duration" 可播放整個音檔。

在 Edit -> Set selection to zero,可以將選取起來的雜音部分都設定為 0,也就是刪除那一部分的聲音的意思。

Edit -> Reverse selection,可將聲音倒過來。就等於將聲音倒著播放。

音檔標注

  1. Open -> Read from file 讀取語音 wav 檔

  2. Annotate -> To TextGrid 產生一個空白的標註文件。要先規劃好對這個聲音文件要標註幾層訊息,通常會標註音素 (phone)、音節 (syllable)、字詞。在 All tier names: 填上 phon syllable。

  3. 目前先在 All tier names 填上 sentence,清除 "wichi of these are point tiers?"

  4. 同時選取聲音文件跟 TextGrid,點 View & Edit 進行標注。標注時,聽辨邊界,並查閱語圖資訊,確定音素與音節的邊界

  5. 點擊剛剛聽到的單字的起點,點中間 sentence 裡面的圓圈,設定單字起點。同樣標記出終點 boundary。

  1. 可在 Tier -> add interval tier ,增加一層標記

    1. 有另一種 Point tier,可用來標記 事件

    1. File -> Save TextGrid as text file 可將標記存成文字檔

    2. 在 Praat Obejcts 畫面,選語音,Save -> Save as WAV file 可將剛剛修改過的 wav 存成另一個 wav file

  2. 把 Parrat 關掉時,會將選取的 wav, TextGrid 都清除。Open -> Open from file 可將剛剛存的 wav, TextGrid 選取回來

Drawing

可將 wav & textgrid 同時選取,並點 Praat Objects 右邊的 Draw,就會在 Praat Picture 出現圖檔。點擊 Draw 之前,可先在 Praat Picture 重新把藍色框框範圍改為 9x6,再 Draw,就可得到比較大的圖檔。

畫圖時,有個 "Garnish" 選項,如果有打勾,畫圖時就會增加座標的資訊。如果沒有,就只會畫出線條。

Combine

如果已經有 150 個單字 wav以及 TextGrid,可同時將 150 個 wav 讀取進來,然後用 Combine -> Concatenate recoverably 將 150 個單字及 TextGrid 合併為一個檔案以及一個 TextGrid。

共振峰

ref:

共振峰 wiki

什麼是共振峰?

12-1 共振峰

共振峰(formant)是用來描述聲學共振現象的一種概念,在語音學中,描述的是人類聲道中的共振情形。常用的量測方法是由頻譜分析或聲譜圖(spectrogram)中,尋找頻譜中的峰值。

人類說話或唱歌產生的聲音包含許多不同的頻率,共振峰是這些頻率中較有意義的部分。定義上,人類若想分辨幾個不同的元音,我們所需要的資訊是完全可以被量化的。共振峰是使聽者能夠區分元音的關鍵泛音。大部份的這些共振峰是由管內或腔體的共振產生,但是有些哨音是由文丘裡效應中的低壓區域週期性回縮產生。

頻率最低的共振峰頻率稱為 f1,第二低的是 f2,而第三低的是 f3(基頻一般以 f0 標示)。絕大多部分的情形是,前兩個共振峰,f1 和 f2 就足以劃分不同元音。這兩個共振峰可以描述元音的開/閉、前/後兩個維度(過去傳統上把這和舌頭的位置聯結在一起,不過這並不完全精確)。因此開元音如 [a] 有比較高的第一共振峰頻率f1,而閉元音如 [i u] 的則比較低;前元音如 [i] 的第二共振峰頻率 f2 較高,後元音如 [u] 的則比較低。元音幾乎都有四個以上的共振峰,有時還會超過六個。然而,前兩個共振峰還是最關鍵的。通常我們會用第一共振峰對第二共振峰的 關係圖描述不同元音的性質。但這不足以描述某些元音的性質,例如圓唇與否。圓唇會降低 f3,該效果對高前元音最明顯。


"音高比較低的共振峰是第一共振峰,另一個就是第二共振峰"

元音,或稱母音,是音素的一種,與輔音相對。元音是在發音過程中由氣流通過口腔而不受阻礙發出的音。

輔音,或稱子音,在調音語音學中是語音的一類,與元音相對,發音的調音環節中氣流在調音器官某一部分受到完全或部分阻礙。

英語的「元音」和「輔音」分別相當於漢語拼音裡的「韻母」和「聲母」。單元音可比對單韻母、雙元音相當於複韻母。


聲音可分為 periodic 與 aperiodic ,就是有沒有週期性的差異

人類語言,不管是元音還是輔音,都要有一個音源(source)。

元音的音源來自聲帶,一班是 almost periodic,輔音的音源一半來自 constriction (ex: s ),由此產生 aperiodic 的 noise

periodic 的音分為兩種:簡單(ex: 正弦波)、複雜

元音的音源一般都是複雜的,也就是可以分解成好幾個簡單的波

有好幾個 components 組成的波,經過數學分解後,可產生多個 harmonic 諧波 (spectrum)

在很多 harmonics 諧波中,第一個稱為基頻,也就是 F0 (0號共振峰、1號諧波),其他的都是基頻的整數倍 (H1,H2,H3)

ex: F0/H1=100Hz, F2/H1=200Hz, F3/H1=300Hz


語音學中,要強調一件事情,可以在兩件事情中間,加上一小段停頓。


頻譜圖(Spectrum) 就是描述在某一時間點上,各個頻率的聲音分佈情況。頻譜圖只能描述某一時間點,不能表達一段時間的情況,所以把頻譜連續的畫到一張圖裡,就有了聲譜圖 (Spectrogram)。

Pitch listing and plotting in Excel

  1. 選取一個音檔,只顯示 Spectrum, Pitch,把 Intensity, Formant 關掉。畫面上是 spectrum 跟藍色線條 Pitch
  2. 選取某一個聲音區塊,點下面的 "sel" 放大該區塊的畫面

  1. 如果發現突然有一個點特別高,還有最前面,沒有聲音,但是卻有 pitch 點,都可能是 praat 誤判。最後輸出時,可將該點刪除,改用前後兩點的平均作為該點的值(內插法)。
  2. 選取畫面上需要的聲音區塊,點 Pitch -> Pitch listing,會列出每10ms 的 F0_Hz

  1. 將兩段語音的 pitching listing,複製到 excel 畫出折線圖


另一種方法是,在 Praat Objects 右邊 "Analyse periodicity" -> "to pitch",(這邊如果已經知道該語音的)pitch 上下界限,可以調整設定。然後 OK 產生 pitch object。然後就先標記一塊 draw area(藍色框框),就能 Draw 到 picture。

Duration Manipulation

在不影響前後的聲音的條件下,先決定想要調整的 duration 聲音區塊,然後在前後一點點時間點,設定一塊處理語音的限制區間,修改 duration。

  1. 在 Praat Objects 右邊的 Manipulate -> To Manipulate,用預設值,點 OK

  2. 先選取要處理 duration 的聲音區塊

  3. 首先放大到聲音區間的開始點。將 cursor 點到想要處理的起點。在選單 Dur -> Add duration point at cursor,畫面上就會產生一個紅點。然後再 Add duration point at...,將 小數點第三位由 3 改為 2。畫面上會出現另一個綠色點

  1. 用相同的步驟,到聲音區塊的終點。增加兩個 duration point

  2. 回到 Praat Objects 畫面,點 Extract duration tier,就會出現一個新的 duration tier object

  3. Save -> Save as text file,存成一個 text file

  4. 用 text editor 打開該檔案 (test2.DurationTier),可看到四個點。第 1,4 兩點不動,

    File type = "ooTextFile"
    Object class = "DurationTier"
    
    xmin = 0 
    xmax = 1.8870625 
    points: size = 4 
    points [1]:
        number = 0.38218997211642386 
        value = 1 
    points [2]:
        number = 0.38318997211642386 
        value = 0.9999999999999996 
    points [3]:
        number = 0.49353125000000003 
        value = 0.9999999999999996 
    points [4]:
        number = 0.49453125000000003 
        value = 1 
    

    把中間兩點的 value 改為 1.5 倍,修改時必須放大為一樣的倍數

    File type = "ooTextFile"
    Object class = "DurationTier"
    
    xmin = 0 
    xmax = 1.8870625 
    points: size = 4 
    points [1]:
        number = 0.38218997211642386 
        value = 1 
    points [2]:
        number = 0.38318997211642386 
        value = 1.5
    points [3]:
        number = 0.49353125000000003 
        value = 1.5
    points [4]:
        number = 0.49453125000000003 
        value = 1 
    

    存檔後

  5. 回到 Parrat Objects,刪除舊的 DurationTier, Open -> Open from file,載入修改後的 duration tier

  6. 選取 "Manupulation" 及 "Duration Tier",右邊會出現 "Replace duration tier" 按鈕

  7. View & Edit Manupulation,可看到被拉高的 duration

  1. 可實際聽聽看聲音是不是被拉長了。在 File -> Publish resynthesis。回到 Praat Object 會出現一個 "Sound fromManipulationEditor" 的聲音檔。在 Save -> Save as wav file 可存成另一個 wav file

Pitch Manipulation

  1. 在 Praat Objects 右邊的 Manipulate -> To Manipulate,用預設值,點 OK。會出現一個 Manipulation object。可先 View & Edit
  2. 可以直接拉動 pitch 的點去做調整。也可以匯出到一個 text file,直接用 text editor 修改
  3. 回到 Praat Object,點右邊的 "Extract pitch tier",會出現 PitchTier object。點上面的 Save -> Save as PitchTier spreadsheet file

  4. 用 text editor 打開會是這樣

    "ooTextFile"
    "PitchTier"
    0 1.8870625 143
    0.24353125  405.36076816599967
    0.25353124999999999 384.58128094973438
    0.26353124999999999 371.21591458911877
    0.27353125  367.63791485651495
    0.28353125000000001 368.6819886604992
    0.29353125000000002 368.89100487289591
    0.30353125000000003 367.44155207316203
    0.31353124999999998 365.30946486949387
    0.32353124999999999 362.17120060758612
    0.33353125  360.9426395082146
    0.34353125000000001 361.86527201551934
    0.35353125000000002 363.25320207521213
  5. 可直接修改後面 pitch 數值,再載入修改後的 PitchTier,然後回到 Praat Object,選取 "Manipulation" 及新的 PitchTier,"Replace pitch tier" 後,可得到修改後的 sound file

Scripting

ref:

Mietta's Scripts

praat scripts

This is a collection of Praat scripts, written, modified, or used by Will Styler

執行 praat script 就是在 praat 最上面的選單中,有個 Open praat script 的功能,選取該 script,然後上面的選單最後一個,Run 執行即可

會將 labels.txt 文字檔,填寫到 TextGrid object 的 intervals 的 label 裡面

# This script reads lines from a text file (called labels.txt and saved in the home directory)
# and adds them line by line as labels for intervals in a selected TextTier in the selected TextGrid object.
#
# You should check that the boundaries are correct before running the script.
# The script will jump over intervals labeled as "xxx". Use this marking if there are intervals that
# you will remove later.
# Hint: This tool is useful if you use the mark_pauses script before it! It is easy to check that the
# pause boundaries are in correct places, if you know what kind of content should be in the sound
# segments - e.g., read sentences.
#
# This script is distributed under the GNU General Public License.
# Mietta Lennes 25.1.2002
#
soundname$ = selected$ ("TextGrid", 1)
select TextGrid 'soundname$'
stringlength = 0
filelength = 0
firstnewline = 0
oldlabel$ = ""
newlabel$ = ""
form Label intervals in an IntervalTier from text file
comment Give the path of the text file containing the label lines:
sentence Filename /Users/zqi/Dropbox/BILD/MMN/psychopy/labels.txt
comment Which IntervalTier in the selected TextGrid do you want to label?
integer Tier_(index) 1 (= the first IntervalTier)
comment Which interval do we start labeling from?
integer Starting_interval_(index) 1 (= the first interval)
comment Do you want to overwrite old labels?
comment (Intervals previously marked with 'xxx' will be skipped despite this!)
boolean Overwrite 1
endform

if fileReadable (filename$)
numberOfIntervals = Get number of intervals... tier
if starting_interval > numberOfIntervals
exit There are not that many intervals in the IntervalTier!
endif
leftoverlength = 0
# Read the text file and put it to the string file$
file$ < 'filename$'
if file$ = ""
    exit The text file is empty.
endif
filelength = length (file$)
leftover$ = file$
# Loop through intervals from the selected interval on:
for interval from starting_interval to numberOfIntervals
oldlabel$ = Get label of interval... tier interval
if oldlabel$ <> "xxx"
# Here we read a line from the text file and put it to newlabel$:
firstnewline = index (leftover$, newline$)
newlabel$ = left$ (leftover$, (firstnewline - 1))
leftoverlength = length (leftover$)
leftover$ = right$ (leftover$, (leftoverlength - firstnewline))
# Then we check if the interval label is empty. If it is or if we decided to overwrite, 
# we add the new label we collected from the text file:
    if overwrite = 1
                Set interval text... tier interval 'newlabel$'
            elsif oldlabel$ = ""
              Set interval text... tier interval 'newlabel$'
            else 
                    exit Stopped labeling, will not overwrite old labels!
   endif
endif
endfor
else 
    exit The label text file 'filename$' does not exist where it should!
endif

限制要處理 long sound file (Open -> Open long sound file)

處理一個已經有 interval labels 的 sound file,將每個 textgrid 作為檔名,分割成多個 wav,可加上檔名的 prefix/suffix。通常如果是有多個人講的同一段文字,在存檔時,會將每個人的 id number 放在檔名 suffix,這樣就可以針對同一個單字,同時聽多個人的 wav,做分析判斷。

# This script saves each interval in the selected IntervalTier of a TextGrid to a separate WAV sound file.
# The source sound must be a LongSound object, and both the TextGrid and 
# the LongSound must have identical names and they have to be selected 
# before running the script.
# Files are named with the corresponding interval labels (plus a running index number when necessary).
#
# NOTE: You have to take care yourself that the interval labels do not contain forbidden characters!!!!
# 
# This script is distributed under the GNU General Public License.
# 8.3.2002 Mietta Lennes
#

form Save intervals to small WAV sound files
    comment Which IntervalTier in this TextGrid would you like to process?
    integer Tier 1
    comment Starting and ending at which interval? 
    integer Start_from 1
    integer End_at_(0=last) 0
    boolean Exclude_empty_labels 1
    boolean Exclude_intervals_labeled_as_xxx 1
    boolean Exclude_intervals_starting_with_dot_(.) 1
    comment Give a small margin for the files if you like:
    positive Margin_(seconds) 0.01
    comment Give the folder where to save the sound files:
    sentence Folder /Users/lennes/Demo/save_labeled_intervals/exported/
    comment Give an optional prefix for all filenames:
    sentence Prefix Test_
    comment Give an optional suffix for all filenames (.wav will be added anyway):
    sentence Suffix 
endform

gridname$ = selected$ ("TextGrid", 1)
soundname$ = selected$ ("LongSound", 1)
select TextGrid 'gridname$'
numberOfIntervals = Get number of intervals... tier
if start_from > numberOfIntervals
    exit There are not that many intervals in the IntervalTier!
endif
if end_at > numberOfIntervals
    end_at = numberOfIntervals
endif
if end_at = 0
    end_at = numberOfIntervals
endif

# Default values for variables
files = 0
intervalstart = 0
intervalend = 0
interval = 1
intname$ = ""
intervalfile$ = ""
endoffile = Get finishing time

# ask if the user wants to go through with saving all the files:
for interval from start_from to end_at
    xxx$ = Get label of interval... tier interval
    check = 0
    if xxx$ = "xxx" and exclude_intervals_labeled_as_xxx = 1
        check = 1
    endif
    if xxx$ = "" and exclude_empty_labels = 1
        check = 1
    endif
    if left$ (xxx$,1) = "." and exclude_intervals_starting_with_dot = 1
        check = 1
    endif
    if check = 0
       files = files + 1
    endif
endfor
interval = 1
pause 'files' sound files will be saved. Continue?

# Loop through all intervals in the selected tier of the TextGrid
for interval from start_from to end_at
    select TextGrid 'gridname$'
    intname$ = ""
    intname$ = Get label of interval... tier interval
    check = 0
    if intname$ = "xxx" and exclude_intervals_labeled_as_xxx = 1
        check = 1
    endif
    if intname$ = "" and exclude_empty_labels = 1
        check = 1
    endif
    if left$ (intname$,1) = "." and exclude_intervals_starting_with_dot = 1
        check = 1
    endif
    if check = 0
        intervalstart = Get starting point... tier interval
            if intervalstart > margin
                intervalstart = intervalstart - margin
            else
                intervalstart = 0
            endif
    
        intervalend = Get end point... tier interval
            if intervalend < endoffile - margin
                intervalend = intervalend + margin
            else
                intervalend = endoffile
            endif
    
        select LongSound 'soundname$'
        Extract part... intervalstart intervalend no
        filename$ = intname$
        intervalfile$ = "'folder$'" + "'prefix$'" + "'filename$'" + "'suffix$'" + ".wav"
        indexnumber = 0
        while fileReadable (intervalfile$)
            indexnumber = indexnumber + 1
            intervalfile$ = "'folder$'" + "'prefix$'" + "'filename$'" + "'suffix$''indexnumber'" + ".wav"
        endwhile
        Write to WAV file... 'intervalfile$'
        Remove
    endif
endfor
  • VOT (Voice onset time) tier

發聲起始時間(英語:Voice onset time,簡稱VOT),或譯為嗓音起始時間、濁音起始時間、聲帶震動起始時間、濁聲初起時、初濁。VOT的具體含義不完全與字面吻合,實際指某一輔音從除阻的一刻到聲帶開始震動,中間所經過的時間。

從 release -> 到 onset 所經過的時間

calculatesegmentdurations.praat

# This script will calculate the durations of all labeled segments in a TextGrid object.
# The results will be save in a text file, each line containing the label text and the 
# duration of the corresponding segment..
# A TextGrid object needs to be selected in the Object list.
#
# This script is distributed under the GNU General Public License.
# 12.3.2002 Mietta Lennes

# ask the user for the tier number
form Calculate durations of labeled segments
    comment Which tier of the TextGrid object would you like to analyse?
    integer Tier 1
    comment Where do you want to save the results?
    text textfile durations.txt
endform

# check how many intervals there are in the selected tier:
numberOfIntervals = Get number of intervals... tier

# loop through all the intervals
for interval from 1 to numberOfIntervals
    label$ = Get label of interval... tier interval
    # if the interval has some text as a label, then calculate the duration.
    if label$ <> ""
        start = Get starting point... tier interval
        end = Get end point... tier interval
        duration = end - start
        # append the label and the duration to the end of the text file, separated with a tab:      
        resultline$ = "'label$' 'duration''newline$'"
        fileappend "'textfile$'" 'resultline$'
    endif
endfor

Automatically open each .wav file in a folder, manually label intervals and rectify vocal pulse markings

References

PRAAT 使用手冊

praat wiki

結合Praat進行語音實驗的步驟

以Praat 語言分析軟體應用於華語語音教學法初探

[Phonetics] Praat的下載、教學、plug-in、script

熊子瑜「XIONG Ziyu」語音與言語科學重點實驗室

praat 語音軟體操作手冊

Lec15 Praat ─ 進階版

NCTU OCW 外國語文學系 賴郁雯老師 發音概論 The art of articulation

音色與聲譜圖

2019/12/16

SSL container formats

在處理 SSL 以及 TLS 的時候,常需要利用 openssl 或是 java 的 keytool 產生憑證,而憑證通常會存放在某種規格的檔案中,而且不同的 client 通常支援了不同的憑證格式,例如常見的 .crt .pem 等等,以下我們試著去了解一下這些存放憑證的檔案規格。

  • .csr

  1. 這是 Certificate Signing Request 的簡稱
  2. 實際上的格式是 RFC2986 定義的 PKCS10
  3. 裡面包含了所有詳細的憑證資料,例如 subject, organization, state
  4. 用在數位簽章

  • .pem

  1. 這是 Privacy Enhanced Email 的簡稱
  2. 定義在 RFC 1421 ~ 1424
  3. 這是一種 container format,通常只會存放 public certificate
  4. 可以存放整個 certificate chain,包含了 public key, private key 與 root certificates
  5. 這是一個失敗的 email 加密方法,但儲存憑證的格式卻有被廣泛使用
  6. Base64 encoded ACII files

  • .key

  1. 這是 .pem 格式的檔案,只會存放 private key
  2. 這是既定俗成的一個副檔名,並不是一種標準的檔案格式

  • .der .cer .crt

  1. Distinguished Encoding Rules 的簡稱
  2. 是一種 binary format of encoding a data value of any data types including nested data structures
  3. 是一種 ASN.1 的編碼規則
  4. 規格定義在 ITU-T X.690
  5. windows 預設會將憑證輸出為 .der 格式的檔案

  • .p7b .p7c

  1. 定義在 RFC 2315
  2. 存放 Certificates & Chain certificates,不包含 private key
  3. Base64 encoded ASCII files

  • .pkcs12 .pfx .p12

  1. 由 RSA 定義在 Public-Key Cryptography Standards 這個規格中
  2. 必須用一個密碼才能打開這個 container 檔案
  3. 裡面儲存了 public 與 private certificate pairs 憑證
  4. 跟 .pem 檔案不同,檔案本身就有用密碼加密
  5. 可利用以下這個指令將 .p12 檔案裡面的 public 與 private keys 轉換成 .pem

    openssl pkcs12 -in a.p12 -out a.pem -nodes
  6. 常用在 Windows OS,這是用來匯入或匯出 certificates and Private keys

  • .crl

  1. Certificate Revocation List 的簡稱
  2. CA (Certificate Authorities) 會在憑證過期前,產生出來,用來通知使用者這些憑證已經過期了

What is a Pem file and how does it differ from other OpenSSL Generated Key File Formats?

What are the differences between PEM, DER, P7B/PKCS#7, PFX/PKCS#12 certificates