
电话拨键号码(DTMF信号)识别
图1 流程图
图2 原始按键音
图3 滤波后的按键音
图4 短时能量与过零率
图5 有效信号区域
图6 分割信号
图7 各按键音频率
图8 识别结果
发布日期:2021-05-07 14:37:58
浏览次数:27
分类:技术文章
本文共 6478 字,大约阅读时间需要 21 分钟。
1、流程

2、MATLAB实现
(1)主程序
clear allclc[x0,Fs]=audioread('1234567890.wav');%sound(x0,Fs);N=length(x0); %采样点k=(0:N-1);f=(k/N-1/2)*Fs;X0=fft(x0);figuresubplot(2,1,1),plot(x0)title('原始按键音(时域)'),xlabel('t'),ylabel('振幅')subplot(2,1,2),plot(f,abs(fftshift(X0)));xlim([0,4000])title('原始按键音(频域)'),xlabel('f/Hz'),ylabel('幅度') % -----------------------------------------带通滤波 Hd=band_pass; %带通滤波器x1=filter(Hd,x0); %滤波%sound(x1,Fs)X1=fft(x1);figuresubplot(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('幅度') % -------------------------------------------过零率与短时能量len=2000; %帧长d=50; %帧重叠样点长s=fra(len,len-d,x1); %分帧,s为帧数es=s.^2; %一帧内各样点能量energy=sum(es,2); %一帧的能量,行求和zcr=zcro(s); %求过零率figuresubplot(3,1,1),plot(x1)title('按键音1234567890'),ylabel('幅度')subplot(3,1,2),plot(energy)title('短时能量'),xlabel('帧编号'),ylabel('E')subplot(3,1,3),plot(zcr)title('信号过零率'),xlabel('帧编号'),ylabel('过零次数')%-------------------------------------------端点检测flag=energy; %有效信号标志Ethresh=0.02; %短时能量阈值flag(find(energy>Ethresh))=1;flag(find(energy<=Ethresh))=0; desired_signal=[]; %有效信号标志desired_signal(1)=0; for i=1:length(flag) for j=2:i if flag(j-1)*flag(j)==0 desired_signal(i)=0; else desired_signal(i)=1; end endend figure,plot(desired_signal),ylim([0,1.2])title('有效信号标志(0无效,1有效)'),xlabel('帧编号'),ylabel('y')for i=2:length(desired_signal) if desired_signal(i)-desired_signal(i-1)==1 left(i)=i; %左端点 elseif desired_signal(i)-desired_signal(i-1)==-1 right(i)=i; %右端点 endendleft_end=find(left~=0); %左端点right_end=find(right~=0); %右端点%---------------------------------------分帧后的恢复,分割信号[leftend1,leftend2]=inverse_fra(left_end,len-d,len);[rightend1,rightend2]=inverse_fra(right_end,len-d,len);figuresubplot(3,1,1),plot(x1)title('按键音1234567890'),ylabel('幅度'),xlabel('t')for i=1:length(leftend1) line([leftend1(i) leftend1(i)],[-0.1 0.1],'Color','red') line([rightend1(i) rightend1(i)],[-0.1 0.1],'Color','red')endsubplot(3,1,2),plot(energy),ylim([-0.1,0.6])title('短时能量'),xlabel('帧编号'),ylabel('E')for i=1:length(left_end) line([left_end(i) left_end(i)],[-0.1 1],'Color','red') line([right_end(i) right_end(i)],[-0.1 1],'Color','red')endsubplot(3,1,3),plot(zcr)for i=1:length(left_end) line([left_end(i) left_end(i)],[-200,200],'Color','red') line([right_end(i) right_end(i)],[-200,200],'Color','red')endtitle('信号过零率'),xlabel('帧编号'),ylabel('过零次数')%------------------------------------提取信号,识别号码Ass=15; %单个检测阈值ferror=-10:10; %频率误差fsL=[697 770 852 941]; %信号低频fsH=[1209 1336 1477]; %信号高频number=zeros(1,length(leftend1)); %存号码figurefor i=1:length(leftend1) x=x1(leftend1(i):rightend1(i)); N=length(x); fk=(0:N-1)/N*Fs; X=abs(fft(x)); if max(X(floor(N*(fsL(1)+ferror)/Fs)))>Ass & max(X(floor(N*(fsH(1)+ferror)/Fs)))>Ass number(i)=1; elseif max(X(floor(N*(fsL(1)+ferror)/Fs)))>Ass & max(X(floor(N*(fsH(2)+ferror)/Fs)))>Ass number(i)=2; elseif max(X(floor(N*(fsL(1)+ferror)/Fs)))>Ass & max(X(floor(N*(fsH(3)+ferror)/Fs)))>Ass number(i)=3; elseif max(X(floor(N*(fsL(2)/Fs)+ferror)))>Ass & max(X(floor(N*(fsH(1)+ferror)/Fs)))>Ass number(i)=4; elseif max(X(floor(N*(fsL(2)/Fs)+ferror)))>Ass & max(X(floor(N*(fsH(2)+ferror)/Fs)))>Ass number(i)=5; elseif max(X(floor(N*(fsL(2)/Fs)+ferror)))>Ass & max(X(floor(N*(fsH(3)+ferror)/Fs)))>Ass number(i)=6; elseif max(X(floor(N*(fsL(3)/Fs)+ferror)))>Ass & max(X(floor(N*(fsH(1)+ferror)/Fs)))>Ass number(i)=7; elseif max(X(floor(N*(fsL(3)/Fs)+ferror)))>Ass & max(X(floor(N*(fsH(2)+ferror)/Fs)))>Ass number(i)=8; elseif max(X(floor(N*(fsL(3)/Fs)+ferror)))>Ass & max(X(floor(N*(fsH(3)+ferror)/Fs)))>Ass number(i)=9; elseif X(floor(N*(fsL(4)/Fs)+ferror))>Ass & X(floor(N*(fsH(2)+ferror)/Fs))>Ass number(i)=0; end subplot(3,4,i),plot(fk,X),title('按键音(频域)'),xlim([500,1500])enddisp('该号码为:')disp(num2str(number)) %转换为字符串输出
(2)带通滤波器,此滤波器是使用fdatool生成
function Hd = band_pass%BAND_PASS Returns a discrete-time filter object.% MATLAB Code% Butterworth Bandpass filter designed using FDESIGN.BANDPASS.% Generated by MATLAB(R) 9.0 and the Signal Processing Toolbox 7.2.% Generated on: 18-Dec-2019 14:51:03% All frequency values are in Hz.Fs = 44100; % Sampling FrequencyFstop1 = 500; % First Stopband FrequencyFpass1 = 697; % First Passband FrequencyFpass2 = 1477; % Second Passband FrequencyFstop2 = 1600; % Second Stopband FrequencyAstop1 = 20; % First Stopband Attenuation (dB)Apass = 1; % Passband Ripple (dB)Astop2 = 30; % Second Stopband Attenuation (dB)match = 'stopband'; % Band to match exactly% Construct an FDESIGN object and call its BUTTER method.h = fdesign.bandpass(Fstop1, Fpass1, Fpass2, Fstop2, Astop1, Apass, ... Astop2, Fs);Hd = design(h, 'butter', 'MatchExactly', match);% [EOF]
(3)分帧
function [f] = fra(len,inc,x)%fra 对语音信号分帧% len-帧长,inc-非重叠样点长度,x-语音信号fh=fix((size(x,1)-len+inc)/inc); %计算帧数f=zeros(fh,len); %行为帧长,列为帧数i=1;n=1;while i
(4)过零率
function [f] = zcro(x)%zcro 计算过零率% f-过零率,x-帧长f=zeros(size(x,1),1);for i=1:size(x,1) z=x(i,:); for j=1:(length(z)-1) if z(j)*z(j+1)<0 f(i)=f(i)+1; end endendend
(5)分帧后的复原
function [end1,end2] = inverse_fra(k,inc,len)%inverse_fra 将帧数编号时,还原到原始语音部分%输出 end1-起始端点,end2-结束端点%输入 k-帧编号,inc-帧非重叠样点长度,len-帧长end1=(k-1)*inc+1;end2=(k-1)*inc+len;end
3、程序结果







在此程序中,端点检测并未用到短时过零率,是通过短时能量进行判断的,短时过零率仅仅是用来辅助判断。由于本人录音时间较长,且每段信号所含信息相同,因此可以用短时能量进行糙的端点检测,若进行更细致的检测则需要使用双门限检测,甚至是多门限检测法。由于电话号码当中并未出现A、B、C、D四个信号,因此滤波时可将高于1477Hz的频率滤除,滤波是为了排除杂波的影响。
识别结果如图8所示,录音顺序确为“1234567890”,表明该程序是正确的。
发表评论
最新留言
路过,博主的博客真漂亮。。
[***.116.15.85]2025年03月17日 05时37分31秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Warning: The core is locked up的解决办法
2019-03-04
奔涌吧 后浪!!! 哔哩哔哩 何冰
2019-03-04
【JVM系列】JDK 内置工具
2019-03-04
JAVA 基础与进阶系列索引 -- JDK 源码学习系列 -- 并发
2019-03-04
网络编程系列索引 -- JAVA 网络编程系列
2019-03-04
【JDK源码分析系列】ArrayBlockingQueue源码分析
2019-03-04
【网络通信 -- 直播】音视频常见封装格式 -- MEPG2 TS
2019-03-04
【网络通信 -- 直播】音视频常见封装格式 -- FLV
2019-03-04
【C/C++基础进阶系列】C/C++ 对象模型 -- 类基础知识总结(三)
2019-03-04
【C/C++基础进阶系列】C/C++ 对象模型 -- 对象语义
2019-03-04
基于FPGA的HDMI信号采样原理
2019-03-04
Spring 与使用STOMP消息
2019-03-04
Linux 查看系统语言
2019-03-04
十 一、C语言创建桌面程序:单选按钮、复选框和分组框控件
2019-03-04
Java Swing JList:列表框组件
2019-03-04
AngularJS $q
2019-03-04
jQuery中的动画
2019-03-04
Linux host命令
2019-03-04
MongoDB 查询分析
2019-03-04