📄 实时音频信号采集和处理系统.m
字号:
'Parent' , hFig,... 'Style' , 'pushbutton',... 'Units' , 'normalized',... 'Position' , [0.0150 0.0111 0.1 0.0556],... 'Value' , 1,... 'String' , '暂停',... 'FontSize' , 10,... 'Callback' , 'demoai_fft(''stop'', gcbf);');hpop = uicontrol(... 'Parent' , hFig,... 'Style' , 'popupmenu',... 'Units' , 'normalized',... 'Position' , [0.35 0.007 0.1 0.0556],... 'Value' , 1,... 'String' , {'巴特沃斯滤波' '切比雪夫1型滤波'},... 'FontSize' , 10,... 'Callback' , '');hmenu(1) = uimenu('Parent', hFig,... 'Label', '文件');hmenu(2) = uimenu(hmenu(1),... 'Label', '关闭数据采集系统',... 'Callback', 'demoai_fft(''close'',gcbf)');hmenu(3) = uimenu('Parent', hFig,... 'Label', '帮助');% hmenu(4) = uimenu(hmenu(3),...% 'Label', 'Data Acquisition Toolbox',...% 'Callback', 'helpwin(''daq'')');% hmenu(5) = uimenu(hmenu(3),...% 'Label', 'demoai_fft',...% 'Callback', 'helpwin(''demoai_fft'')'); %#ok<NASGU>%%% Store the handles in the data matrix.data.handle.figure = hFig;%对句柄进行存储data.handle.axes = hAxes;data.handle.line = hLine;data.handle.toggle = htoggle;data.handle.hpop = hpop;data.state = 0;%%% Set the axes handlevisibility to off.set(hAxes, 'HandleVisibility', 'off');%%% Store the data matrix and display figure.set(hFig,'Visible','on','UserData',data,'HandleVisibility', 'off');%%% Configure the callback to update the display.set(data.ai, 'TimerFcn', @localfftShowData);%% *********************************************************************** % 关闭数据采集系统。function localClose(data)%%% Stop the device if it is running and delete the object.if isvalid(data.ai) if isrunning(data.ai) stop(data.ai); end delete(data.ai);end%%% Close the figure window.delete(data.handle.figure);%% *********************************************************************** % Stop or start the device.function data = localStop(data)%%% Based on the state either stop or start.if isrunning(data.ai) % Stop the device. stop(data.ai); set(data.handle.toggle, 'String', '开始'); % Store the new state. data.state = 1;else % Toggle the Start/Stop string. set(data.handle.toggle, 'String', '暂停'); % Store the new state. data.state = 0; % Start the device. start(data.ai);endfunction [firstcross, lastcross] = localDaqCrossPt(data)% Calculate the first & last crosspoints over the mean of the data.% function returns 0 if no crosspoint is found.firstcross = 0;crossvalue = mean(data);for i = 2:length(data) if(data(i-1) >= crossvalue && data(i) < crossvalue) firstcross = i; break; endendlastcross = 0;for i = length(data):-1:2 if(data(i-1) >= crossvalue && data(i) < crossvalue) lastcross = i; break; endend%% ***********************************************************************% 对原始数据进行FFT运算、幅值运算、相位运算。function [f, DAQfft,mag,phas] = localDaqfft(data,Fs,blockSize)%%% Calculate the fft of the data.xFFT = fft(data,blockSize);xfft = abs(xFFT);DAQfft =xfft; %20*log10(xfft);DAQfft = DAQfft(1:blockSize/2);%%% Avoid taking the log of 0.index = find(xfft == 0);xfft(index) = 1e-17; %#ok<FNDSB>mag =20*log10(xfft);mag = mag(1:blockSize/2);phas =angle(xFFT);phas = phas /3.1415926 * 180 ;phas = phas(1:blockSize/2);f = (0:length(DAQfft)-1)*Fs/blockSize; f = f(:);%% ***********************************************************************% 对原始数据先进行巴特沃斯滤波,然后进行FFT运算、幅值运算、相位运算。function [d_filter,DAQfft_filter,mag_filter,phas_filter] = localDaqfft_filter1(d,Ft,blockSize)Fp=800; %通带截止频率Fs=1200; %阻带截止频率Ap=1; %通带纹波Ap=1As=20; %阻带纹波As=20wp=2*pi*Fp/Ft;ws=2*pi*Fs/Ft;[n,wn]=buttord(wp,ws,Ap,As,'s'); %求低通滤波器的阶数和截止频率,n=8[b,a]=butter(n,wn,'s'); %求S域的频率响应参数[num,den]=bilinear(b,a,1); %双线性变换实现S域到Z域的变换d_filter=filter(num,den,d); %对原始波形进行滤波%%% Calculate the fft of the data.xFFT1 = fft(d_filter,blockSize);xfft1 = abs(xFFT1);DAQfft_filter =xfft1; %20*log10(xfft);DAQfft_filter = DAQfft_filter(1:blockSize/2);%%% Avoid taking the log of 0.index = find(xfft1 == 0);xfft1(index) = 1e-17; %#ok<FNDSB>mag_filter =20*log10(xfft1);%计算幅度谱mag_filter = mag_filter(1:blockSize/2);phas_filter =angle(xFFT1);%计算相位谱phas_filter = phas_filter /3.1415926 * 180 ;%将弧度装换成角度phas_filter = phas_filter(1:blockSize/2);%% ***********************************************************************% 对原始数据先进行切比雪夫1型滤波,然后进行FFT运算、幅值运算、相位运算。function [d_filter,DAQfft_filter,mag_filter,phas_filter] = localDaqfft_filter2(d,Ft,blockSize)Fp=1800; %通带截止频率Fs=2000; %阻带截止频率% Ft=8000; %采集频率Ap=1; %通带纹波Ap=1As=20; %阻带纹波As=20R=1; %通带峰峰纹波Rwp=2*pi*Fp/Ft;ws=2*pi*Fs/Ft;[n,wp]=cheb1ord(wp,ws,Ap,As,'s'); %求低通滤波器的阶数和截止频率,n=8[b,a]=cheby1(n,R,wp,'s'); %求S域的频率响应参数[num,den]=bilinear(b,a,1); %双线性变换实现S域到Z域的变换d_filter=filter(num,den,d); %对原始波形进行滤波%%% Calculate the fft of the data.xFFT2 = fft(d_filter,blockSize);xfft2 = abs(xFFT2);DAQfft_filter =xfft2; %20*log10(xfft);DAQfft_filter = DAQfft_filter(1:blockSize/2);%%% Avoid taking the log of 0.index = find(xfft2 == 0);xfft2(index) = 1e-17; %#ok<FNDSB>mag_filter =20*log10(xfft2);%计算幅度谱mag_filter = mag_filter(1:blockSize/2);phas_filter =angle(xFFT2);%计算相位谱phas_filter = phas_filter /3.1415926 * 180 ;%将弧度装换成角度phas_filter = phas_filter(1:blockSize/2);%% *********************************************************************** % 更新绘图。function localfftShowData(obj,event)%%% 获取句柄。data = obj.UserData;hpop = data.handle.hpop;hFig = data.handle.figure; %#ok<NASGU>hAxes = data.handle.axes;hLine = data.handle.line;str = get(hpop, 'String');val = get(hpop,'Value');%%% 提取最大值。x = peekdata(obj, obj.SamplesPerTrigger);%%% FFT运算。Fs = obj.SampleRate;blockSize = obj.SamplesPerTrigger;[firstcross, lastcross] = localDaqCrossPt(x);if firstcross == 0 || firstcross == lastcross return;endfftx = x(firstcross:lastcross);[f, DAQfft,mag,phas] = localDaqfft(fftx,Fs,blockSize);switch str{val}; case '巴特沃斯滤波' %使用巴特沃斯滤波 [d_filter,DAQfft_filter,mag_filter,phas_filter] = localDaqfft_filter1(fftx,Fs,blockSize);%对输入信号先进行巴特沃斯滤波,然后进行FFT、幅值及相位运算 case '切比雪夫1型滤波' % 使用切比雪夫1型滤波 [d_filter,DAQfft_filter,mag_filter,phas_filter] = localDaqfft_filter2(fftx,Fs,blockSize);%对输入信号先进行切比雪夫1型滤波,然后进行FFT、幅值及相位运算 end%%% 动态配置实时数据显示框的Y轴。maxX=max(x);minX=min(x);yax1=get(hAxes(1),'YLim');if minX<yax1(1), yax1(1)=minX;endif maxX>yax1(2), yax1(2)=maxX;endset(hAxes(1),'YLim',yax1)%设置hLine(1)句柄的属性,运用最大值法对Y轴进行控制set(hAxes(5),'YLim',yax1)%%% 配置FFT子图的x轴和y轴。set(hAxes(2),'XLim',[0 5000])set(hAxes(2),'YLim',[0 50])set(hAxes(6),'XLim',[0 5000])set(hAxes(6),'YLim',[0 50])%%% 动态配置幅度子图的Y轴。maxM=max(mag);minM=min(mag);yax2=get(hAxes(3),'YLim');if minM<yax2(1), yax2(1)=minM;endif maxM>yax2(2), yax2(2)=maxM;endset(hAxes(3),'YLim',yax2)set(hAxes(7),'YLim',yax2)%%% 动态配置相位子图的Y轴。maxM=max(phas);minM=min(phas);yax2=get(hAxes(4),'YLim');if minM<yax2(1), yax2(1)=minM;endif maxM>yax2(2), yax2(2)=maxM;endset(hAxes(4),'YLim',yax2)set(hAxes(8),'YLim',yax2)%%% 更新显示。set(hLine(1), 'YData', fftx(:,1));set(hLine(2), 'XData', f(:,1), 'YData', DAQfft(:,1));%设置hLine(2)句柄的属性,X轴的数据与频率有关,Y轴的数据由快速傅里叶变换后获得set(hLine(3), 'XData', f(:,1), 'YData', mag(:,1)); set(hLine(4), 'XData', f(:,1), 'YData', phas(:,1));set(hLine(5), 'YData', d_filter(:,1));set(hLine(6), 'XData', f(:,1), 'YData', DAQfft_filter(:,1));set(hLine(7), 'XData', f(:,1), 'YData', mag_filter(:,1));set(hLine(8), 'XData', f(:,1), 'YData', phas_filter(:,1));str=get(data.handle.toggle, 'String');if strcmp(str,'开始') set(data.handle.toggle, 'String', '暂停');enddrawnow;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -