基于matlab实现对一段语音信号的处理,这些处理包括时域分析、频域分析、倒谱、能量谱和语谱图,并且可以将图形保存以便后续研究。
先用matlabGUI设计好界面
我的界面:
菜单界面
运行后于是就出现了这样的效果
下一步就是问题的核心为这些按钮添加回调函数callback
下面贴出我的程序和注释:
function varargout = sigany(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @sigany_OpeningFcn, ...
'gui_OutputFcn', @sigany_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before sigany is made visible.
function sigany_OpeningFcn(hObject, ~, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);
function varargout = sigany_OutputFcn(~, ~, handles)
varargout{1} = handles.output;
% --- Executes on button press in start.
% --------------------------------------------------------------------
function init_Callback(hObject, eventdata, handles)%清理内存 初始化
clear all;
clc;
% --------------------------------------------------------------------
function openexistdata_Callback(hObject, ~, handles)%打开音频,并显示时域波形
[FileName,PathName]= uigetfile('*.wav'); %打开对话框
if ~isequal(FileName, 0)
% open(file);
[y, fs]=wavread([PathName FileName]);%x是音频的数据向量,fs是采样频率(单位Hz),bits是每一个采样点的数据深度(即比特数)
end
handles.data=y; %x是向量含有的所有数字的个数,与数据的大小有关
handles.sample=fs; %采样的频率 一般为8k
t=length(handles.data)/fs; %采样的总时间
tt=0:t/length(handles.data):t; %中间计算出来的采样周期
handles.t=tt(1:length(tt)-1); %作为要显示图形的横坐标
guidata(hObject, handles); %保存更新
axes(handles.axes2); %打开的文件显示在第二个里
plot(handles.t,y); % ±ò¨
ylabel('signal Magnitude ');
xlabel('time(s)');
title('时域波形');
% --------------------------------------------------------------------
% --------------------------------------------------------------------
function wavsave_Callback(~, ~, handles) %时域保存
% hObject handle to wavsave (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
[file,path] = uiputfile('wave.jpg','Save file name'); %打开保存窗口
%~isempty(handles.data);
h=figure; %画图
plot(handles.t,handles.data);
saveas(h,[path file]); %保存
close(h);
% --------------------------------------------------------------------
function savefftpic_Callback(~, ~, handles)%频谱保存
% hObject handle to savefftpic (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
Fs=handles.sample; % 采样率
data=handles.data; % 样本向量
blockSize=length(data); % 样本大小
xFFT = fft(data); % 快速傅里叶变换
xfft = abs(xFFT); % 离散傅里叶变换的幅值
index = xfft == 0;
xfft(index) = 1e-17;
mag = 20*log10(xfft); %20倍的log以10为底求对数
mag = mag(1:blockSize/2); %只取前一半
%原因:对实信号fft,产生了负频率,由于FFT变化是对称的,
%所以负频率对应到了Fs/2~Fs上,对实信号而言,该段频率没有任何意义,
%所以只显示到Fs/2。
%f = (0:length(mag)-1)*Fs/blockSize;
f = (0:length(mag)-1)*Fs/blockSize; %求横坐标 频率序列
[file,path] = uiputfile('fft.jpg','Save file name'); %保存图片,同上
h=figure;
plot(f(:,1),mag(:,1));
ylabel('Magnitude (dB)');
xlabel('Frequency (Hz)');
title('频谱图');
saveas(h,[path file]);
close(h);
% --------------------------------------------------------------------
function picdaopusave_Callback(~, ~, handles)%倒谱保存
% hObject handle to picdaopusave (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
c=fft(log(abs(handles.data)+eps));% 取模 取对数 快速傅里叶 求出倒谱 eps返回参数的精度
ms1=handles.sample/1000;
ms20=handles.sample/50;
q=(ms1:ms20)/handles.sample; % 横坐标 时间序列
[file,path] = uiputfile('daopu.jpg','Save file name');
h=figure; %作图 保存
plot(q,abs(c(ms1:ms20)));
xlabel('倒角');
ylabel('倒谱幅度');
title('倒谱图');
saveas(h,[path file]);
close(h);
% --------------------------------------------------------------------
function picyupusave_Callback(~, ~, handles) %语谱图保存
% hObject handle to picyupusave (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
Winsiz=256;Shift=128;Base=0;%帧长 帧移植 基准电平值
signal=handles.data;
fs=handles.sample;
nseg=floor((length(signal)-Winsiz)/Shift)+1; %floor 朝负无穷方向舍入
A=zeros(Winsiz/2+1,nseg);
%下面循环是x信号的加窗处理并求出各点频谱能量
for i=1:nseg
n1=(i-1)*Shift+1;
n2=n1+(Winsiz-1);
xx=signal(n1:n2);
xx=xx.*hamming(Winsiz);
y=fft(xx);
y=y(1:Winsiz/2+1);
y=y.*conj(y);
y=10*log10(y);
A(:,i)=y;
end
L1=(A>Base);
L0=(A<Base);
B=A.*L1+Base*L0;
C=(B-Base)./(max(max(B))-Base);%灰度
y=[0:Winsiz/2]*fs/Winsiz; %纵坐标频率
x=[0:nseg-1]*Shift; %横坐标时间
%保存
[file,path] = uiputfile('yuputu.jpg','Save file name');
h=figure;
imagesc(x,y,C);axis xy;
saveas(h,[path file]);
close(h);
function picsaveglp_Callback(~, ~, handles)%功率谱保存
% hObject handle to picsaveglp (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
Fs=handles.sample; %
xn=handles.data;
window=rectwin(length(xn)); %矩形加窗
nfft=1024;
[Pxx,f]=periodogram(xn,window,nfft,Fs); %求功率谱的
[file,path] = uiputfile('gonglvpu.jpg','Save file name');%保存文件
h=figure;
plot(f,10*log10(Pxx));
title('功率谱');
saveas(h,[path file]);
close(h);
% --- Executes on button press in wavepos.
function wavepos_Callback(~, ~, handles) %时域回调
% hObject handle to wavepos (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
y=handles.data; % ù
axes(handles.axes2); % èúò
plot(handles.t,y); % 时域直接表示即可
ylabel('signal Magnitude ');
xlabel('time(s)');
title('时域波形');
function fftplot_Callback(~, ~, handles)%频域回调
% hObject handle to fftplot (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
Fs=handles.sample; % ù
data=handles.data; % ù
blockSize=length(data);
xFFT = fft(data); % 快速傅里叶变换
xfft = abs(xFFT); % 取模值
%index = xfft == 0;
%xfft(index) = 1e-17;
mag = 20*log10(xfft); % 转化成以dB为单位的数值
mag = mag(1:blockSize/2);
f = (0:length(mag)-1)*Fs/blockSize;
axes(handles.axes2);
plot(f(:,1),mag(:,1));
ylabel('Magnitude (dB)');
xlabel('Frequency (Hz)');
title('频谱图');
function glpbutton_Callback(hObject, eventdata, handles) %功率谱的
% hObject handle to glpbutton (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
ggp_Callback(hObject, eventdata, handles);
function daopu_Callback(~, ~, handles)%倒谱回调
% hObject handle to daopu (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
c=fft(log(abs(handles.data)+eps)); % ×
ms1=handles.sample/1000;
ms20=handles.sample/50;
q=(ms1:ms20)/handles.sample;
axes(handles.axes2);
plot(q,abs(c(ms1:ms20)));
xlabel('倒角');
ylabel('倒谱幅度');
title('倒谱图');
% --- Executes on button press in yuputu.
function yuputu_Callback(hObject, eventdata, handles) %语谱图回调
% hObject handle to yuputu (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
window_Callback(hObject, eventdata, handles) %菜单语谱图回调
function ggp_Callback(~, ~, handles) %菜单上的功率谱 回调
% hObject handle to ggp (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
Fs=handles.sample; %ù
xn=handles.data; %所求信号
window=boxcar(length(xn)); %加矩形窗,所用窗口
nfft=1024; %采样点数
[Pxx,f]=periodogram(xn,window,nfft,Fs); %直接求功率谱密度
plot(f,10*log10(Pxx));
title('功率谱');
function window_Callback(~, ~, handles) %菜单语谱图回调 同上边的语谱图保存
% hObject handle to window (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
Winsiz=256;Shift=128;Base=0;
signal=handles.data;
fs=handles.sample;
nseg=floor((length(signal)-Winsiz)/Shift)+1;
A=zeros(Winsiz/2+1,nseg);
for i=1:nseg
n1=(i-1)*Shift+1;n2=n1+(Winsiz-1);
xx=signal(n1:n2);xx=xx.*hamming(Winsiz);
y=fft(xx);y=y(1:Winsiz/2+1);
y=y.*conj(y);y=10*log10(y);A(:,i)=y;
end
L1=(A>Base);L0=(A<Base);B=A.*L1+Base*L0;
C=(B-Base)./(max(max(B))-Base);
y=[0:Winsiz/2]*fs/Winsiz;x=[0:nseg-1]*Shift;
axes(handles.axes2);
imagesc(x,y,C);axis xy;
function fftmenu_Callback(hObject, eventdata, handles) %菜单上的频域回调
% hObject handle to fftmenu (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
fftplot_Callback(hObject, eventdata, handles); %频域回调
% --------------------------------------------------------------------
function recps_Callback(hObject, eventdata, handles) %菜单上的倒谱回调
% hObject handle to recps (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
daopu_Callback(hObject, eventdata, handles);
% --- Executes when figure1 is resized.
function figure1_ResizeFcn(~, ~, ~)
% hObject handle to figure1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% --------------------------------------------------------------------
function datagetsve_Callback(hObject, eventdata, handles)
% hObject handle to datagetsve (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% --------------------------------------------------------------------
function analysis_Callback(~, eventdata, handles)
% hObject handle to analysis (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% --------------------------------------------------------------------
function picsave_Callback(hObject, eventdata, handles)
% hObject handle to picsave (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
最后三个函数没有内容,是系统自动生成的,如果删去,会提示错误,他们三个菜单的回调函数。至此,程序就可以运行了。
实践一下:打开一段音频自动显示时域图:
点击倒谱图
点击结果图形保存,选择语谱图保存,文件名为:我的语谱图
可见已经保存为jpg图片