MATLAB音频信号采样与恢复GUI程序分析
该程序是一个MATLAB GUI程序,用于对音频信号进行采样和恢复。程序实现了以下功能:
- 读取音频信号;
- 根据累计功率确定限带频率;
- 确定信号最高频率,根据最高信号频率计算奈奎斯特频率;
- 利用信号最高频率确定三种抽样频率;
- 对原始音频信号进行三种抽样,并恢复;
- 绘制采样信号和恢复信号的时域和频域图像。
用户可以通过选择不同的抽样频率按钮来查看不同频率下的采样和恢复效果。
function varargout = liyinchuan(varargin)
% LIYINCHUAN MATLAB code for liyinchuan.fig
% LIYINCHUAN, by itself, creates a new LIYINCHUAN or raises the existing
% singleton*.
%
% H = LIYINCHUAN returns the handle to a new LIYINCHUAN or the handle to
% the existing singleton*.
%
% LIYINCHUAN('CALLBACK',hObject,eventData,handles,...) calls the local
% function named CALLBACK in LIYINCHUAN.M with the given input arguments.
%
% LIYINCHUAN('Property','Value',...) creates a new LIYINCHUAN or raises the
% existing singleton*. Starting from the left, property value pairs are
% applied to the GUI before liyinchuan_OpeningFcn gets called. An
% unrecognized property name or invalid value makes property application
% stop. All inputs are passed to liyinchuan_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 liyinchuan
% Last Modified by GUIDE v2.5 24-Mar-2023 11:08:54
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @liyinchuan_OpeningFcn, ...
'gui_OutputFcn', @liyinchuan_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 liyinchuan is made visible.
function liyinchuan_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to liyinchuan (see VARARGIN)
% Choose default command line output for liyinchuan
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes liyinchuan wait for user response (see UIRESUME)
% uiwait(handles.figure1);
% --- Outputs from this function are returned to the command line.
function varargout = liyinchuan_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;
% --- 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)
% clc
% clear all
delete(allchild(handles.axes1));%清除绘图1
delete(allchild(handles.axes2));%清除绘图2
delete(allchild(handles.axes3));%清除绘图3
delete(allchild(handles.axes4));%清除绘图4
%读取音频信号
[x,fs]=audioread('D:\USERS\Desktop\YinPin\om.mp3');
%% 根据累计功率确定限带频率
%计算FFT和功率谱密度(PSD)
N=length(x);
X=fft(x)/N;
PSD=abs(X).^2/N;
%% 确定限带频率
freq=linspace(0,fs/2,floor(N/2)+1);%创建一个频率向量
P=PSD(1:length(freq));%提取PSD中的有限频率
[~,ind]=sort(P,'descend');%按降序排列功率谱密度
cumP=cumsum(P(ind));%计算排序后功率谱密度的累积分布
cumP=cumP/cumP(end);%归一化,最大值为1
threshold=0.9;%限定阈值为0.9
f_low=freq(ind(find(cumP>=threshold,1)));%获取低频率限制
f_high=freq(ind(find(cumP>=threshold,1,'last')));%获取高频率限制
disp(['Signalbandwidthisbetween',num2str(f_low),'Hzand',num2str(f_high),'Hz.']);%输出限带频率信息
%% 确定信号最高频率,根据最高信号频率计算奈奎斯特频率,下面用的方法是将最高频率向上取整至最高位,得到奈奎斯特频率
f=(0:N-1)*(fs/N);%f是每个采样点的频率
[maxValue,maxIndex]=max(abs(X));%获取FFT中的最大幅值和相应的下标
freq=f(maxIndex);%根据下表获取信号最高频率
fc=2*freq(1,1);%抽样频率需大于信号最高频率的两倍
fc_r=round(fc);%取整数
numStr=num2str(fc_r);%将数字转换为字符串
%取出第一位数字
firstDigit=str2double(numStr(1));
%如果第一位数字是1-9之间的数,就将整数向上取整到这个数字的最高位
if firstDigit>0&&firstDigit<=9
rounded_fc=ceil(fc_r/10^(length(numStr)-1))*10^(length(numStr)-1);
else
%如果第一位数字是0,则向上取整到第一个非零数字的最高位
for i=2:length(numStr)
if str2double(numStr(i))>0
rounded_fc=ceil(fc_r/10^(length(numStr)-i))*10^(length(numStr)-i);
return;
end
end
rounded_fc=0;%如果整数是0,则无法取整
end
%% 利用信号最高频率确定三种抽样频率,系数自定
Fs_1=rounded_fc;%等于两倍奈奎斯特抽样频率
Fs_2=2*rounded_fc;%大于两倍奈奎斯特抽样频率
Fs_3=0.8*rounded_fc;%小于两倍奈奎斯特抽样频率
%% %抽样
n_1=length(x);%两倍抽样频率抽样的点数
t_1=(0:n_1-1)/fs;%两倍抽样频率抽样信号的时间向量
n_2=round(n_1*Fs_2/Fs_1);%大于两倍抽样频率抽样的点数
t_2=(0:n_2-1)/Fs_2;%大于两倍抽样频率抽样信号的时间向量
n_3=round(n_1*Fs_3/Fs_1);%小于两倍抽样频率抽样的点数
t_3=(0:n_3-1)/Fs_3;%小于两倍抽样频率抽样信号的时间向量
x_1=x;%初始化抽样信号1
x_2=zeros(n_2,1);%初始化抽样信号2
x_3=zeros(n_3,1);%初始化抽样信号3
%生成抽样频率为Fs_2的抽样信号
for i=1:n_2
x_2(i)=x(ceil(i*Fs_1/Fs_2));
end
%生成抽样频率为Fs_2抽样的信号
for i=1:n_3
x_3(i)=x(ceil(i*Fs_1/Fs_3));
end
f=fs*(0:(N/2))/N;
X_1=fft(x_1)/N;
X_2=fft(x_2)/N;
X_3=fft(x_3)/N;
%% 恢复
y_1=x_1;%初始化恢复信号1
y_2=zeros(n_1,1);%初始化恢复信号2
y_3=zeros(n_1,1);%初始化恢复信号3
%以Fs_2抽样的信号恢复
for i=1:n_2
y_2(ceil(i*Fs_1/Fs_2))=x_2(i);
end
%以Fs_3抽样的信号恢复
for i=1:n_3
y_3(ceil(i*Fs_1/Fs_3))=x_3(i);
end
Y_1=fft(y_1)/N;
Y_2=fft(y_2)/N;
Y_3=fft(y_3)/N;
%% 绘图
if get(handles.radiobutton1,'value')
plot(handles.axes1,t_1, x_1); title(handles.axes1,sprintf('Sampled Signal (Fs = %dHz)',Fs_1)); xlabel(handles.axes1,'Time (s)'); ylabel(handles.axes1,'Amplitude');
plot(handles.axes2,t_1, y_1); title(handles.axes2,sprintf('Recovered Signal (Fs = %dHz)', Fs_1)); xlabel(handles.axes2,'Time (s)'); ylabel(handles.axes2,'Amplitude');
plot(handles.axes3,f, 2*abs(X_1(1:N/2+1))); title(handles.axes3,sprintf('Sampled Signal (Fs = %dHz)', Fs_1)); xlabel(handles.axes3,'Frequency (Hz)'); ylabel(handles.axes3,'Magnitude');
plot(handles.axes4,f, 2*abs(Y_1(1:N/2+1))); title(handles.axes4,sprintf('Recovered Signal (Fs = %dHz)', Fs_1)); xlabel(handles.axes4,'Frequency (Hz)'); ylabel(handles.axes4,'Magnitude');
elseif get(handles.radiobutton2,'value')
plot(handles.axes1,t_2, x_2); title(handles.axes1,sprintf('Sampled Signal (Fs = %dHz)', Fs_2)); xlabel(handles.axes1,'Time (s)'); ylabel(handles.axes1,'Amplitude');
plot(handles.axes2,t_1, y_2); title(handles.axes2,sprintf('Recovered Signal (Fs = %dHz)', Fs_2)); xlabel(handles.axes2,'Time (s)'); ylabel(handles.axes2,'Amplitude');
plot(handles.axes3,f, 2*abs(X_2(1:N/2+1))); title(handles.axes3,sprintf('Sampled Signal (Fs = %dHz)', Fs_2)); xlabel(handles.axes3,'Frequency (Hz)'); ylabel(handles.axes3,'Magnitude');
plot(handles.axes4,f, 2*abs(Y_2(1:N/2+1))); title(handles.axes4,sprintf('Recovered Signal (Fs = %dHz)', Fs_2)); xlabel(handles.axes4,'Frequency (Hz)'); ylabel(handles.axes4,'Magnitude');
elseif get(handles.radiobutton3,'value')
plot(handles.axes1,t_3, x_3); title(handles.axes1,sprintf('Sampled Signal (Fs = %dHz)', Fs_3)); xlabel(handles.axes1,'Time (s)'); ylabel(handles.axes1,'Amplitude');
plot(handles.axes2,t_1, y_3); title(handles.axes2,sprintf('Recovered Signal (Fs = %dHz)', Fs_3)); xlabel(handles.axes2,'Time (s)'); ylabel(handles.axes2,'Amplitude');
plot(handles.axes3,f, 2*abs(X_3(1:N/2+1))); title(handles.axes3,sprintf('Sampled Signal (Fs = %dHz)', Fs_3)); xlabel(handles.axes3,'Frequency (Hz)'); ylabel(handles.axes3,'Magnitude');
plot(handles.axes4,f, 2*abs(Y_3(1:N/2+1))); title(handles.axes4,sprintf('Recovered Signal (Fs = %dHz)', Fs_3)); xlabel(handles.axes4,'Frequency (Hz)'); ylabel(handles.axes4,'Magnitude');
end
% --- Executes on button press in radiobutton1.
function radiobutton1_Callback(hObject, eventdata, handles)
% hObject handle to radiobutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hint: get(hObject,'Value') returns toggle state of radiobutton1
% --- Executes on button press in radiobutton2.
function radiobutton2_Callback(hObject, eventdata, handles)
% hObject handle to radiobutton2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hint: get(hObject,'Value') returns toggle state of radiobutton2
% --- Executes on button press in radiobutton3.
function radiobutton3_Callback(hObject, eventdata, handles)
% hObject handle to radiobutton3 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hint: get(hObject,'Value') returns toggle state of radiobutton3
% --- Executes on mouse press over axes background.
function axes1_ButtonDownFcn(hObject, eventdata, handles)
% hObject handle to axes1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% --- If Enable == 'on', executes on mouse press in 5 pixel border.
% --- Otherwise, executes on mouse press in 5 pixel border or over radiobutton1.
function radiobutton1_ButtonDownFcn(hObject, eventdata, handles)
% hObject handle to radiobutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
原文地址: https://www.cveoy.top/t/topic/lQgl 著作权归作者所有。请勿转载和采集!