logo资料库

说话人识别代码 MATLAB 端点检测 预加重 MFCC.doc

第1页 / 共7页
第2页 / 共7页
第3页 / 共7页
第4页 / 共7页
第5页 / 共7页
第6页 / 共7页
第7页 / 共7页
资料共7页,全文预览结束
说话人识别
说话人识别 SMALL_MFCC 是子程序,调用生成 MEL 系数,供神经网络 训练使用 clear; close all; Time1=cputime; CM=[]; %----------提取系数-------------------- %-----------读语音数据------------- for sound_dgital=1:2 sound=['11.wav';'21.wav';'31.wav']; str=double(sound); wav_name=char(str(sound_dgital,:)); [signal,fs]=wavread(wav_name); data1=signal(:,1); %???????????? data2=signal(:,2); Data=cat(1,data1,data2); %-----------端点检测------------- i=1; while data1(i+1)-data1(i)<0.014 i=i+1; end j=length(data1); while data1(j-1)-data1(j)<0.014 j=j-1; end %--------------------------- %-----------预加重------------- figure(sound_dgital)
subplot(2,1,1) plot(data1) title('加重前信号') %加重系数 a=0.98; for n=2:length(data1) data1(n-1)=data1(n)-a*data1(n-1); end figure(sound_dgital) subplot(2,1,2) plot(data1) title('加重后信号') %------------------------------ %-----------fourier 变换定义------------- N=256;shift=80;nfft=256; numoverlap=N-shift; t1=i/8000;t2=j/8000; lent=length(data1); %------------------------------ %-----------取成一维语音数据------------- dd=1; for d=i:1:j data(dd)=data1(d); dd=dd+1; end %------------------------------ %-------------MFCC------------- C=small_MFCC(data,nfft,N,numoverlap,shift,fs) CM=cat(2,CM,C)
%------------------------------ end %-----------神经网络部分------------- [N,m1]=size(CM); %神经网络初始化 n1=1; %定义输入神经元个数 M=256; %定义输出神经元个数 X=CM;%预定义输入矢量矩阵 W=rand(16,256)*255; %权值的初始化 W=round(W);%权值取整 T1=n1*m1;%学习次数 T2=200; %训练 s=round(rand(1,n1*m1)*(n1*m1-1));%产生一个随机矩阵,以便随机选取样本图 像矢量,范围(0,4095) s=s+1;%s 范围变为(1,4096) %权值调整 for(t=1:T2) %开始训练,从 1 到 T2 t; for(T=1:T1) %开始取输入图像矢量 NE=-132+362*exp(-T/T1); %定义邻域大小函数 NE=round(NE); %计算邻域半径 if(rem(NE,2)==0) R=NE/2; else R=(NE-1)/2; end %找出最小欧氏距离 for(j=1:256) P(:,j)=(X(:,s(1,T))-W(:,j)).^2;%计算欧氏距离 Q(1,j)=sum(P(:,j)); %欧氏距离和赋予新的矩阵 [minQ,I]=min(Q);%找出最小数的下标,等同于输出矢量的下标
end r0=I; %最小距离下标赋予 r0 %在邻域内调整权值 stu=0.5*exp(-t/T2); %定义学习函数 if(I<=R) %邻域节点下标是负数时,即超出矩阵维数,邻域从 1 开始 for(j=1:I+R) r=j; stu_f=exp(-(r-r0).^2/(230*exp(-t/T2)));%定义学习加权邻域函数 W(:,j)=W(:,j)+stu*stu_f*(X(:,s(1,T))-W(:,j)); end elseif(I>=256-R) %邻域节点下标大于 256 时,即超出矩阵维数,邻域到 256 止 for(j=I-R:256) r=j; stu_f=exp(-(r-r0).^2/(230*exp(-t/T2)));%定义学习加权邻域函数 W(:,j)=W(:,j)+stu*stu_f*(X(:,s(1,T))-W(:,j)); end else for(j=I-R:I+R) r=j; stu_f=exp(-(r-r0).^2/(230*exp(-t/T2)));%定义学习加权邻域函数 W(:,j)=W(:,j)+stu*stu_f*(X(:,s(1,T))-W(:,j)); end end end end W=round(W) save codebookbeeline W; %码书保存 W=uint8(W); mesh(W); Time2=cputime-Time1 imwrite(W,'beeline.bmp'); figure(64) imshow('beeline.bmp');
MFCC function C1=small_MFCC(data,nfft,N,numoverlap,shift,fs) %帧间移动 fft_window=specgram(data,nfft,fs,hamming(N),numoverlap); %每列代表每帧的 fft 变换 fft_frequency=abs(fft_window); SM=[]; [frame_rows,frame_sum_colums]=size(fft_frequency); %应该加循环对每个列进行滤波,每个列代表一个窗 for fft_colums=1:frame_sum_colums evf=fft_frequency(:,fft_colums); for filter_S=1:24 c=100; %定义滤波器阶数 97 阶 fc1=[300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950, 1123,1296,1469,1642,1815,1988,2161,2334,2507,2853];% 下限截止频率 fc2=[400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000 ,1296, 1469,1642,1815,1988,2161,2334,2507,2853,3199,3545];% 上 限 截 止 频率 %参数转换,将模拟滤波器的技术指标转换为数字滤波器的技术指标
w1=2*pi*fc1(filter_S)/fs; w2=2*pi*fc2(filter_S)/fs; %使用三角窗函数 window=triang(c+1); %使用标准响应的加窗设计函数 fir1 h=fir1(c,[w1/pi w2/pi],window); %第 frame 帧滤波结果 S(:,filter_S)=filter(h,1,evf); end SM=cat(2,SM,S);%得到一个 Mel 频谱 S(:)=[]; end %得到一个数字 Mel 频谱 %滤波器组输出的对数能量为 CM %206 帧,每个帧经过个滤波器,最后得到 206*13 个对数能量输出 colums_sum=length(SM); for colums_s=1:colums_sum %每一列进行对数能量处理 colums_s for log_s=1:frame_rows%行循环 A=((abs(SM(log_s,colums_s)).^2)*hamming(log_s)); end
end %得到余弦变换系数 C=dct(log(A)); C1=dct(A,16) clear frame_sum_colums; return
分享到:
收藏