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


【博主原創】

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

 

一、首先matlab的gui界面設計

打開matlab—>在命令行執行guide—>出現gui編輯界面,選擇一個默認的空白模板—>在界面上添加兩個坐標軸axes1、axes2,再添加兩個push_button,和兩個text—>調整好位置,將兩個按鈕tag改名為錄音和播放,將兩個text改為時域波形和頻域波形,這樣簡單的界面就做好了,想要美觀一些,可以自己再編輯。

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

                                                                     

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

三、回調函數的編寫

這個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.

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

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM