%------>0.导入文件--------------------------------------------------------------------------------------------------
[file,path] = uigetfile( {'*.wav','WAV音频文件'; },'选择一个WAV音频文件','MultiSelect', 'off');
%-------------------------------------------------------------------------------------------------------------------
%uigetfile ->用于创建文件选择对话框的函数。它的主要功能是允许用户从计算机文件系统中选择一个或多个文件。
%file ->是一个字符串变量,它用于存储用户选择的文件的名称(包括文件扩展名),例如,"example.wav"。
%path ->是一个字符串变量,用于存储用户选择的文件的路径,例如,"C:\Users\YourUsername\Documents"。
%{'*.wav','WAV音频文件'; }->设置过滤器过滤出.wav格式的文件,另外 '*.*', '所有文件' 表示可以选择所有格式的文件
%'选择一个WAV音频文件' ->设置文件选择对话框的标题
%'MultiSelect', 'off' ->用于指定用户是否可以选择多个文件,这里设置为off表示只能选择一个文件
%-------------------------------------------------------------------------------------------------------------------
if isequal(file,0) %检查 file 变量的值是否等于0,也就是用户是否选择了文件
disp('您没有选择文件!'); %如果用户没有选择文件,在命令行窗口打印出提示
else
disp(['您选择的文件是:', file]);
disp(['文件的路径是:', path]);
end %end表示条件块结束
%-------------------------------------------------------------------------------------------------------------------
path_filename = strcat(path,file); %strcat将两个字符串连接在一起,拼接文件完整路径(path+filename),赋给files数组的第一个元素
%在MATLAB中,使用花括号 {} 用于索引或创建单元格数组,而不是中括号 [],因为单元格数组是一种不同于常规数组(矩阵)的数据类型。单元格数组允许存储不同数据类型的元素,包括字符串、数字、其他数组等。
%------>1.导入音频文件,获取时域、频域图-----------------------------------------------------------------------------------------
[Cellnum,Fs]=audioread(path_filename); %---Cellnum(数组或矩阵类型)为获取到的音频数据,Fs为采样率
N=length(Cellnum); %---N为Cellnum 中的元素数量,即音频数据的样本点数
k=(0:N-1); %---创建一维数组k,赋值为0~N-1
f=(k/N-1/2)*Fs; %---将时域的采样点映射到频域中的相应频率
X0=fft(Cellnum); %---执行快速傅里叶变换(FFT)操作,将时域的音频信号Cellnum转换为频域表示,结果(振幅、相位)存储在变量X0中。
figure; %---用于创建新的图形窗口的命令
subplot(2,1,1),plot(Cellnum); %---参数(2,1,1)表示两行一列,当前绘图区域是第一个子图,即上半部分的子图。plot(Cellnum): 这部分命令用于在当前选择的第一个子图中绘制音频数据的时域图像。plot函数将Cellnum中的数据绘制成折线图,其中 x 轴表示采样点,y 轴表示振幅。
title('音频时域图'),xlabel('采样点'),ylabel('振幅');
subplot(2,1,2),plot(f,abs(fftshift(X0))),xlim([0,4000]); %---plot(f,abs(fftshift(X0)): 这部分命令用于在当前选择的第二个子图中绘制音频数据的频域图像。f表示频率数组,abs(fftshift(X0))表示频域数据的振幅,即傅里叶变换后的信号的幅度。这将显示音频信号在不同频率上的能量分布。xlim([0,4000]): 这部分命令用于限制 x 轴的显示范围,将频率范围限制在0到4000 Hz之间。这样做是为了在频谱图中仅显示特定范围内的频率分量,以便更清晰地观察感兴趣的频率区域。
title('音频频域图'),xlabel('f/Hz'),ylabel('幅度');
%------>2.根据时域图分割出有效信号------------------------------------------------------------------------------------------------
[n1,Fs]=audioread(path_filename,[2439,15330]);
[n2,Fs]=audioread(path_filename,[22570,37080]);
[n3,Fs]=audioread(path_filename,[44580,58590]);
[n4,Fs]=audioread(path_filename,[65620,80170]);
[n5,Fs]=audioread(path_filename,[88120,101100]);
[n6,Fs]=audioread(path_filename,[107800,124000]);
[n7,Fs]=audioread(path_filename,[129500,147500]);
[n8,Fs]=audioread(path_filename,[150200,166100]);
[n9,Fs]=audioread(path_filename,[171400,188500]);
[n10,Fs]=audioread(path_filename,[193900,209000]);
[n11,Fs]=audioread(path_filename,[217500,230800]);
cell={n1 n2 n3 n4 n5 n6 n7 n8 n9 n10 n11}; %---将有效信号存入cell中
for i=1:1:11 %---表示从1-11每次加1循环
N=length(cell{i}); %---画出所截的的有效信号的时域、频域图
k=(0:N-1);
f=(k/N-1/2)*Fs;
X0=fft(cell{i});
%figure;
%subplot(2,1,1),plot(cell{i});
%title('音频时域图'),xlabel('采样点'),ylabel('振幅');
%subplot(2,1,2),plot(f,abs(fftshift(X0)));xlim([0,4000]);
%title('音频频域图'),xlabel('f/Hz'),ylabel('幅度');
%------>3.滤波,获取每段信号的高频和低频-------------------------------------------------------------------------------------------
Hd=lband_pass; %---低带通滤波器
x1=filter(Hd,cell{i}); %---这行代码使用 filter 函数,将低带通滤波器 Hd 应用于信号 cell{i}。x1 将是滤波后的信号,它将只包含 Hd 指定的频率范围内的信号成分。
X1=fft(x1); %---X1 = fft(x1);: 这行代码对滤波后的信号 x1 执行傅里叶变换,以获取它的频域表示。
%figure; %---画出滤波后的时域、频域图
%subplot(2,1,1),plot(x1);
%title('滤波后的按键音(时域)'),xlabel('采样点'),ylabel('振幅');
%subplot(2,1,2),plot(f,abs(fftshift(X1))),xlim([0,2000]);
%title('滤波后的按键音(频域)'),xlabel('f/Hz'),ylabel('幅度');
Z=abs(fft(x1)); %---这行代码计算了信号 x1 的傅里叶变换后的振幅
[mal, I]=max(Z); %---mal为振幅,I为最大振幅的下标值
index_lo=I/length(Z)*Fs; %---这行代码计算了最大振幅值所对应的频率值
He=hband_pass; %---高带通滤波器
x1=filter(He,cell{i});
X1=fft(x1);
%figure
%subplot(2,1,1),plot(x1)
%title('滤波后的按键音(时域)'),xlabel('t'),ylabel('振幅')
%subplot(2,1,2),plot(f,abs(fftshift(X1))),xlim([0,2000])
%title('滤波后的按键音(频域)'),xlabel('f/Hz'),ylabel('幅度')
Z=abs(fft(x1));
[mah, I]=max(Z);
index_hi=I/length(Z)*Fs;
%------>4.判断按键值-----------------------------------------------------------------------------------------------------------------------
fc1=697; fc2=770; fc3=852; fc4=941; %---低频组
fr1=1209;fr2=1336;fr3=1477; %---高频组
if index_lo-fc1<=30 & index_hi-fr1<=40
keynum = '1';
elseif index_lo-fc1<=30& index_hi-fr2<=40
keynum = '2';
elseif index_lo-fc1<=30 & index_hi-fr3<=40
keynum = '3';
elseif index_lo-fc2<=30 & index_hi-fr1<=40
keynum = '4';
elseif index_lo-fc2<=30 & index_hi-fr2<=40
keynum = '5';
elseif index_lo-fc2<=30 & index_hi-fr3<=40
keynum = '6';
elseif index_lo-fc3<=30 & index_hi-fr1<=40
keynum = '7';
elseif index_lo-fc3<=30 & index_hi-fr2<=40
keynum = '8';
elseif index_lo-fc3<=30 & index_hi-fr3<=40
keynum = '9';
elseif index_lo-fc4<=30 & index_hi-fr2<=40
keynum = '0';
elseif index_lo-fc4<=30 & index_hi-fr1<=40
keynum = '*';
elseif index_lo-fc4<=30 & index_hi-fr3<=40
keynum = '#';
end
Cell(i)=keynum; %---手机号码识别结果
end
disp('识别结果为:');
disp(Cell);
%--------------------------------------------------------------------------------------------------------------------------------
%高带通滤波---允许1209-1477的信号通过
function He = hband_pass
Fs = 44100;
Fstop1 = 1000;
Fpass1 = 1209;
Fpass2 = 1477;
Fstop2 = 1600;
Astop1 = 20;
Apass = 1;
Astop2 = 30;
match = 'stopband';
h = fdesign.bandpass(Fstop1, Fpass1,Fpass2, Fstop2, Astop1, Apass,Astop2, Fs);
He = design(h, 'butter', 'MatchExactly', match);
end
%低带通滤波---允许697-941的信号通过
function Hd = lband_pass %---这一行定义了一个名为lband_pass的函数,并指定它将返回一个名为Hd的滤波器对象。
Fs = 44100; %---设置采样率为44100Hz
Fstop1 =500; %---这是第一个阻带开始的频率
Fpass1 =697; %---这是通带的较低频率
Fpass2 = 941; %---这是通带的较高频率
Fstop2 = 1000; %---这是第二个阻带开始的频率
Astop1 = 20; %---这是第一个阻带中的衰减,以分贝(dB)为单位。
Apass = 1; %---这是通带波纹,以分贝为单位。
Astop2 = 30; %---这是第二个阻带中的衰减,以分贝为单位。
match = 'stopband'; %---这指定了滤波器设计应完全匹配阻带
h = fdesign.bandpass(Fstop1, Fpass1,Fpass2, Fstop2, Astop1, Apass,Astop2,Fs);%---这一行使用指定的参数构建了一个FDESIGN对象,用于Butterworth带通滤波器。fdesign.bandpass函数用于创建滤波器设计对象。
Hd = design(h, 'butter', 'MatchExactly', match); %---这一行使用design函数创建了Butterworth带通滤波器,使用在h对象中指定的设计参数。'MatchExactly'选项指定滤波器应完全匹配阻带。
end
%------------------------------------------------------------------------------------------------------------------------------------
MATLAB拨号音识别
于 2023-10-26 20:03:09 首次发布