📄 pipei.m
字号:
%该段程序实现将手机号码语音x经端点检测出的第i个号的语音分帧提取LPC特征参数与码本匹配,求出各帧所对应的索引号
%先进行端点检测
function pipei(x)
%幅度归一化到[-1,1]
x=double(x);
x=x/max(abs(x));
%常数设置
FrameLen=240; %8k采样,30ms对应240点
FrameInc=240; %30ms对应桢移240点
amp1=2;
amp2=0.3;
zcr1=20;
zcr2=0.0005;
maxsilence=3; %3*30ms=90ms
minlen=6; %6*30ms=180ms
status=0;
count=0; %语音长度
silence=0;
%计算过零率
tmp1=enframe(x(1:length(x)-1),FrameLen,FrameInc);
tmp2=enframe(x(2:length(x)),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)/4);
amp2=min(amp2,max(amp)/9);
d=zeros(22,1);
d(1)=1;
d(2)=1;
%开始端点检测
for i=0:10
status=0;
count=0;
for n=d(2*i+1):length(zcr)
switch status
case 0,
if amp(n)>amp2|zcr(n)>zcr2 %满足此条件假定进入语音段
count=count+1;
status=1;
silence=0;
else %静音状态
status=0;
count=0;
end
case 1,
if amp(n)>amp2|zcr(n)>zcr2 %保持在语音段
count=count+1;
d(2*i+1)=max(n-count,1);
else %语音将结束
silence=silence+1;
if silence<maxsilence %静音还不够长,尚未结束
count=count+1;
elseif count<minlen %语音长度太短,认为是噪声
status=0;
silence=0;
count=0;
else %语音结束
status=2;
end
end
case 2,
break;
end
end
count=count-silence/2;
d(2*i+2)=d(2*i+1)+count-0.5;
d(2*i+3)=fix(d(2*i+2)+5);
end
%将手机号码语音经端点检测出的第i个号的语音分帧提取LPC特征参数与码本匹配,求出各帧所对应的索引号
load('index','i');
n=d(2*i+2)-d(2*i+1);
p=d(2*i+1)*240;
v1=x(p+1:p+240);
cx=lpc(v1,12)';
c3=cx(2:13);
p=p+240;
for i=1:n-1
y=x(p+1:p+240);
cx1=lpc(y,12)';
c1=cx1(2:13);
c3=horzcat(c3,c1);
p=p+240;
end
load('codebook','cw');
d=disteu(c3,cw);
[m,index1]=min(d,[],2);
%对得到的索引号做一定的处理,减少匹配错误,方法是将连续相同的索引号中间出现跳变的索引号改为与前后索引号相同
if index1(1)~=index1(2);
index1(2)=index1(1);
end
for i=2:length(index1)-1
if index1(i-1)==index1(i+1)&&index1(i)~=index1(i+1)
index1(i)=index1(i+1);
end
end
l=length(index1);
if index1(l-1)~=index1(l)
index1(l)=index1(l-1);
end
transindex=index1;
save('transmittedindex','transindex');
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -