資源簡介
基于MATLAB 的程序。實現(xiàn)語音的合成以及變調(diào)變聲
代碼片段和文件信息
%?ct1
clear?allclose?all?clc;
????%?定義常數(shù)
????FL?=?80;????????????????%?幀長
????WL?=?240;???????????????%?窗長
????P?=?10;?????????????????%?預測系數(shù)個數(shù)
????[sfs]?=?wavread(‘sunday.wav‘);?????????????%?載入語音s
s?=?s/max(s); %歸一化
????L?=?length(s);??????????%?讀入語音長度
????FN?=?floor(L/FL)-2;?????%?計算幀數(shù)
????
%?預測和重建濾波器
????exc?=?zeros(L1);???????%?激勵信號(預測誤差)
????zi_pre?=?zeros(P1);????%?預測濾波器的狀態(tài)
????s_rec?=?zeros(L1);?????%?重建語音
????zi_rec?=?zeros(P1);
????
%?合成濾波器
????exc_syn?=?zeros(L1);???%?合成的激勵信號(脈沖串)
????s_syn?=?zeros(L1);?????%?合成語音
last_syn?=?0;???%存儲上一個(或多個)段的最后一個脈沖的下標
zi_syn?=?zeros(P1);???%?合成濾波器的狀態(tài)
????
%?變調(diào)不變速濾波器
????exc_syn_t?=?zeros(L1);???%?合成的激勵信號(脈沖串)
????s_syn_t?=?zeros(L1);?????%?合成語音
last_syn_t?=?0;???%存儲上一個(或多個)段的最后一個脈沖的下標
zi_syn_t?=?zeros(P1);???%?合成濾波器的狀態(tài)
????
%?變速不變調(diào)濾波器(假設速度減慢一倍)
v=.5;
????exc_syn_v?=?zeros(v\L1);???%?合成的激勵信號(脈沖串)
????s_syn_v?=?zeros(v\L1);?????%?合成語音
last_syn_v?=?0;???%存儲上一個(或多個)段的最后一個脈沖的下標
zi_syn_v?=?zeros(P1);???%?合成濾波器的狀態(tài)
????hw?=?hamming(WL);???????%?漢明窗
????
????%?依次處理每幀語音
????for?n?=?3:FN
????????%?計算預測系數(shù)(不需要掌握)
????????s_w?=?s(n*FL-WL+1:n*FL).*hw;????%漢明窗加權后的語音
????????[A?E]?=?lpc(s_w?P);????????????%用線性預測法計算P個預測系數(shù)
???????????????????????????????????%?A是預測系數(shù),E會被用來計算合成激勵的能量
????????if?n?==?27
????????%?(3)?觀察預測系統(tǒng)的零極點圖
????????????zplane(1A);
????????end
????????
????????s_f?=?s((n-1)*FL+1:n*FL);???????%?本幀語音,下面就要對它做處理
????????%?(4)?用filter函數(shù)s_f計算激勵,注意保持濾波器狀態(tài)
[exc1zi_pre]?=?filter(A1s_fzi_pre);%最終值zi_pre保留下來提供給下一組數(shù)據(jù)運算,就能維持輸出數(shù)據(jù)的連續(xù)性。exc1為激勵
????????
????????exc((n-1)*FL+1:n*FL)?=?exc1;?%計算得到的激勵
????????%?(5)?用filter函數(shù)和exc重建語音,注意保持濾波器狀態(tài)
[s_rec1zi_rec]?=?filter(1Aexc1zi_rec);
????????
????????s_rec((n-1)*FL+1:n*FL)?=?s_rec1;?%計算得到的重建語音
????????%?注意下面只有在得到exc后才會計算正確
????????s_Pitch?=?exc(n*FL-222:n*FL);
????????PT?=?findpitch(s_Pitch);????%?計算基音周期PT(不要求掌握)
????????G?=?sqrt(E*PT);???????????%?計算合成激勵的能量G(不要求掌握)
????????
%方法3:本段激勵只能修改本段長度
tempn_syn?=?[1:n*FL-last_syn]‘;
exc_syn1?=?zeros(length(tempn_syn)1);
exc_syn1(mod(tempn_synPT)==0)?=?G;?%某一段算出的脈沖
exc_syn1?=?exc_syn1((n-1)*FL-last_syn+1:n*FL-last_syn);
[s_syn1zi_syn]?=?filter(1Aexc_syn1zi_syn);
exc_syn((n-1)*FL+1:n*FL)?=??exc_syn1;???%計算得到的合成激勵
s_syn((n-1)*FL+1:n*FL)?=?s_syn1;???%計算得到的合成語音
last_syn?=?last_syn+PT*floor((n*FL-last_syn)/PT);
?
????????%?(11)?不改變基音周期和預測系數(shù),將合成激勵的長度增加一倍,再作為filter
????????%?的輸入得到新的合成語音,聽一聽是不是速度變慢了,但音調(diào)沒有變。
FL_v?=?floor(FL/v);
tempn_syn_v?=?[1:n*FL_v-last_syn_v]‘;
exc_syn1_v?=?zeros(length(tempn_syn_v)1);
exc_syn1_v(mod(tempn_syn_vPT)==0)?=?G;?%某一段算出的脈沖
exc_syn1_v?=?exc_syn1_v((n-1)*FL_v-last_syn_v+1:n*FL_v-last_syn_v);
[s_syn1_vzi_syn_v]?=?filter(1Aexc_syn1_vzi_syn_v);
????? last_syn_v?=?last_syn_v+PT*floor((n*FL_v-last_syn_v)/PT);???
????????exc_syn_v((n-1)*FL_v+1:n*FL_v)?=exc_syn1_v;??%計算得到的
評論
共有 條評論