本帖最后由 想回到那一天 于 2018-4-30 20:29 编辑
%function number=duandianjiance() %函数返回的就是读到的拨号值
%读一段语音信号 这里要填写语音信号的绝对路径
clc
clear
[x, Fs]=audioread('matlab1.wav');
x = double(x);
x = x / max(abs(x));%幅度归一化到[-1,1]
fp1=[500 1700]; fp2=[300 2100];
[n1,Wn1]=ellipord(fp1*2/Fs,fp2*2/Fs,0.5,40);
[b1,a1]=ellip(n1,0.5,40,Wn1);
Output=filter(b1,a1,x);
x=Output;
y=zeros(1,length(x)); %声明y为去掉空白音之后保存新的信号
%常数设置
FrameLen = 240;%帧长
FrameInc = 80;%分帧未重叠部分
amp1 = 30; %短时能量阈值
amp2 = 30; %即设定能量的两个阈值。
zcr1 = 20;%过零率阈值
zcr2 = 5; %过零率的两个阈值
maxsilence = 8; %用无声的长度来判断语音是否结束
minlen = 40; %判断是语音的最小长度
status = 0;%记录语音段的状态
count = 0; %语音序列的长度
silence = 0; %无声的长度
%计算过零率
tmp1 = enframe(x(1:end-1), FrameLen, FrameInc);
tmp2 = enframe(x(2:end) , FrameLen, FrameInc);
signs = (tmp1.*tmp2)<0;
diffs = (tmp1 -tmp2)>0.02;
zcr = sum(signs.*diffs, 2);
%计算短时能量
amp = sum(abs(enframe(filter([1 -0.9375], 1, x), FrameLen, FrameInc)), 2);
%调整能量门限
amp1 = min(amp1, max(amp)/2);
amp2 = min(amp2, max(amp)/2.5);
%开始端点检测
x1 = 0;
x2 = 0;
length_now=1;
for n=1:length(zcr)
goto = 0;
switch status
case {0,1} % 0 = 静音, 1 = 可能开始
if amp(n) > amp1 % 确信进入语音段
x1 = max(n-count-1,1);
status = 2;
silence = 0;
count = count + 1;
elseif amp(n) > amp2 | ... % 可能处于语音段
zcr(n) > zcr2
status = 1;
count = count + 1;
else % 静音状态
status = 0;
count = 0;
end
case 2, % 2 = 语音段
if amp(n) > amp2 | ... % 保持在语音段
zcr(n) > zcr2
count = count + 1;
else % 语音将结束
silence = silence+1;
if silence < maxsilence % 静音还不够长,尚未结束
count = count + 1;
elseif count < minlen % 语音长度太短,认为是噪声
status = 0;
silence = 0;
count = 0;
else % 语音结束
status = 3;
end
end
case 3,
count = count-silence/2;
x2 = x1 + count -1;%记录语音段结束点 x1为起始点,x2为结束点
%将每一个语音信号长度限制到6900方便后面识别
if ((x2*FrameInc-x1*FrameInc)<6900)
x3=[x(x1*FrameInc:x2*FrameInc)',zeros(1,(6900-x2*FrameInc+x1*FrameInc))]';
else
x3=x(x1*FrameInc:(x1*FrameInc+6900));
end
y(length_now:(length_now+length(x3)-1))=x3;%将每次得到的一个拨号音添加到y序列里面
length_now=length_now+length(x3); %记录非空白语音长度
status=0;
count=0;
end
end
%这些都是简单的小时
y1=y(1:length_now);
%subplot(211)
figure(1)
plot(x) %显示原语音信号的时域谱
%subplot(212)
figure(2)
plot(y1) %显示端点检测滤波之后的时域谱
%wavplay(y1,Fs);
number=shibie(y1,Fs);%调用识别函数进行识别
其中的shibei和enframe子函数是有的,程序没什么语法错误,但是检测不了电话号码出来,是为啥?
2018-4-30 20:29 上传
点击文件名下载附件
53.48 KB, 下载次数: 22