基于MATLAB的多功能语音处理器
设计前的学习教程《图形界面处理(上)》《图形界面(下)》
一、设计功能
- 录制音频,保存音频
- 对录制的语音信号进行频谱分析,确定该段语音的主要频率范围;
- 利用采样定理,对该段语音信号进行采样,观察不用采样频率(过采样、欠采样、临界采样)对信号的影响;
- 实现语音信号的快放、慢放、倒放、男女变声;
- 对语音信号加噪,然后进行滤波,分析不同的滤波方式对信号的影响;
- 实现两音频的合成、拼接;
- 利用MATLAB GUI制作语音信号采集与分析演示系统;
二、设计步骤
1.创建GUI界面
2.新建空白界面
3.拖放控件,双击控件修改tag值和string
4.最后界面布置为图示,右键点击任何一个控件,进入回调函数callback。
5.在OpeningFcn中写入下面程序
% --- Executes just before functionalDSP is made visible. function functionalDSP_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to functionalDSP (see VARARGIN) % Choose default command line output for functionalDSP handles.output = hObject; % Update handles structure guidata(hObject, handles); h1=gcf; set(h1,\'Name\',\'多功能语音处理器\',\'Resize\',\'on\'); h2=uimenu(h1,\'label\',\'功能\'); h3=uimenu(h2,\'label\',\'基本功能\'); h4=uimenu(h2,\'label\',\'采样定理\'); h5=uimenu(h2,\'label\',\'快慢放\'); h6=uimenu(h2,\'label\',\'加噪去噪\'); h7=uimenu(h2,\'label\',\'滤波器设计\'); h8=uimenu(h2,\'label\',\'合成拼接\'); h12=uimenu(h1,\'label\',\'设计人员\'); h13=uimenu(h12,\'label\',\'孙宁宁\'); h14=uimenu(h12,\'label\',\'宝历\'); h15=uimenu(h12,\'label\',\'李佳桐\'); h16=uimenu(h12,\'label\',\'马宁泽\'); h17=uimenu(h12,\'label\',\'王璐\'); h18=uimenu(h12,\'label\',\'王智聪\'); % UIWAIT makes functionalDSP wait for user response (see UIRESUME) % uiwait(handles.h1);
6.编辑“录制1”功能
--- Executes on button press in record2.
function record2_Callback(hObject, eventdata, handles)
% hObject handle to record2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
r=audiorecorder(10000,16,1);
recordblocking(r, 3);
g=getaudiodata(r);
m=\'C:\Users\孙宁宁\Desktop\孙宁宁程序\x1.wav\';
audiowrite(m,g,10000);%将音频写入文件
7.编辑“录制2”功能
--- Executes on button press in record2. function record2_Callback(hObject, eventdata, handles) % hObject handle to record2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) r=audiorecorder(10000,16,1); recordblocking(r, 3); g=getaudiodata(r); m=\'C:\Users\孙宁宁\Desktop\孙宁宁程序\x2.wav\'; audiowrite(m,g,10000);%将音频写入文件
8.编辑“读取”功能
%读取信号
function read_Callback(hObject, eventdata, handles)
% hObject handle to read (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
[filename, pathname]=uigetfile({\'.\'},\'读取音频文件\');
%文件打开对话框,返回文件名和文件路径,当文件存在时会成功返回,如果不存在,则返回不存在。
if isequal([filename pathname],[0,0])%用户取消对话框返回0
return;
end
str=[pathname filename];%将文件名和路径名组合为一个字符串,赋值给str。
[x1,Fs]=audioread(str);%读取声音信号,采样值放在向量x1中,fs为采样频率
x=x1(:,1); %对双声道信号取单声道,如果是x=x1(1:5000,1),则表示取了5000点。
handles.y1=x;%将原先采样的序列向量x给句柄y1
handles.Fs=Fs;%采样频率句柄
guidata(hObject,handles);%储存handles
9.编辑“分析”功能
% --- Executes on button press in original.
function original_Callback(hObject, eventdata, handles)
% hObject handle to original (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
fs1=handles.Fs;%fs1为原信号的采样频率
Y=handles.y1;%Y为原采样的原信号
Y=Y(:,1);%取单值
sound(Y,fs1);%播放声音
M=length(Y);%M为信号长度
t=0:1/fs1:(M-1)/fs1;%傅里叶变换时间长度(30000个点,变换为以s为单位)
plot(handles.shiyu1,t,Y);%绘制时域图
xlabel(handles.shiyu1,\'时间/s\');
ylabel(handles.shiyu1,\'幅度\');
title(handles.shiyu1,\'原声时域图\');
F=fft(Y,M);%快速傅里叶变换
f=linspace(-fs1/2,fs1/2,length(Y)+1);
f(end) = [];;%频率序列(0~50000个点)
plot(handles.pinyu1,f,abs(F));%绘制频谱图
title(handles.pinyu1,\'原声频谱图\');
xlabel(handles.pinyu1,\'频率/Hz\');
ylabel(handles.pinyu1,\'幅值\');
10.编辑“原信号”功能
function origin_Callback(hObject, eventdata, handles) % hObject handle to origin (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) wm=10; wc=wm; Ts=pi/wm; ws=2*pi/Ts; n=-100:100; nTs=n*Ts; f=sinc(nTs/pi); t=-20:0.2:20; f=sinc(t/pi); N=length(f); plot(handles.shiyu1,t,f);%绘制时域图 xlabel(handles.shiyu1,\'时间/s\'); ylabel(handles.shiyu1,\'幅度\'); title(handles.shiyu1,\'原信号时域图\'); F=fft(f);%快速傅里叶变换 f=[0:N-1]*wc/N;%频率序列 plot(handles.pinyu1,f,abs(F));%绘制频谱图 title(handles.pinyu1,\'原信号频谱图\'); xlabel(handles.pinyu1,\'频率/Hz\'); ylabel(handles.pinyu1,\'幅值\');
11.编辑“欠采样”功能
% --- Executes on button press in qian. function qian_Callback(hObject, eventdata, handles) % hObject handle to qian (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) wm=10;%带宽 wc=wm;%频率 Ts=2*pi/wm;%周期 ws=2*pi/Ts; n=-100:100; nTs=n*Ts; f=sinc(nTs/pi); N=length(f); t=-20:0.2:20; stem(handles.shiyu4,t,f);%绘制时域图 xlabel(handles.shiyu4,\'时间/s\'); ylabel(handles.shiyu4,\'幅度\'); title(handles.shiyu4,\'欠采样时域图\'); F=fft(f);%快速傅里叶变换 f=[0:N-1]*wc/N;%频率序列 plot(handles.pinyu4,f,abs(F));%绘制频谱图 title(handles.pinyu4,\'欠采样频谱图\'); xlabel(handles.pinyu4,\'频率/Hz\'); ylabel(handles.pinyu4,\'幅值\');
12.编辑“临界采样”功能
% --- Executes on button press in lincai. function lincai_Callback(hObject, eventdata, handles) % hObject handle to lincai (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) wm=10;%带宽 wc=wm;%频率 Ts=pi/wm;%周期 ws=2*pi/wm; n=-100:100; nTs=n*Ts; f=sinc(nTs/pi); t=-20:0.2:20; N=length(f); stem(handles.shiyu3,t,f);%绘制时域图 xlabel(handles.shiyu3,\'时间/s\'); ylabel(handles.shiyu3,\'幅度\'); title(handles.shiyu3,\'临界采样时域图\'); F=fft(f);%快速傅里叶变换 f=[0:N-1]*wc/N;%频率序列 plot(handles.pinyu3,f,abs(F));%绘制频谱图 title(handles.pinyu3,\'临界采样频谱图\'); xlabel(handles.pinyu3,\'频率/Hz\'); ylabel(handles.pinyu3,\'幅值\');
13.编辑“过采样”功能
% --- Executes on button press in guo. function guo_Callback(hObject, eventdata, handles) % hObject handle to guo (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) wm=10; wc=wm; Ts=0.5*pi/wm; ws=2*pi/Ts; n=-100:100; nTs=n*Ts; f=sinc(nTs/pi); t=-20:0.2:20; f=sinc(t/pi); N=length(f); stem(handles.shiyu2,t,f);%绘制时域图 xlabel(handles.shiyu2,\'时间/s\'); ylabel(handles.shiyu2,\'幅度\'); title(handles.shiyu2,\'过采样时域图\'); F=fft(f);%快速傅里叶变换 f=[0:N-1]*wc/N;%频率序列 plot(handles.pinyu2,f,abs(F));%绘制频谱图 title(handles.pinyu2,\'过采样频谱图\'); xlabel(handles.pinyu2,\'频率/Hz\'); ylabel(handles.pinyu2,\'幅值\');
14.编辑“倒放”功能
% --- Executes on button press in dao.
function dao_Callback(hObject, eventdata, handles)
% hObject handle to dao (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
dfs=handles.Fs;
dy=handles.y1;
M=length(dy):-1:1;%M序列颠倒
rY=dy(M);%颠倒后的信号
sound(rY,dfs);%倒放
t=0:1/dfs:(length(rY)-1)/dfs;%时间序列
plot(handles.shiyu2,t,rY);%绘制时域图
xlabel(handles.shiyu2,\'时间/s\');
ylabel(handles.shiyu2,\'幅度\');
title(handles.shiyu2,\'倒放时域图\');
F=fft(rY,length(rY));%快速傅里叶变换
f=[0:length(dy)-1]*dfs/length(dy);%频率序列
plot(handles.pinyu2,f,abs(F));%绘制频谱图
title(handles.pinyu2,\'倒放频谱图\');
xlabel(handles.pinyu2,\'频率/Hz\');
ylabel(handles.pinyu2,\'幅值\');
15.编辑“快放”功能
% --- Executes on button press in kuai.
function kuai_Callback(hObject, eventdata, handles)
% hObject handle to kuai (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
kfs=3*handles.Fs; %fs2为采样频率
kx=handles.y1;%mx为原信号
sound(kx,kfs);
M=length(kx);%M为信号长度
t=0:1/kfs:(M-1)/kfs;%傅里叶变换时间长度
plot(handles.shiyu3,t,kx);%绘制时域图
xlabel(handles.shiyu3,\'时间/s\');
ylabel(handles.shiyu3,\'幅度\');
title(handles.shiyu3,\'快放时域图\');
F=fft(kx,M);%快速傅里叶变换
f=[0:M-1]*kfs/M;%频率序列
plot(handles.pinyu3,f,abs(F));%绘制频谱图
title(handles.pinyu3,\'快放频谱图\');
xlabel(handles.pinyu3,\'频率/Hz\');
ylabel(handles.pinyu3,\'幅值\');
16.编辑“慢放”功能
% --- Executes on button press in man.
function man_Callback(hObject, eventdata, handles)
% hObject handle to man (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
mfs=0.7*handles.Fs; %fs2为采样频率
mx=handles.y1;%mx为原信号
sound(mx,mfs);
M=length(mx);%M为信号长度
t=0:1/mfs:(M-1)/mfs;%傅里叶变换时间长度
plot(handles.shiyu4,t,mx);%绘制时域图
xlabel(handles.shiyu4,\'时间/s\');
ylabel(handles.shiyu4,\'幅度\');
title(handles.shiyu4,\'慢放时域图\');
F=fft(mx,M);%快速傅里叶变换
f=[0:M-1]*mfs/M;%频率序列
plot(handles.pinyu4,f,abs(F));%绘制频谱图
title(handles.pinyu4,\'慢放频谱图\');
xlabel(handles.pinyu4,\'频率/Hz\');
ylabel(handles.pinyu4,\'幅值\');
17.编辑“音一”功能
function yin1_Callback(hObject, eventdata, handles) % hObject handle to yin1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) [filename, pathname]=uigetfile({\'.\'},\'读取音频文件\'); %文件打开对话框,返回文件名和文件路径,当文件存在时会成功返回,如果不存在,则返回不存在。 if isequal([filename pathname],[0,0])%用户取消对话框返回0 return; end str=[pathname filename];%将文件名和路径名组合为一个字符串,赋值给str。 [x1,Fs]=audioread(str);%读取声音信号,采样值放在向量x1中,fs为采样频率 x=x1(:,1); %对双声道信号取单声道,如果是x=x1(1:5000,1),则表示取了5000点。 Y=x;%取单值 fs1=Fs; sound(Y,fs1);%播放声音 M=length(Y);%M为信号长度 t=0:1/fs1:(M-1)/fs1;%傅里叶变换时间长度(30000个点,变换为以s为单位) plot(handles.shiyu1,t,Y);%绘制时域图 xlabel(handles.shiyu1,\'时间/s\'); ylabel(handles.shiyu1,\'幅度\'); title(handles.shiyu1,\'音一时域图\'); F=fft(Y,M);%快速傅里叶变换 f=[0:M-1]*fs1/M;%频率序列(0~50000个点) plot(handles.pinyu1,f,abs(F));%绘制频谱图 title(handles.pinyu1,\'音一频谱图\'); xlabel(handles.pinyu1,\'频率/Hz\'); ylabel(handles.pinyu1,\'幅值\'); handles.y2=x;%将原先采样的序列向量x给句柄y1 handles.Fs2=Fs;%采样频率句柄 guidata(hObject,handles);%储存handles
18.编辑“音二”功能
% --- Executes on button press in yin2. function yin2_Callback(hObject, eventdata, handles) % hObject handle to yin2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) [filename, pathname]=uigetfile({\'.\'},\'读取音频文件\'); %文件打开对话框,返回文件名和文件路径,当文件存在时会成功返回,如果不存在,则返回不存在。 if isequal([filename pathname],[0,0])%用户取消对话框返回0 return; end str=[pathname filename];%将文件名和路径名组合为一个字符串,赋值给str。 [x1,Fs]=audioread(str);%读取声音信号,采样值放在向量x1中,fs为采样频率 x=x1(:,1); %对双声道信号取单声道,如果是x=x1(1:5000,1),则表示取了5000点。 Y=x;%取单值 fs1=Fs; sound(Y,fs1);%播放声音 M=length(Y);%M为信号长度 t=0:1/fs1:(M-1)/fs1;%傅里叶变换时间长度(30000个点,变换为以s为单位) plot(handles.shiyu2,t,Y);%绘制时域图 xlabel(handles.shiyu2,\'时间/s\'); ylabel(handles.shiyu2,\'幅度\'); title(handles.shiyu2,\'音二时域图\'); F=fft(Y,M);%快速傅里叶变换 f=[0:M-1]*fs1/M;%频率序列(0~50000个点) plot(handles.pinyu2,f,abs(F));%绘制频谱图 title(handles.pinyu2,\'音二频谱图\'); xlabel(handles.pinyu2,\'频率/Hz\'); ylabel(handles.pinyu2,\'幅值\'); handles.y3=x;%将原先采样的序列向量x给句柄y1 handles.Fs3=Fs;%采样频率句柄 guidata(hObject,handles);%储存handles
19.编辑“合成”功能
% --- Executes on button press in hecheng.
function hecheng_Callback(hObject, eventdata, handles)
% hObject handle to hecheng (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
y=handles.y2;
fs=handles.Fs2;
y2=handles.y3;
[m,n]=size(y);%查看y的大小
[m2,n2]=size(y2);%查看y2的大小
z=zeros(max(m,m2)-min(m,m2),n);%生成一个零矩阵
if length(y)<length(y2);
y1=[y;z];%将y与零矩阵z组合,变成一个与Y2同等大小的矩阵
new=y1+y2;%生成的新的矩阵与y2相加,得到新的音频的矩阵
sound(new,fs);%播放新的音频
else
y1=[y2;z];%同上,当y2的长度较小时,将零矩阵和Y2组合
new=y1+y;%生成新的矩阵和Y相加
sound(new,fs);%播放
end;
time_new=(1:length(new))/fs;
N=length(new);
plot(handles.shiyu3,time_new,new);
xlabel(handles.shiyu3,\'时间/s\');
ylabel(handles.shiyu3,\'幅度\');
title(handles.shiyu3,\'拼接信号时域图\');
F=fft(new);%快速傅里叶变换
f=[0:N-1]*fs/N;%频率序列
plot(handles.pinyu3,f,abs(F));%绘制频谱图
title(handles.pinyu3,\'原信号频谱图\');
xlabel(handles.pinyu3,\'频率/Hz\');
ylabel(handles.pinyu3,\'幅值\');
20.编辑“拼接”功能
% --- Executes on button press in pj.
function pj_Callback(hObject, eventdata, handles)
% hObject handle to pj (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
y=handles.y2;
fs=handles.Fs2;
y2=handles.y3;
[m,n]=size(y);%查看y的大小
[m2,n2]=size(y2);%查看y2的大小
z=zeros(max(m,m2)-min(m,m2),n);%生成一个零矩阵
if length(y)<=length(y2);
y1=[y;z];%将y与零矩阵z组合,变成一个与Y2同等大小的矩阵
new=[y1;y2];%生成的新的矩阵与y2相加,得到新的音频的矩阵
sound(new,fs);%播放新的音频
else
y1=[y2;z];%同上,当y2的长度较小时,将零矩阵和Y2组合
new=[y1;y2];%生成新的矩阵和Y相加
sound(new,fs);%播放
end;
time_new=(1:length(new))/fs;
N=length(new);
plot(handles.shiyu4,time_new,new);
xlabel(handles.shiyu4,\'时间/s\');
ylabel(handles.shiyu4,\'幅度\');
title(handles.shiyu4,\'拼接信号时域图\');
F=fft(new);%快速傅里叶变换
f=[0:N-1]*fs/N;%频率序列
plot(handles.pinyu4,f,abs(F));%绘制频谱图
title(handles.pinyu4,\'原信号频谱图\');
xlabel(handles.pinyu4,\'频率/Hz\');
ylabel(handles.pinyu4,\'幅值\');
21.编辑“加噪”功能
% --- Executes on button press in jia.
function jia_Callback(hObject, eventdata, handles)
% hObject handle to jia (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
fs=handles.Fs;
x=handles.y1;
y=x(:,1); %取一行提取矩阵
noise=0.2*sin(pi*20000*(1:length(y))/fs)+0.3*sin(pi*21000*(1:length(y))/fs)...
+0.4*sin(pi*22000*(1:length(y))/fs);%噪声 10000rad/s+10500+11000
VNnoise=y+noise\';%向量维度一致
F = fft(VNnoise);
freq = linspace(-fs/2,fs/2,length(VNnoise)+1);
freq(end) = [];
t1=1:length(VNnoise);
t=t1/fs;
plot(handles.shiyu3,t,VNnoise)
xlabel(handles.shiyu3,\'时间\');
ylabel(handles.shiyu3,\'幅度\');
title(handles.shiyu3,\'加噪的时域图\');
plot(handles.pinyu3,freq,abs(fftshift(F)));
xlabel(handles.pinyu3,\'圆频率\');
ylabel(handles.pinyu3,\'幅度\');
title(handles.pinyu3,\'加噪的频谱图\');
sound(VNnoise,fs);
22.编辑“去噪”功能
function qu_Callback(hObject, eventdata, handles) % hObject handle to qu (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) qfs=handles.Fs; X=handles.y1; y=X(:,1); %取一行提取矩阵 n=0.2*sin(pi*20000*(1:length(y))/qfs)+0.3*sin(pi*21000*(1:length(y))/qfs)+0.4*sin(pi*22000*(1:length(y))/qfs);%噪声 10000rad/s+10500+11000 jz=y+n\';%向量维度一致 %[b,a] = butter(8,5000*2/fs,\'LOW\') ; %巴特沃斯滤波器 %result=filter(b,a,VNnoise); Hd = ditong1;%Fdatool滤波 result=filter(Hd,X); result=result(:,1); sound(result,qfs); F = fft(result); freq = linspace(-qfs/2,qfs/2,length(result)+1); freq(end) = []; t1=1:length(result); t=t1/qfs; plot(handles.shiyu4,t,result) xlabel(handles.shiyu4,\'时间\'); ylabel(handles.shiyu4,\'幅度\'); title(handles.shiyu4,\'去噪的时域图\'); plot(handles.pinyu4,freq,abs(fftshift(F))); xlabel(handles.pinyu4,\'频率\'); ylabel(handles.pinyu4,\'幅度\'); title(handles.pinyu4,\'去噪的频谱图\');
23.编辑“回声”功能
% --- Executes on button press in hui. function hui_Callback(hObject, eventdata, handles) % hObject handle to hui (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) fs=handles.Fs; y=handles.y1; x1=[zeros(9000,1);y]; x2=[y;zeros(9000,1)]; z=x1+x2; sound(2*z,fs); F=fft(z); f=linspace(-fs/2,fs/2,length(z)+1); f(end) = []; t1=1:length(z); t=t1/fs; plot(handles.shiyu2,t,z); title(handles.shiyu2,\'加入回音时域图\'); xlabel(handles.shiyu2,\'时间\'); ylabel(handles.shiyu2,\'幅度\'); plot(handles.pinyu2,f,abs(F)); xlabel(handles.pinyu2,\'圆频率\'); ylabel(handles.pinyu2,\'幅度\'); title(handles.pinyu2,\'加入回音频谱图\'); sound(z,fs);
24.编辑“去回声”功能
% --- Executes on button press in lv. function lv_Callback(hObject, eventdata, handles) % hObject handle to lv (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) fs=handles.Fs; y=handles.y1; N=length(y); x1=[zeros(9000,1);y]; x2=[y;zeros(9000,1)]; z=x1+x2; b=1; a=zeros(1,N); a(1)=1; a(9001)=1; z2=filter(b,a,z); F=fft(z2); f=linspace(-fs/2,fs/2,length(z2)+1); f(end) = []; t1=1:length(z2); t=t1/fs; plot(handles.shiyu4,t,z2); title(handles.shiyu4,\'滤除回音时域图\'); xlabel(handles.shiyu4,\'时间\'); ylabel(handles.shiyu4,\'幅度\'); plot(handles.pinyu4,f,abs(F)); xlabel(handles.pinyu4,\'频率\'); ylabel(handles.pinyu4,\'幅度\'); title(handles.pinyu4,\'滤除回音频谱图\'); sound(z2,fs);
25.编辑“男女声转化”功能
% --- Executes on button press in nv. function nv_Callback(hObject, eventdata, handles) % hObject handle to nv (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) FL = 80 ; % 帧移 WL = 240 ; % 窗长 P = 10 ; %预测系数个数 s = handles.y1; fs = handles.Fs; % 定义常数 s = s/max(s); % 归一化 L = length(s); % 读入语音长度 FN = floor(L/FL)-2; % 计算帧长,floor;向负无穷方向 % 预测和重建滤波器 exc = zeros(L,1); % 激励信号,double类零矩阵L行1列 zi_pre = zeros(P,1); % 预测滤波器状态 s_rec = zeros(L,1); % 重建语音 zi_rec = zeros(P,1); % 变调滤波器 exc_syn_t = zeros(L,1); % 合成的激励信号,创建一个L行1列的0脉冲 s_syn_t = zeros(L,1); % 合成语音 last_syn_t = 0; % 存储上一个段的最后一个脉冲的下标 zi_syn_t = zeros(P,1); % 合成滤波器 hw = hamming(WL); %汉明窗 %滤波器 % 依次处理每帧语音 for n = 3:FN %从第三个子数组开始 % 计算预测系数 s_w = s(n*FL-WL+1:n*FL).*hw; %汉明窗加权 [A,E]=lpc(s_w,P); %线性预测计算预测系数 % A是预测系数,E会被用来计算合成激励的能量 s_f=s((n-1)*FL+1:n*FL); % 本帧语音 %利用filter函数重建语音 [exc1,zi_pre] = filter(A,1,s_f,zi_pre); exc((n-1)*FL+1:n*FL) = exc1; %计算激励 %利用filter函数重建语音 [s_rec1,zi_rec] = filter(1,A,exc1,zi_rec); s_rec((n-1)*FL+1:n*FL) = s_rec1; %重建语音 % 下面只有得到exc后才可以 s_Pitch = exc(n*FL-222:n*FL); PT(n) = findpitch(s_Pitch); %计算基音周期pt G = sqrt(E*PT(n)); %计算合成激励的能量G PT1 =floor(PT(n)/2); %减小基音周期 poles = roots(A); deltaOMG =100*2*pi/fs; for p=1:10 %增加共振峰 if imag(poles(p))>0 poles(p) = poles(p)*exp(1j*deltaOMG); elseif imag(poles(p))<0 poles(p) = poles(p)*exp(-1j*deltaOMG); end end A1=poly(poles); tempn_syn_t=(1:n*FL-last_syn_t); exc_syn1_t = zeros(length(tempn_syn_t),1); exc_syn1_t(mod(tempn_syn_t,PT1)==0) = G; exc_syn1_t = exc_syn1_t((n-1)*FL-last_syn_t+1:n*FL-last_syn_t); [s_syn1_t,zi_syn_t] = filter(1,A1,exc_syn1_t,zi_syn_t); exc_syn_t((n-1)*FL+1:n*FL) = exc_syn1_t; %合成激励 s_syn_t((n-1)*FL+1:n*FL) = s_syn1_t; %合成语音 last_syn_t = last_syn_t+PT1*floor((n*FL-last_syn_t)/PT1); end Y = s_syn_t; F = fft(Y); freq = linspace(-fs/2,fs/2,length(Y)+1); freq(end) = []; plot(handles.pinyu2,freq,abs(fftshift(F))); xlabel(handles.pinyu2,\'圆频率\'); ylabel(handles.pinyu2,\'幅度\'); title(handles.pinyu2,\'频率特性
请发表评论