基於MATLAB的GUI(Graphical User Interface)音頻實時顯示設計

【博主原創】app

摘要:本文章的設計主要講基於matlab的gui音頻實時顯示設計,這次設計的gui至關於一個簡潔的音樂播放器,界面只有」錄音「和」播放「兩個控件,哈哈,夠簡潔吧。經過」錄音「按鈕能夠實現聲音從電腦的聲卡錄入,而且實時顯示錄入聲音的時域圖形和頻域圖形;待錄音結束,經過」播放「按鈕能夠播放剛錄入的聲音,而且一邊播放一遍實時顯示時域和頻域圖形。本設計的編碼在matlab2013a上親測,能夠實現。。。ide

 

1、首先matlab的gui界面設計函數

打開matlab—>在命令行執行guide—>出現gui編輯界面,選擇一個默認的空白模板—>在界面上添加兩個座標軸axes一、axes2,再添加兩個push_button,和兩個text—>調整好位置,將兩個按鈕tag更名爲錄音和播放,將兩個text改成時域波形和頻域波形,這樣簡單的界面就作好了,想要美觀一些,能夠本身再編輯。ui

2、設計好gui界面保存後就會自動生成一個.fig的文件和一個.m的文件,兩個文件不要丟失,下次能夠經過運行.m文件來打開界面,實現功能。設計好的界面以下圖所示this

                                                                     

打開.m的文件,裏面能夠看到圖形設計的主函數function varargout = yin(varargin),打開函數function yin_OpeningFcn(hObject, eventdata, handles, varargin)和輸出函數function varargout = yin_OutputFcn(hObject, eventdata, handles),至於這些函數裏面是什麼意思,能夠參考園子裏一位園友「技術蛀蟲」的關於matlab的文章,講的很是好。總之設計好界面後,生成的.m文件裏會自動生成這些函數,此外還會生成你所加控件的回調函數callback,在相應的回調函數里加入代碼後,點擊界面上相應按鈕時就會實現代碼的功能。編寫回調函數是很是重要的一步,這決定界面按鈕能不能實現相應的功能。編碼

3、回調函數的編寫spa

這個gui的設計要編寫的回調函數只有兩個,分別爲「錄音」和「播放」兩個按鈕,不用實現功能的按鈕就不用在.m文件中編寫。編寫控件的回調函數的方法有兩種,一是直接打開.m文件在相應的回調函數名下編寫或者修改。另外一種是在製做gui界面的時候,在界面上相應的控件上右擊,而後在「view callback」選項中編寫並保存。下面開始編寫兩個控件的回調函數:命令行

錄音按鈕的功能是:按下時,實時從聲卡錄入音頻,並實時顯示時域和頻域的波形,先判斷當前窗口句柄的isrecording的值,而後執行if語句,當isrecording值爲0時,執行if下的語句,調用record(gcf,handles)函數,record函數我會另外寫出來,運行的時候把它們放在同一個文件夾下就能夠了。當isrecording爲1時,表示當前窗口正在運行,表示在錄音,這時按下這個按鈕,就會執行else,將isrecording設置爲0,從而中止錄音。因此錄音按鈕第一次按下開始錄音,第二次按下中止錄音,都是經過設置isrecording的值實現。爲了保證在界面剛打開的時候,爲中止錄音的狀態,咱們須要在打開函數function yin_OpeningFcn(hObject, eventdata, handles, varargin)中添加setappdata(gcf,'isrecording',0)命令,即一開始設置isrecording爲0;設計

% --- Executes on button press in pushbutton1.3d

function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
isrecording=getappdata(gcf,'isrecording');
if ~isrecording
setappdata(gcf,'isrecording',1);
recorder(gcf,handles);
else
setappdata(gcf,'isrecording',0);
end

附上record函數的代碼:(record函數的做用是創建聲卡對象,控制聲卡實現錄音,並對錄音的數據進行實時的時域和頻域顯示)

function aa= recorder(cf,handles)
%RECORDER Summary of this function goes here
% Detailed explanation goes here
% h=figure(soundrec);

h=cf;
thehandles=handles;
setappdata(h,'isrecording',1);

Ai=analoginput('winsound'); % 建立一個模擬信號輸入對象
% 添加通道
addchannel(Ai,1);
Ai.SampleRate=10000; % 採樣頻率
Ai.SamplesPerTrigger=Inf; % 採樣數

 

start(Ai); % 開啓採樣
warning off % 當採樣數據不夠時,取消警告
while isrunning(Ai) % 檢查對象是否仍在運行
if getappdata(h,'isrecording')
data=peekdata(Ai,Ai.SampleRate/2);% 獲取對象中的最後Ai.SampleRate個採樣數據
plot(thehandles.axes1,data) % 繪製最後Ai.SampleRate個採樣數據的圖形,所以表現出來就是實時的了
set(handles.axes1,'ylim',[-1 1],'xlim',[0 5000]);
y1=fft(data,2048); %對信號作2048點FFT變換
f=Ai.SampleRate*(0:1023)/2048;
bar(handles.axes2,f,abs(y1(1:1024)),0.8,'g') %作原始語音信號的FFT頻譜圖
set(handles.axes2,'ylim',[0 10],'xlim',[100 250]);%設置handles.axes2的橫縱座標範圍
drawnow; % 刷新圖像
else
stop(Ai);
num=get(Ai,'SamplesAvailable');
aa=getdata(Ai,num);
axes(thehandles.axes1);
plot(thehandles.axes1,aa) % 繪製全部採樣數據的圖形

y1=fft(data,2048); %對信號作2048點FFT變換
f=Ai.SampleRate*(0:1023)/2048;
bar(handles.axes2,f,abs(y1(1:1024)),0.8,'g') %作原始語音信號的FFT頻譜圖
drawnow; % 刷新圖像
setappdata(h,'sounds',aa);
end
end

end

播放按鈕的功能是:按下時,播放已經錄入的音頻,並實時顯示頻譜,這就須要本身設計記錄音頻播放的位置,這樣才能使在循環內每次音頻的播放位置正確,記錄位置經過計時來實現,記錄的時間差time轉換爲以秒爲單位獲得s,再經過s*fs來獲得採樣了多少個點,從而獲得採樣點的位置,而且限制每次處理5000個採樣點,在時域波形上刷新顯示;而頻域的計算則是每次取2048個採樣點進行fft變換。

% --- Executes on button press in pushbutton2.

function pushbutton2_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global ad fs yp y ;
y=getappdata(gcf,'sounds');
fs=10000;
ad=analogoutput('winsound');%創建以聲卡做爲輸入輸出對象
addchannel(ad,1);
set(ad,'samplerate',fs);
putdata(ad,y);
handles.ad=ad;
guidata(hObject, handles);%更新圖形句柄
start(ad);
T=clock;
pause(0.1);
while isrunning(ad)
T1=clock;
time=T1-T;%計算時間差
s=3600*time(4)+60*time(5)+time(6);
if(round(s*fs+5000)<length(y))
yp=y(round(s*fs):round(s*fs+5000));%round函數取距離最近的整數
plot(handles.axes1,yp);
set(handles.axes1,'ylim',[-1 1],'xlim',[0 5000]);
y1=fft(yp,2048);
f=fs*(0:1023)/2048;
bar(handles.axes2,f,abs(y1(1:1024)),0.8,'g') %作原始語音信號的FFT頻譜圖
set(handles.axes2,'ylim',[0 10],'xlim',[100 250]);%設置handles.axes2的橫縱座標範圍
drawnow;
end
end

4、至此,整個設計就已經完成了,雖然界面簡單,可是完美實現了所需的功能;

相關文章
相關標籤/搜索