【語音合成】基於matlab線性預測共振峰檢測和基音引數語音合成【含Matlab原始碼 562期】
阿新 • • 發佈:2021-06-27
一、簡介
基於matlab線性預測共振峰檢測和基音引數的語音合成
二、原始碼
clear all; clc; close all; [xx,fs]=wavread('C7_3_y.wav'); % 讀取檔案 xx=xx-mean(xx); % 去除直流分量 x1=xx/max(abs(xx)); % 歸一化 x=filter([1 -.99],1,x1); % 預加重 N=length(x); % 資料長度 time=(0:N-1)/fs; % 訊號的時間刻度 wlen=240; % 幀長 inc=80; % 幀移 overlap=wlen-inc; % 重疊長度 tempr1=(0:overlap-1)'/overlap; % 斜三角窗函式w1 tempr2=(overlap-1:-1:0)'/overlap; % 斜三角窗函式w2 n2=1:wlen/2+1; % 正頻率的下標值 wind=hamming(wlen); % 窗函式 X=enframe(x,wlen,inc)'; % 分幀 fn=size(X,2); % 幀數 Etemp=sum(X.*X); % 計算每幀的能量 Etemp=Etemp/max(Etemp); % 能量歸一化 T1=0.1; r2=0.5; % 端點檢測引數 miniL=10; % 有話段最短幀數 mnlong=5; % 母音主體最短幀數 ThrC=[10 15]; % 閾值 p=12; % LPC階次 frameTime=FrameTimeC(fn,wlen,inc,fs); % 計算每幀的時間刻度 Doption=0; % 用主體-延伸法基音檢測 [voiceseg,vosl,SF,Ef,period]=pitch_Ceps(x,wlen,inc,T1,fs); %基於倒譜法的基音週期檢測 Dpitch=pitfilterm1(period,voiceseg,vosl); % 對T0進行平滑處理求出基音週期T0 %% 共振峰提取 for i=1:length(SF) [Frmt(:,i),Bw(:,i),U(:,i)]=Formant_Root(X(:,i),p,fs,3); end %% 語音合成 zint=zeros(2,4); % 初始化 tal=0; for i=1 : fn yf=Frmt(:,i); % 取來i幀的三個共振峰頻率和頻寬 bw=Bw(:,i); [an,bn]=formant2filter4(yf,bw,fs); % 轉換成四個二階濾波器係數 synt_frame=zeros(wlen,1); if SF(i)==0 % 無話幀 excitation=randn(wlen,1); % 產生白噪聲 for k=1 : 4 % 對四個濾波器並聯輸入 An=an(:,k); Bn=bn(k); [out(:,k),zint(:,k)]=filter(Bn(1),An,excitation,zint(:,k)); synt_frame=synt_frame+out(:,k); % 四個濾波器輸出疊加在一起 end else % 有話幀 PT=round(Dpitch(i)); % 取週期值 exc_syn1 =zeros(wlen+tal,1); % 初始化脈衝發生區 exc_syn1(mod(1:tal+wlen,PT)==0)=1;% 在基音週期的位置產生脈衝,幅值為1 exc_syn2=exc_syn1(tal+1:tal+inc); % 計算幀移inc區間內的脈衝個數 index=find(exc_syn2==1); excitation=exc_syn1(tal+1:tal+wlen);% 這一幀的激勵脈衝源 if isempty(index) % 幀移inc區間內沒有脈衝 tal=tal+inc; % 計算下一幀的前導零點 else % 幀移inc區間內有脈衝 eal=length(index); % 計算有幾個脈衝 tal=inc-index(eal); % 計算下一幀的前導零點 end for k=1 : 4 % 對四個濾波器並聯輸入 An=an(:,k); Bn=bn(k); [out(:,k),zint(:,k)]=filter(Bn(1),An,excitation,zint(:,k)); synt_frame=synt_frame+out(:,k); % 四個濾波器輸出疊加在一起 end end Et=sum(synt_frame.*synt_frame); % 用能量歸正合成語音 rt=Etemp(i)/Et; synt_frame=sqrt(rt)*synt_frame; if i==1 % 若為第1幀 output=synt_frame; % 不需要重疊相加,保留合成數據 else M=length(output); % 按線性比例重疊相加處理合成資料 output=[output(1:M-overlap); output(M-overlap+1:M).*tempr2+... synt_frame(1:overlap).*tempr1; synt_frame(overlap+1:wlen)]; end
三、執行結果
四、備註
版本:2014a
完整程式碼或代寫加1564658423