(1)端点检测部分(vad):
function [x1,x2] = vad(x)
%语音信号x幅度归一化到[-1,1]
x = double(x)
x = x / max(abs(x))
%常数设置
FrameLen = 240%帧长度为240
FrameInc = 80%帧移为80
amp1 = 10%短时能量高门限10
amp2 = 2%短时能量低门限为2
zcr1 = 10%短时过零率高门限为10
zcr2 = 5%短时过零率低门限为5
maxsilence =3%静音时间门限3*10ms= 30ms
minlen= 15%最小语音时间长度15*10ms = 150ms
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%符旁前帆号数组,用于存储相邻两个采样点符号是否相同,即是运雹否穿越0电平
diffs = (tmp1-tmp2)>0.02%度量相邻两个采样点之间距离,如果大于门限0.02(经验值),则1,否则0
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)/8)
%开始端点检测
x1 = 0
x2 = 0
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,
break
end
end
count = count-silence/2
x2 = x1 + count -1
subplot(311)
plot(x)
axis([1 length(x) -1 1])
xlabel('语音信号')
line([x1*FrameIncx1*FrameInc ],[-1,1],'Color','red')
line([x2*FrameIncx2*FrameInc ],[-1,1],'Color','red')
subplot(312)
plot(amp)
axis([1 length(amp) 0max(amp)])
xlabel('短时能量')
line([x1,x1],[min(amp),max(amp)],'Color','red')
line([x2,x2],[min(amp),max(amp)],'Color','red')
subplot(313)
plot(zcr)
axis([1 length(zcr) 0max(zcr)])
xlabel('过零率')
line([x1,x1],[min(zcr),max(zcr)],'Color','悔胡red')
line([x2,x2],[min(zcr),max(zcr)],'Color','red')
(2)MFCC部分:
function ccc = mfcc(x)
%归一化mel滤波器组系数
bank=melbankm(24,256,8000,0,0.5,'m')%24滤波器个数,8000采样频率
bank=full(bank)
bank=bank/max(bank(:))
% DCT系数,12*24
for k=1:12
n=0:23
dctcoef(k,:)=cos((2*n+1)*k*pi/(2*24))
end
%归一化倒谱提升窗口
w = 1 + 6 * sin(pi *(1:12) ./ 12)
w = w/max(w)
%预加重滤波器
xx=double(x)
xx=filter([1-0.9375],1,xx)
%语音信号分帧,xx是输入语音信号;256是帧长;80是帧移
xx=enframe(xx,256,80)
%计算每帧的MFCC参数
for i=1:size(xx,1)
y = xx(i,:)
s = y' .* hamming(256)%加汉明窗
t = abs(fft(s))%fft变换
t = t.^2
c1=dctcoef * log(bank * t(1:129))
c2 = c1.*w'
m(i,:)=c2'
end
%差分系数
dtm = zeros(size(m))
for i=3:size(m,1)-2
dtm(i,:) = -2*m(i-2,:) - m(i-1,:) + m(i+1,:)+ 2*m(i+2,:)
end
dtm = dtm / 3
%合并mfcc参数和一阶差分mfcc参数
ccc = [m dtm]
%去除首尾两帧,因为这两帧的一阶差分参数为0
ccc =ccc(3:size(m,1)-2,:)
(3)dtw计算部分:
function dist = dtw2(test, ref)
global x y_min y_max
global t r
global D d
global m n
t = test
r = ref
n = size(t,1)
m = size(r,1)
d = zeros(m,1)
D =ones(m,1) *realmax
D(1) = 0
%如果两个模板长度相差过多,匹配失败
if (2*m-n<3) || (2*n-m<2)
dist =realmax
return
end
%计算匹配区域
xa = round((2*m-n)/3)
xb = round((2*n-m)*2/3)
if xb>xa
%xb>xa,按下面三个区域匹配
%1:xa
%xa+1:xb
%xb+1:N
for x =1:xa
y_max= 2*x
y_min= round(0.5*x)
warp
end
for x =(xa+1):xb
y_max= round(0.5*(x-n)+m)
y_min= round(0.5*x)
warp
end
for x =(xb+1):n
y_max= round(0.5*(x-n)+m)
y_min= round(2*(x-n)+m)
warp
end
elseif xa>xb
%xa>xb,按下面三个区域匹配
%0:xb
%xb+1:xa
%xa+1:N
for x =1:xb
y_max= 2*x
y_min= round(0.5*x)
warp
end
for x =(xb+1):xa
y_max= 2*x
y_min= round(2*(x-n)+m)
warp
end
for x =(xa+1):n
y_max= round(0.5*(x-n)+m)
y_min= round(2*(x-n)+m)
warp
end
elseif xa==xb
%xa=xb,按下面两个区域匹配
%0:xa
%xa+1:N
for x =1:xa
y_max= 2*x
y_min= round(0.5*x)
warp
end
for x =(xa+1):n
y_max= round(0.5*(x-n)+m)
y_min= round(2*(x-n)+m)
warp
end
end
%返回匹配分数
dist = D(m)
function warp
global x y_min y_max
global t r
global D d
global m n
d = D
for y = y_min:y_max
D1 = D(y)
if y>1
D2= D(y-1)
else
D2 =realmax
end
if y>2
D3= D(y-2)
else
D3 = realmax
end
d(y) =sum((t(x,:)-r(y,:)).^2) + min([D1,D2,D3])
end
D = d
(4)测试函数testdtw部分;
disp('正在计算参考模板的参数...')
for i=1:10
fname = sprintf('G:\\石东东\\语音\\%da.wav',i-1)
x = wavread(fname)
[x1 x2] = vad(x)
m = mfcc(x)
m = m(x1-2:x2-2,:)
ref(i).mfcc = m
end
disp('正在计算测试模板的参数...')
for i=1:10
fname = sprintf('G:\\石东东\\语音\\%db.wav',i-1)
x = wavread(fname)
[x1 x2] = vad(x)
m = mfcc(x)
m = m(x1-2:x2-2,:)
test(i).mfcc = m
end
disp('正在进行模板匹配...')
dist = zeros(10,10)
for i=1:10
for j=1:10
dist(i,j) = dtw2(test(i).mfcc, ref(j).mfcc)
end
end
disp('正在计算匹配结果...')
for i=1:10
[d,j] = min(dist(i,:))
fprintf('测试模板%d的识别结果为:%d\n', i-1, j-1)
end
MFCC:Mel频率倒谱系数的缩写。Mel频率是基于人耳听觉特性提出来的,它与Hz频率成非线性对应关系。Mel频率倒谱系数(MFCC)则是利用它们之间的这种关系,计算得到的Hz频谱特征,MFCC已经广泛地应用在语音识别领域。由于Mel频率与Hz频率之间非线性的对应关系,使得MFCC随着频率的提高,其计算精度随之下降。因此,在应用中常常只使颂圆高用低频MFCC,而丢弃中高频MFCCmfcc提取流程/mfcc
MFCC参数的提取包括以下几个步骤:
预滤波:CODEC前端带宽为300-3400Hz的 抗混叠滤波器 。
A/D变换:8kHz的采样频率,12bit的线性 量化精度 。
预加重:通过一个一阶有限激励响应高通滤波器,使信号的频谱变得平坦,不易受到有限字长效应的影响。
分帧:根据语音的短时平稳特性,语音可以以帧为单位进行处理,实验中选取的语音帧长为32ms,帧叠为16ms。
加窗:采用哈明窗对一帧语音加窗,以减小 吉布斯效应 的影响。
快速傅立叶变换(Fast Fourier Transformation, FFT):将时域信号变换成为信号的功率谱。
三角窗滤波:用一组Mel频标上线性分布的三角窗滤波器(共24个三角窗滤波器),对信号的功率谱滤波,每一个三角窗滤波器覆盖的范围都近似于人耳的一个临界带宽,以此来模拟人耳的 掩野尺蔽效应 。
求对数:三角窗滤波器组的输出求取对数,可以得到近似于同态变换的结果。
离散余弦变换(Discrete Cosine Transformation, DCT):去除各维信号之间的相关性,将信号映射到低维空间。
谱加权:由于倒谱的低阶参数易受说话人特性、信道特性等的影响,而高阶参数的分辨能力比较低,所以需要进行谱加权,抑制其低阶和高阶参数。
腔正 倒谱均值减(Cepstrum Mean Subtraction, CMS):CMS可以有效地减小语音输入信道对特征参数的影响。
差分参数:大量实验表明,在语音特征中加入表征语音动态特性的差分参数,能够提高系统的识别性能。在本系统中,我们也用到了MFCC参数的一阶差分参数和 二阶差分 参数。
短时能量:语音的短时能量也是重要的特征参数,本系统中我们采用了语音的短时归一化对数能量及其一阶差分、二阶差分参数。
1、用audioread('')函数读取电脑音频文件参数音频文件路径:[sampledata,FS] = audioread('F:1.mp3')
sampledata保存音频信号数据FS音频采率MP3格式采率般44100;
2、判断音频数据否双郑弯声道双声道则保留声道数据弯丛知埋消用calsample.m文件函数完功能文件内容:
function sample = calsample(sampledata,FS)
temp_sample = resample(sampledata,1,FS/11025)
[m,n] = size(temp_sample)
if (n == 2)
sample = temp_sample(:,1)
else
sample = temp_sample
end
end
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)