用matlab产生合成信号,《MATLAB在语音信号分析与合成中的应用》第10章语音合成问题...

本帖最后由 YJ2016 于 2016-9-22 17:26 编辑

《MATLAB在语音信号分析与合成中的应用》第10章,换用别的音频文件,程序pr10_4_1合成的语音有杂音,怎样可以合成清晰的语音?

%

% pr10_4_1

clear all; clc; close all;

filedir=[];                               % 设置数据文件的路径

filename='colorcloud.wav';% 设置数据文件的名称

fle=[filedir filename]                    % 构成路径和文件名的字符串

[xx,fs]=wavread(fle);                     % 读取文件

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

af5d80d43c9b6e247a4fd2033f52f198.gifverlap-1)'/overlap;            % 斜三角窗函数w1

tempr2=(overlap-1:-1:0)'/overlap;         % 斜三角窗函数w2

wind=hanning(wlen);                       % 窗函数

X=enframe(x,wind,inc)';                   % 分帧

fn=size(X,2);                             % 帧数

T1=0.1; r2=0.5;                           % 端点检测参数

miniL=10;                                 % 有话段最短帧数

mnlong=5;                                 % 元音主体最短帧数

ThrC=[10 15];                             % 阈值

p=12;                                     % LPC阶次

for i=1 : fn                              % 计算每帧的线性预测系数和增益

u=X(:,i);

[ar,g]=lpc(u,p);

AR_coeff(:,i)=ar;

Gain(i)=g;

end

% 基音检测

[Dpitch,Dfreq,Ef,SF,voiceseg,vosl,vseg,vsl,T2]=...

Ext_F0ztms(xx,fs,wlen,inc,T1,r2,miniL,mnlong,ThrC,0);

tal=0;                                    % 初始化前导零点

zint=zeros(p,1);

for i=1:fn;

ai=AR_coeff(:,i);                     % 获取第i帧的预测系数

sigma_square=Gain(i);                 % 获取第i帧的增益系数

sigma=sqrt(sigma_square);

if SF(i)==0                           % 无话帧

excitation=randn(wlen,1);         % 产生白噪声

[synt_frame,zint]=filter(sigma,ai,excitation,zint); % 用白噪声合成语音

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

gain=sigma/sqrt(1/PT);            % 增益

[synt_frame,zint]=filter(gain,ai,excitation,zint); % 用脉冲合成语音

end

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

af5d80d43c9b6e247a4fd2033f52f198.gifverlap).*tempr1; synt_frame(overlap+1:wlen)];

end

end

ol=length(output);                        % 把输出output延长至与输入信号xx等长

if ol

output1=[output; zeros(N-ol,1)];

else

output1=output(1:N);

end

bn=[0.964775   -3.858862   5.788174   -3.858862   0.964775]; % 滤波器系数

an=[1.000000   -3.928040   5.786934   -3.789685   0.930791];

output=filter(bn,an,output1);             % 高通滤波

output=output/max(abs(output));           % 幅值归一

% 通过声卡发音,比较原始语音和合成语音

sound(x,fs);

pause(3);

sound(output,fs);

%作图

figure(1)

subplot 211; plot(time,x,'k'); title('原始语音波形');

axis([0 max(time) -1 1.1]); xlabel('时间/s'); ylabel('幅值')

subplot 212; plot(time,output,'k');  title('合成语音波形');

axis([0 max(time) -1 1.1]); xlabel('时间/s'); ylabel('幅值')

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值