信号处理实验实验八:音频频谱分析仪设计与实现一、实验名称:音频频谱分析仪设计与实现二、实验原理:MATLAB是一个数据信息和处理功能十分强大的工程实用软件,其数据采集工具箱为实现数据的输入和输出提供了十分方便的函数和命令。
本实验可以用MATLAB进行音频信号频谱分析仪的设计与实现。
1、信号频率、幅值和相位估计(1)频率(周期)检测对周期信号来说,可以用时域波形分析来确定信号的周期,也就是计算相邻的两个信号波峰的时间差、或过零点的时间差。
这里采用过零点(ti)的时间差T(周期)。
频率即为f = 1/T,由于能够求得多个T值(ti有多个),故采用它们的平均值作为周期的估计值。
(2)幅值检测在一个周期内,求出信号最大值ymax与最小值ymin的差的一半,即A = (ymax - ymin)/2,同样,也会求出多个A值,但第1个A值对应的ymax和ymin不是在一个周期内搜索得到的,故以除第1个以外的A值的平均作为幅值的估计值。
(3)相位检测采用过零法,即通过判断与同频零相位信号过零点时刻,计算其时间差,然后换成相应的相位差。
φ=2π(1-ti/T),{x}表示x的小数部分,同样,以φ的平均值作为相位的估计值。
频率、幅值和相位估计的流程如图所示。
其中tin表示第n个过零点,yi为第i个采样点的值,Fs为采样频率。
2、数字信号统计量估计(1) 峰值P的估计在样本数据x中找出最大值与最小值,其差值为双峰值,双峰值的一半即为峰值。
P=0.5[max(yi)-min(yi)](2)均值估计式中,N为样本容量,下同。
(3) 均方值估计(4)方差估计2、频谱分析原理时域分析只能反映信号的幅值随时间的变化情况,除单频率分量的简单波形外,很难明确提示信号的频率组成和各频率分量大小,而频谱分析能很好的解决此问题。
(1)DFT与FFT对于给定的时域信号y,可以通过Fourier变换得到频域信息Y。
Y可按下式计算式中,N为样本容量,Δt = 1/Fs为采样间隔。
采样信号的频谱是一个连续的频谱,不可能计算出所有的点的值,故采用离散Fourier 变换(DFT),即式中,Δf = Fs/N。
但上式的计算效率很低,因为有大量的指数(等价于三角函数)运算,故实际中多采用快速Fourier变换(FFT)。
其原理即是将重复的三角函数算计的中间结果保存起来,以减少重复三角函数计算带来的时间浪费。
由于三角函数计算的重复量相当大,故FFT能极大地提高运算效率。
(2)频率、周期的估计对于Y(kΔf),如果当kΔf = 时,Y(kΔf)取最大值,则为频率的估计值,由于采样间隔的误差,也存在误差,其误差最大为Δf / 2。
周期T=1/f。
从原理上可以看出,如果在标准信号中混有噪声,用上述方法仍能够精确地估计出原标准信号的频率和周期,这个将在下一章做出验证3、频谱图为了直观地表示信号的频率特性,工程上常常将Fourier变换的结果用图形的方式表示,即频谱图。
以频率f为横坐标,|Y(f)|为纵坐标,可以得到幅值谱;以频率f为横坐标,arg Y(f)为纵坐标,可以得到相位谱;以频率f为横坐标,Re Y(f)为纵坐标,可以得到实频谱;以频率f为横坐标,Im Y(f)为纵坐标,可以得到虚频谱。
根据采样定理,只有频率不超过Fs/2的信号才能被正确采集,即Fourier变换的结果中频率大于Fs/2的部分是不正确的部分,故不在频谱图中显示。
即横坐标f ∈[0, Fs/2]4、模块划分模块化就是把程序划分成独立命名且可独立访问的模块,每个模块完成一个子功能,把这些模块集成起来构成一个整体,可以完成指定的功能满足用户需求。
根据人类解决一般问题的经验,如果一个问题由两个问题组合而成,那么它的复杂程度大于分别考虑每个问题时的复杂程度之和,也就是说把复杂的问题分解成许多容易解决的小问题,原来的问题也就容易解决了。
这就是模块化的根据。
在模块划分时应遵循如下规则:改进软件结构提高模块独立性;模块规模应该适中;深度、宽度、扇出和扇入都应适当;模块的作用域应该在控制域之内;力争降低模块接口的复杂程度;设计单入口单出口的模块;模块功能应该可以预测。
三、实验要求:参考以上原理,查阅相关资料,构建交互界面,设计一个音频频谱分析仪,实现一下功能:(1)音频信号信号输入,从声卡输入、从W A V文件输入、从标准信号发生器输入;(2)信号波形分析,包括幅值、频率、周期、相位的估计,以及统计量峰值、均值、均方值和方差的计算;(3)信号频谱分析,频率、周期的估计,图形显示幅值谱、相位谱、实频谱、虚频谱和功率谱的曲线。
四、实验界面及程序程序:function varargout = yinpin(varargin)% YINPIN M-file for yinpin.fig% YINPIN, by itself, creates a new YINPIN or raises the existing% singleton*.%% H = YINPIN returns the handle to a new YINPIN or the handle to% the existing singleton*.%% YINPIN('CALLBACK',hObject,eventData,handles,...) calls the local% function named CALLBACK in YINPIN.M with the given input arguments.%% YINPIN('Property','Value',...) creates a new YINPIN or raises the% existing singleton*. Starting from the left, property value pairs are% applied to the GUI before yinpin_OpeningFunction gets called. An% unrecognized property name or invalid value makes property application% stop. All inputs are passed to yinpin_OpeningFcn via varargin.%% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one% instance to run (singleton)".%% See also: GUIDE, GUIDATA, GUIHANDLES% Edit the above text to modify the response to help yinpin% Last Modified by GUIDE v2.5 07-Nov-2012 17:08:53% Begin initialization code - DO NOT EDITgui_Singleton = 1;gui_State = struct('gui_Name', mfilename, ...'gui_Singleton', gui_Singleton, ...'gui_OpeningFcn', @yinpin_OpeningFcn, ...'gui_OutputFcn', @yinpin_OutputFcn, ...'gui_LayoutFcn', [] , ...'gui_Callback', []);if nargin && ischar(varargin{1})gui_State.gui_Callback = str2func(varargin{1});endif nargout[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});elsegui_mainfcn(gui_State, varargin{:});endfunction yinpin_OpeningFcn(hObject, eventdata, handles, varargin)handles.output = hObject;guidata(hObject, handles);function varargout = yinpin_OutputFcn(hObject, eventdata, handles)varargout{1} = handles.output;function edit1_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction caiyangpinlv_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction caiyangdianshu_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction luyin_Callback(hObject, eventdata, handles)set(handles.luyin,'value',1);set(handles.wavfile,'value',0);set(handles.xinhaofasheng,'value',0);h=findobj('Tag','recordtime');set(h,'enable','on');h=findobj('Tag','kaishiluyin');set(h,'enable','on');h=findobj('Tag','wavname');set(h,'enable','off');h=findobj('Tag','liulan');set(h,'enable','off');h=findobj('Tag','inwave');set(h,'enable','off');h=findobj('Tag','infudu');set(h,'enable','off');h=findobj('Tag','infre');set(h,'enable','off');h=findobj('Tag','inphase');set(h,'enable','off');h=findobj('Tag','mix');set(h,'enable','off');h=findobj('Tag','shengchengboxing');set(h,'enable','off');function wavfile_Callback(hObject, eventdata, handles)set(handles.luyin,'value',0);set(handles.wavfile,'value',1);set(handles.xinhaofasheng,'value',0);h=findobj('Tag','recordtime');set(h,'enable','off');h=findobj('Tag','kaishiluyin');set(h,'enable','off');h=findobj('Tag','wavname');set(h,'enable','on');h=findobj('Tag','liulan');set(h,'enable','on');h=findobj('Tag','inwave');set(h,'enable','off');h=findobj('Tag','infudu');set(h,'enable','off');h=findobj('Tag','infre');set(h,'enable','off');h=findobj('Tag','inphase');set(h,'enable','off');h=findobj('Tag','mix');set(h,'enable','off');h=findobj('Tag','shengchengboxing');set(h,'enable','off');function xinhaofasheng_Callback(hObject, eventdata, handles)set(handles.luyin,'value',0);set(handles.wavfile,'value',0);set(handles.xinhaofasheng,'value',1);h=findobj('Tag','recordtime');set(h,'enable','off');h=findobj('Tag','kaishiluyin');set(h,'enable','off');h=findobj('Tag','wavname');set(h,'enable','off');h=findobj('Tag','liulan');set(h,'enable','off');h=findobj('Tag','inwave');set(h,'enable','on');h=findobj('Tag','infudu');set(h,'enable','on');h=findobj('Tag','infre');set(h,'enable','on');h=findobj('Tag','inphase');set(h,'enable','on');h=findobj('Tag','mix');set(h,'enable','on');h=findobj('Tag','shengchengboxing');set(h,'enable','on');function recordtime_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction kaishiluyin_Callback(hObject, eventdata, handles)Fs=str2double(get(handles.caiyangpinlv,'String'));N=str2double(get(handles.recordtime,'String'))*Fs;handles.y=wavrecord(N, Fs,'double');handles.inputtype=1;guidata(hObject,handles);plot(handles.fenxiduixiang,handles.y);ysize=size(handles.y);set(handles.caiyangdianshu,'String',num2str(ysize(1)));function wavname_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction liulan_Callback(hObject, eventdata, handles)[filename,filepath]=uigetfile('*.wav','wavfile');set(handles.wavname,'string',filename);[handles.y,Fs,bit]=wavread(filename);handles.inputtype=2;guidata(hObject,handles);plot(handles.fenxiduixiang,(1:length(handles.y)/10)/Fs,handles.y(1:length(handles.y)/10)); ysize=size(handles.y);set(handles.caiyangdianshu,'String',num2str(ysize(1)));set(handles.caiyangpinlv,'string',Fs);function listbox2_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction inwave_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction infudu_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction infre_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction inphase_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction shengchengboxing_Callback(hObject, eventdata, handles)Fs=str2double(get(findobj('Tag','caiyangpinlv'),'String'));N=str2double(get(findobj('Tag','caiyangdianshu'),'String'));x=linspace(0,N/Fs,N);soundtype=get(handles.inwave,'Value');frequency=str2double(get(handles.infre,'String'));amp=str2double(get(handles.infudu,'String'));phase=str2double(get(handles.inphase,'String'));switch soundtypecase 1y=amp*sin(2*pi*x*frequency+phase);handles.inputtype=3;case 2y=amp*sign(sin(2*pi*x*frequency+phase));handles.inputtype=3;case 3y=amp*sawtooth(2*pi*x*frequency+phase,0.5);handles.inputtype=3;case 4y=amp*sawtooth(2*pi*x*frequency+phase);handles.inputtype=3;case 5y=amp*(2*rand(size(x))-1);handles.inputtype=4;endif get(handles.mix,'Value')==0.0handles.y=y;elsehandles.y=handles.y+y;endguidata(hObject,handles);plot(handles.fenxiduixiang,handles.y);title('WA VE');axis([0 N -str2double(get(handles.infudu,'String')) str2double(get(handles.infudu,'String'))]); function edit11_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction edit12_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction popupmenu3_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction edit13_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction edit14_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction edit15_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction edit9_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction edit10_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction circle_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction outfreq_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction outamp_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');endfunction outphase_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');end% --- Executes during object creation, after setting all properties.function outpeak_CreateFcn(hObject, eventdata, handles)% hObject handle to outpeak (see GCBO)% eventdata reserved - to be defined in a future version of MA TLAB% handles empty - handles not created until after all CreateFcns called% Hint: edit controls usually have a white background on Windows.% See ISPC and COMPUTER.if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');end% --- Executes during object creation, after setting all properties.function outmean_CreateFcn(hObject, eventdata, handles)% hObject handle to outmean (see GCBO)% eventdata reserved - to be defined in a future version of MA TLAB% handles empty - handles not created until after all CreateFcns called% Hint: edit controls usually have a white background on Windows.% See ISPC and COMPUTER.if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');end% --- Executes during object creation, after setting all properties.function edit24_CreateFcn(hObject, eventdata, handles)% hObject handle to edit24 (see GCBO)% eventdata reserved - to be defined in a future version of MA TLAB% handles empty - handles not created until after all CreateFcns called% Hint: edit controls usually have a white background on Windows.% See ISPC and COMPUTER.if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');end% --- Executes during object creation, after setting all properties.function outminus_CreateFcn(hObject, eventdata, handles)% hObject handle to outminus (see GCBO)% eventdata reserved - to be defined in a future version of MA TLAB% handles empty - handles not created until after all CreateFcns called% Hint: edit controls usually have a white background on Windows.% See ISPC and COMPUTER.if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');end% --- Executes during object creation, after setting all properties.function foutt_CreateFcn(hObject, eventdata, handles)% hObject handle to foutt (see GCBO)% eventdata reserved - to be defined in a future version of MA TLAB% handles empty - handles not created until after all CreateFcns called% Hint: edit controls usually have a white background on Windows.% See ISPC and COMPUTER.if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');end% --- Executes during object creation, after setting all properties.function foutfreq_CreateFcn(hObject, eventdata, handles)% hObject handle to foutfreq (see GCBO)% eventdata reserved - to be defined in a future version of MA TLAB% handles empty - handles not created until after all CreateFcns called% Hint: edit controls usually have a white background on Windows.% See ISPC and COMPUTER.if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');end% --- Executes during object creation, after setting all properties.function pointfrom_CreateFcn(hObject, eventdata, handles)% hObject handle to pointfrom (see GCBO)% eventdata reserved - to be defined in a future version of MA TLAB% handles empty - handles not created until after all CreateFcns called% Hint: edit controls usually have a white background on Windows.% See ISPC and COMPUTER.if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');end% --- Executes during object creation, after setting all properties.function pointto_CreateFcn(hObject, eventdata, handles)% hObject handle to pointto (see GCBO)% eventdata reserved - to be defined in a future version of MA TLAB% handles empty - handles not created until after all CreateFcns called% Hint: edit controls usually have a white background on Windows.% See ISPC and COMPUTER.if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white');end% --- Executes on button press in timeanalyse.function timeanalyse_Callback(hObject, eventdata, handles)Fs=str2double(get(findobj('Tag','caiyangpinlv'),'String'));N=str2double(get(findobj('Tag','caiyangdianshu'),'String'));if handles.inputtype==0msgbox('No wave exist! Please choose a input type!');return;end%guo ling jian cen=1;ymax=max([handles.y(1) handles.y(2)]);ymin=min([handles.y(1) handles.y(2)]);from=str2double(get(handles.pointfrom,'String'));to=str2double(get(handles.pointto,'String'));if from<1 | to-from<5;msgbox('Error range!');return;endfor i=from+2:to-1;if handles.y(i-1)<0 & handles.y(i-2)<0 & handles.y(i)>=0 & handles.y(i+1)>0if handles.y(i)==0ti(n)=i;elseti(n)=i-handles.y(i)/(handles.y(i)-handles.y(i-1));endamp(n)=(ymax-ymin)/2;ymax=0;ymin=0;n=n+1;elseif ymax<handles.y(i)ymax=handles.y(i);endif ymin>handles.y(i)ymin=handles.y(i);endendendn=n-1;%freqence and periodicityfor i=1:n-1T(i)=ti(i+1)-ti(i);endfreq=Fs/mean(T);if (handles.inputtype==1||handles.inputtype==2||handles.inputtype==4)set(handles.circle,'String','非周期');set(handles.outfreq,'String','非周期');endif(handles.inputtype==3)set(handles.circle,'String',1/freq);set(handles.outfreq,'String',num2str(freq));endset(handles.outamp,'String',num2str(mean(amp(2:n-1))));%phasephase=2*pi*(1-(ti(1:n-1)-1)./T+floor((ti(1:n-1)-1)./T));set(handles.outphase,'String',num2str(mean(phase)));%peakset(handles.outpeak,'String',(max(handles.y(from:to))-min(handles.y(from:to)))/2);%meanset(handles.outmean,'String',mean(handles.y(from:to)));%meansquareset(handles.outmeansquare,'String',mean(handles.y(from:to).^2));%sset(handles.outminus,'String',std(handles.y(from:to))^2);% --------------------------------------------------------------------function uipanel18_ButtonDownFcn(hObject, eventdata, handles)% hObject handle to uipanel18 (see GCBO)% eventdata reserved - to be defined in a future version of MA TLAB% handles structure with handles and user data (see GUIDATA)[filename,filepath]=uigetfile('*.wav','wavfile');set(handles.wavname,'string',filename);[handles.y,Fs,bit]=wavread(filename);handles.inputtype=2;guidata(hObject,handles);plot(handles.axes1,(1:length(handles.y))/Fs,handles.y);ysize=size(handles.y);set(handles.samplenum,'String',num2str(ysize(1)));set(handles.samplefre,'string',Fs);h=waitbar(0,'pleas wait...');for i=1:10000waitbar(i/10000,h)endclose(h)% --- Executes on button press in freqanalyse.function freqanalyse_Callback(hObject, eventdata, handles)% hObject handle to freqanalyse (see GCBO)% eventdata reserved - to be defined in a future version of MA TLAB % handles structure with handles and user data (see GUIDATA) Fs=str2double(get(findobj('Tag','caiyangpinlv'),'String'));N=str2double(get(findobj('Tag','caiyangdianshu'),'String'));if handles.inputtype==0msgbox('No wave exist! Please choose a input type!');return;endfrom=str2double(get(handles.pointfrom,'String'));to=str2double(get(handles.pointto,'String'));sample=handles.y(from:to);f=linspace(0,Fs/2,(to-from+1)/2);Y=fft(sample,to-from+1);[C,I]=max(abs(Y));if(handles.inputtype==1||handles.inputtype==2||handles.inputtype==4) set(handles.foutt,'String','非周期');set(handles.foutfreq,'String','非周期');endif(handles.inputtype==3)set(handles.foutt,'String',1/f(I));set(handles.foutfreq,'String',f(I));endY=Y(1:(to-from+1)/2);plot(handles.fuzhipu,f,2*sqrt(Y.*conj(Y)));plot(handles.xiangweipu,f,angle(Y));plot(handles.shipin,f,real(Y));plot(handles.xupin,f,imag(Y));plot(handles.gonglvpu,f,abs(Y).^2);xlabel(handles.fuzhipu,'freqency(Hz)');xlabel(handles.xiangweipu,'freqency(Hz)');xlabel(handles.shipin,'freqency(Hz)');xlabel(handles.xupin,'freqency(Hz)');xlabel(handles.gonglvpu,'freqency(Hz)');ylabel(handles.fuzhipu,'amplitude');ylabel(handles.xiangweipu,'phase(rad)');ylabel(handles.shipin,'real');ylabel(handles.xupin,'Imaginary');ylabel(handles.gonglvpu,'power');五、音频频谱分析仪运行结果1.声卡输入声卡输入的录音是非周期的,故时域分析和频域分析结果都是“非周期”。