【語音合成】基於matlab語音訊號變速【含Matlab原始碼 565期】
阿新 • • 發佈:2021-06-27
一、簡介
基於matlab語音訊號變速
二、原始碼
clear all; clc; close all; [xx,fs]=wavread('C7_4_y.wav'); % 讀取檔案 xx=xx-mean(xx); % 去除直流分量 x=xx/max(abs(xx)); % 歸一化 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; % 正頻率的下標值 X=enframe(x,wlen,inc)'; % 分幀 fn=size(X,2); % 幀數 T1=0.1; r2=0.5; % 端點檢測引數 miniL=10; % 有話段最短幀數 mnlong=5; % 母音主體最短幀數 ThrC=[10 15]; % 閾值 p=12; % LPC階次 frameTime=FrameTimeC(fn,wlen,inc,fs); % 計算每幀的時間刻度 in=input('請輸入伸縮語音的時間長度是原語音時間長度的倍數:','s');%輸入伸縮長度比例 rate=str2num(in); for i=1 : fn % 求取每幀的預測係數和增益 u=X(:,i); [ar,g]=lpc(u,p); AR_coeff(:,i)=ar; Gain(i)=g; end % 基音檢測 [voiceseg,vosl,SF,Ef,period]=pitch_Ceps(x,wlen,inc,T1,fs); %基於倒譜法的基音週期檢測 Dpitch=pitfilterm1(period,voiceseg,vosl); % 對T0進行平滑處理求出基音週期T0 tal=0; % 初始化 zint=zeros(p,1); %% LSP引數的提取 for i=1 : fn a2=AR_coeff(:,i); % 取來本幀的預測係數 lsf=lpctolsf(a2); % 呼叫ar2lsf函式求出lsf Glsf(:,i)=lsf; % 把lsf儲存在Glsf陣列中 end % 通過內插把相應陣列縮短或伸長 fn1=floor(rate*fn); % 設定新的總幀數fn1 Glsfm=interp1((1:fn),Glsf',linspace(1,fn,fn1))';% 把LSF係數內插 Dpitchm=interp1(1:fn,Dpitch,linspace(1,fn,fn1));% 把基音週期內插 Gm=interp1((1:fn),Gain,linspace(1,fn,fn1));%把增益係數內插 SFm=interp1((1:fn),SF,linspace(1,fn,fn1)); %把SF係數內插 %% 語音合成 for i=1:fn1; lsf=Glsfm(:,i); % 獲取本幀的lsf引數 ai=lsftolpc(lsf); % 呼叫lsf2ar函式把lsf轉換成預測係數ar sigma=sqrt(Gm(i)); if SFm(i)==0 % 無話幀 excitation=randn(wlen,1); % 產生白噪聲 [synt_frame,zint]=filter(sigma,ai,excitation,zint); else % 有話幀 PT=round(Dpitchm(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
三、執行結果
四、備註
版本:2014a
完整程式碼或代寫加1564658423