当前位置:   article > 正文

MATLAB识别座机拨号号码(DTMF信号)_dtmf给座机打电话

dtmf给座机打电话

编写原因

课程作业,菜狗乱写,希望能给学弟学妹们一些微不足道的参考,本人是一名普通大学生,根据课程学习了一些代码编写知识,本篇是数字信号综合实验内容之一,内容是识别一段音频中的电话号码。之所以写下这篇文章是因为我想起了当初什么都不懂时去做课程实验(某数电FPGA实验)的无助,偶然之间发现一位学长在此留下的指引,向他学习,人家真材实料,我就洒洒水。代码没啥技术含量,大家看个乐子就行。

DTMF编码

网上有很详细的介绍,我这里就不多说了,直接上代码。

主要代码

1.主函数
  1. close all;
  2. clear ;
  3. clc
  4. Filename='文件名';
  5. [audio_1,Fs] = audioread(Filename);%读取音频文件
  6. audio=audio_1(:,1);
  7. sound(audio,Fs);%播放音频文件
  8. %% 预设相关形参
  9. result="The phone number is:";
  10. MAX=1/4*max(audio);
  11. audiolength=length(audio);
  12. t=1:1:audiolength;
  13. length=11;
  14. %% 实现信号分段和分别检测
  15. for i = 1:length
  16. unanalyse=zeros(1,10000);%数据采集
  17. num=1;
  18. issampling=0;%判读是否在采集声音信号段
  19. for j = 1:audiolength
  20. pan=0;
  21. if (audio(j) > MAX) && (issampling == 0)%标记开始位
  22. issampling = 1;
  23. unanalyse(num) = audio(j);
  24. audio(j) = 0;
  25. num = num + 1;
  26. continue;
  27. end
  28. if issampling == 1%采集数据并确定数据长度
  29. unanalyse(num) = audio(j);
  30. audio(j)=0;
  31. num=num+1;
  32. if audio(j+1) < MAX
  33. for s = 1:7000%判断长度
  34. if audio(j+s) < MAX
  35. pan=pan+1;%无效信号标志位
  36. end
  37. end
  38. end
  39. end
  40. if pan == 7000
  41. break;
  42. end
  43. end
  44. keynum=detect(unanalyse,10000,Fs);%计算每段截取信号代表的数字
  45. result=strcat(result,keynum);%将数字加到字符串末尾
  46. end
  47. disp(result);

简单说一下奥,这里我用的是作业中自带的音频信号。文件就是一段拨号录音。

里面的MAX是用来咱们信号每段的开始点的,后面那个‘pan’就是为了判定是否已经截完一个音的信号,因为每个按键之间有一定的间隔,这段时间内,原信息的数值远小于按键响时的数值。当然,这些参数大家可以根据自己的音频进行修改。

2.调用函数(detect.m)

用来判断截取信息所对应的按键

  1. function [keynum]=detect(audio,audiolength,Fs)
  2. t=1:1:audiolength;
  3. % figure(1)
  4. % subplot(2,1,1)
  5. % plot(t,audio)
  6. audio=filter(filter_1,audio);%滤除噪声干扰
  7. % subplot(2,1,2)
  8. % plot(t,audio);
  9. audio_fft=abs(fft(audio));
  10. figure(2)
  11. % plot(t,audio_fft);
  12. %
  13. % fre_h1=ceil(1209*audiolength/Fs);
  14. % fre_h2=ceil(1336*audiolength/Fs);
  15. % fre_h3=ceil(1477*audiolength/Fs);
  16. % fre_h4=ceil(1633*audiolength/Fs);
  17. %
  18. % fre_L1=ceil(697*audiolength/Fs);
  19. % fre_L2=ceil(770*audiolength/Fs);
  20. % fre_L3=ceil(852*audiolength/Fs);
  21. % fre_L4=ceil(941*audiolength/Fs);
  22. audio_test=audio_fft;
  23. %% 取fft的前半段结果分析双频数值
  24. for i=ceil(audiolength/2):audiolength
  25. audio_fft(i)=0;
  26. end
  27. [max_1,index_1]=max(audio_fft);
  28. fre_1=ceil((index_1+1)/audiolength*48000);
  29. for i=0:40%设置40就是相当于设置一个频率计算的容错范围,把你算出来的高/低频信号减去,方便对第二个频率进行分析,下面同理
  30. audio_fft(index_1+i)=0;
  31. audio_fft(index_1-i)=0;
  32. end
  33. %之所以写这一块是因为有些音频他干扰比较离谱,会影响分析
  34. if fre_1>1000 && fre_1<1100
  35. [max_1,index_1]=max(audio_fft);
  36. fre_1=ceil((index_1+1)/audiolength*48000);
  37. end
  38. [max_2,index_2]=max(audio_fft);
  39. fre_2=ceil((index_2+1)/audiolength*48000);
  40. for i=0:40
  41. audio_fft(index_2+i)=0;
  42. audio_fft(index_2-i)=0;
  43. end
  44. if fre_2>1000 && fre_2<1100
  45. [max_2,index_2]=max(audio_fft);
  46. fre_2=ceil((index_2+1)/audiolength*48000);
  47. end
  48. %分辨高频低频
  49. if fre_1<fre_2
  50. tab=fre_1;
  51. fre_1=fre_2;
  52. fre_2=tab;
  53. end
  54. %俩参数代指高低频对应位置,判断按键类型
  55. low=0;
  56. high=0;
  57. %确认信号双频这块写的就比较随意了,因为分析等各种原因,总会与实际产生不少误差,写的比较夸张,理解原理就行
  58. if fre_1 >1200 && fre_1 < 1300
  59. high=1;
  60. elseif fre_1 >1330 && fre_1 < 1370
  61. high=2;
  62. elseif fre_1 >1450 && fre_1 < 1500
  63. high=3;
  64. elseif fre_1 >1600 && fre_1 < 1670
  65. high=4;
  66. end
  67. if fre_2 >600 && fre_2 < 734
  68. low=1;
  69. elseif fre_2 >734 && fre_2 < 810
  70. low=2;
  71. elseif fre_2 >810 && fre_2 < 896
  72. low=3;
  73. elseif fre_2 >896 && fre_2 < 1000
  74. low=4;
  75. end
  76. %把按键赋给输出值
  77. if high == 1 && low == 1
  78. keynum='1';
  79. elseif high == 2 && low ==1
  80. keynum='2';
  81. elseif high == 3 && low ==1
  82. keynum='3';
  83. elseif high == 4 && low ==1
  84. keynum='A';
  85. elseif high == 1 && low ==2
  86. keynum='4';
  87. elseif high == 2 && low ==2
  88. keynum='5';
  89. elseif high == 3 && low ==2
  90. keynum='6';
  91. elseif high == 4 && low ==2
  92. keynum='B';
  93. elseif high == 1 && low ==3
  94. keynum='7';
  95. elseif high == 2 && low ==3
  96. keynum='8';
  97. elseif high == 3 && low ==3
  98. keynum='9';
  99. elseif high == 4 && low ==3
  100. keynum='C';
  101. elseif high == 1 && low ==4
  102. keynum='*';
  103. elseif high == 2 && low ==4
  104. keynum='0';
  105. elseif high == 3 && low ==4
  106. keynum='#';
  107. elseif high == 4 && low ==4
  108. keynum='D';
  109. end
  110. end
3.滤波器

我用的这个是个低通滤波器,把小于500HZ的噪声全滤除了,当然有更好的选择,大家根据实际进行调整,MATLAB中自带设计滤波器的工具(命令行打filterDesigner),用法网上很多。

  1. function Hd = filter_1
  2. %UNTITLED 返回离散时间滤波器对象。
  3. % MATLAB Code
  4. % Generated by MATLAB(R) 9.10 and Signal Processing Toolbox 8.6.
  5. % Generated on: 09-Dec-2023 11:13:57
  6. % FIR Window Bandpass filter designed using the FIR1 function.
  7. % All frequency values are in Hz.
  8. Fs = 48000; % Sampling Frequency
  9. Fstop1 = 500; % First Stopband Frequency
  10. Fpass1 = 600; % First Passband Frequency
  11. Fpass2 = 2000; % Second Passband Frequency
  12. Fstop2 = 2500; % Second Stopband Frequency
  13. Dstop1 = 0.001; % First Stopband Attenuation
  14. Dpass = 0.057501127785; % Passband Ripple
  15. Dstop2 = 0.0001; % Second Stopband Attenuation
  16. flag = 'scale'; % Sampling Flag
  17. % Calculate the order from the parameters using KAISERORD.
  18. [N,Wn,BETA,TYPE] = kaiserord([Fstop1 Fpass1 Fpass2 Fstop2]/(Fs/2), [0 ...
  19. 1 0], [Dstop1 Dpass Dstop2]);
  20. % Calculate the coefficients using the FIR1 function.
  21. b = fir1(N, Wn, TYPE, kaiser(N+1, BETA), flag);
  22. Hd = dfilt.dffir(b);
  23. % [EOF]
  24. % [EOF]

补充说明

第一次写博客,也不太懂规矩,上述代码基本上都是了解原理后自行编写的,如有雷同应该纯属意外,我也不会闲的没事copy或东拉西扯一堆拼接过来给自己找麻烦。当然,如果真的有什么所谓的雷同而影响到别人的博客,联系我,立刻删除,摆烂大学生不想惹祸上身。爱门。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/315216?site
推荐阅读
相关标签
  

闽ICP备14008679号