赞
踩
课程作业,菜狗乱写,希望能给学弟学妹们一些微不足道的参考,本人是一名普通大学生,根据课程学习了一些代码编写知识,本篇是数字信号综合实验内容之一,内容是识别一段音频中的电话号码。之所以写下这篇文章是因为我想起了当初什么都不懂时去做课程实验(某数电FPGA实验)的无助,偶然之间发现一位学长在此留下的指引,向他学习,人家真材实料,我就洒洒水。代码没啥技术含量,大家看个乐子就行。
网上有很详细的介绍,我这里就不多说了,直接上代码。
- close all;
- clear ;
- clc
-
- Filename='文件名';
- [audio_1,Fs] = audioread(Filename);%读取音频文件
- audio=audio_1(:,1);
- sound(audio,Fs);%播放音频文件
-
- %% 预设相关形参
- result="The phone number is:";
- MAX=1/4*max(audio);
- audiolength=length(audio);
- t=1:1:audiolength;
- length=11;
-
-
- %% 实现信号分段和分别检测
- for i = 1:length
- unanalyse=zeros(1,10000);%数据采集
- num=1;
- issampling=0;%判读是否在采集声音信号段
- for j = 1:audiolength
- pan=0;
- if (audio(j) > MAX) && (issampling == 0)%标记开始位
- issampling = 1;
- unanalyse(num) = audio(j);
- audio(j) = 0;
- num = num + 1;
- continue;
- end
- if issampling == 1%采集数据并确定数据长度
- unanalyse(num) = audio(j);
- audio(j)=0;
- num=num+1;
- if audio(j+1) < MAX
- for s = 1:7000%判断长度
- if audio(j+s) < MAX
- pan=pan+1;%无效信号标志位
- end
- end
- end
- end
- if pan == 7000
- break;
- end
- end
- keynum=detect(unanalyse,10000,Fs);%计算每段截取信号代表的数字
- result=strcat(result,keynum);%将数字加到字符串末尾
- end
-
- disp(result);

简单说一下奥,这里我用的是作业中自带的音频信号。文件就是一段拨号录音。
里面的MAX是用来咱们信号每段的开始点的,后面那个‘pan’就是为了判定是否已经截完一个音的信号,因为每个按键之间有一定的间隔,这段时间内,原信息的数值远小于按键响时的数值。当然,这些参数大家可以根据自己的音频进行修改。
用来判断截取信息所对应的按键
- function [keynum]=detect(audio,audiolength,Fs)
- t=1:1:audiolength;
- % figure(1)
- % subplot(2,1,1)
- % plot(t,audio)
- audio=filter(filter_1,audio);%滤除噪声干扰
- % subplot(2,1,2)
- % plot(t,audio);
- audio_fft=abs(fft(audio));
- figure(2)
- % plot(t,audio_fft);
- %
- % fre_h1=ceil(1209*audiolength/Fs);
- % fre_h2=ceil(1336*audiolength/Fs);
- % fre_h3=ceil(1477*audiolength/Fs);
- % fre_h4=ceil(1633*audiolength/Fs);
- %
- % fre_L1=ceil(697*audiolength/Fs);
- % fre_L2=ceil(770*audiolength/Fs);
- % fre_L3=ceil(852*audiolength/Fs);
- % fre_L4=ceil(941*audiolength/Fs);
-
- audio_test=audio_fft;
- %% 取fft的前半段结果分析双频数值
- for i=ceil(audiolength/2):audiolength
- audio_fft(i)=0;
- end
- [max_1,index_1]=max(audio_fft);
- fre_1=ceil((index_1+1)/audiolength*48000);
- for i=0:40%设置40就是相当于设置一个频率计算的容错范围,把你算出来的高/低频信号减去,方便对第二个频率进行分析,下面同理
- audio_fft(index_1+i)=0;
- audio_fft(index_1-i)=0;
- end
- %之所以写这一块是因为有些音频他干扰比较离谱,会影响分析
- if fre_1>1000 && fre_1<1100
- [max_1,index_1]=max(audio_fft);
- fre_1=ceil((index_1+1)/audiolength*48000);
- end
- [max_2,index_2]=max(audio_fft);
- fre_2=ceil((index_2+1)/audiolength*48000);
- for i=0:40
- audio_fft(index_2+i)=0;
- audio_fft(index_2-i)=0;
- end
- if fre_2>1000 && fre_2<1100
- [max_2,index_2]=max(audio_fft);
- fre_2=ceil((index_2+1)/audiolength*48000);
- end
-
- %分辨高频低频
- if fre_1<fre_2
- tab=fre_1;
- fre_1=fre_2;
- fre_2=tab;
- end
- %俩参数代指高低频对应位置,判断按键类型
- low=0;
- high=0;
- %确认信号双频这块写的就比较随意了,因为分析等各种原因,总会与实际产生不少误差,写的比较夸张,理解原理就行
- if fre_1 >1200 && fre_1 < 1300
- high=1;
- elseif fre_1 >1330 && fre_1 < 1370
- high=2;
- elseif fre_1 >1450 && fre_1 < 1500
- high=3;
- elseif fre_1 >1600 && fre_1 < 1670
- high=4;
- end
-
- if fre_2 >600 && fre_2 < 734
- low=1;
- elseif fre_2 >734 && fre_2 < 810
- low=2;
- elseif fre_2 >810 && fre_2 < 896
- low=3;
- elseif fre_2 >896 && fre_2 < 1000
- low=4;
- end
- %把按键赋给输出值
- if high == 1 && low == 1
- keynum='1';
- elseif high == 2 && low ==1
- keynum='2';
- elseif high == 3 && low ==1
- keynum='3';
- elseif high == 4 && low ==1
- keynum='A';
- elseif high == 1 && low ==2
- keynum='4';
- elseif high == 2 && low ==2
- keynum='5';
- elseif high == 3 && low ==2
- keynum='6';
- elseif high == 4 && low ==2
- keynum='B';
- elseif high == 1 && low ==3
- keynum='7';
- elseif high == 2 && low ==3
- keynum='8';
- elseif high == 3 && low ==3
- keynum='9';
- elseif high == 4 && low ==3
- keynum='C';
- elseif high == 1 && low ==4
- keynum='*';
- elseif high == 2 && low ==4
- keynum='0';
- elseif high == 3 && low ==4
- keynum='#';
- elseif high == 4 && low ==4
- keynum='D';
- end
- end

我用的这个是个低通滤波器,把小于500HZ的噪声全滤除了,当然有更好的选择,大家根据实际进行调整,MATLAB中自带设计滤波器的工具(命令行打filterDesigner),用法网上很多。
- function Hd = filter_1
- %UNTITLED 返回离散时间滤波器对象。
-
- % MATLAB Code
- % Generated by MATLAB(R) 9.10 and Signal Processing Toolbox 8.6.
- % Generated on: 09-Dec-2023 11:13:57
-
- % FIR Window Bandpass filter designed using the FIR1 function.
-
- % All frequency values are in Hz.
- Fs = 48000; % Sampling Frequency
-
- Fstop1 = 500; % First Stopband Frequency
- Fpass1 = 600; % First Passband Frequency
- Fpass2 = 2000; % Second Passband Frequency
- Fstop2 = 2500; % Second Stopband Frequency
- Dstop1 = 0.001; % First Stopband Attenuation
- Dpass = 0.057501127785; % Passband Ripple
- Dstop2 = 0.0001; % Second Stopband Attenuation
- flag = 'scale'; % Sampling Flag
-
- % Calculate the order from the parameters using KAISERORD.
- [N,Wn,BETA,TYPE] = kaiserord([Fstop1 Fpass1 Fpass2 Fstop2]/(Fs/2), [0 ...
- 1 0], [Dstop1 Dpass Dstop2]);
-
- % Calculate the coefficients using the FIR1 function.
- b = fir1(N, Wn, TYPE, kaiser(N+1, BETA), flag);
- Hd = dfilt.dffir(b);
-
- % [EOF]
- % [EOF]

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