1. 程式人生 > 其它 >【語音合成】基於matlab語音訊號變速【含Matlab原始碼 565期】

【語音合成】基於matlab語音訊號變速【含Matlab原始碼 565期】

一、簡介

基於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