一、简介
本文基于Matlab设计实现了一个文本相关的声纹识别系统,可以判定说话人身份。
1 系统原理
a.声纹识别
这两年随着人工智能的发展,不少手机App都推出了声纹锁的功能。这里面所采用的主要就是声纹识别相关的技术。声纹识别又叫说话人识别,它和语音识别存在一点差别。
b.梅尔频率倒谱系数(MFCC)
梅尔频率倒谱系数(Mel Frequency Cepstrum Coefficient, MFCC)是语音信号处理中最常用的语音信号特征之一。
实验观测发现人耳就像一个滤波器组一样,它只关注频谱上某些特定的频率。人耳的声音频率感知范围在频谱上的不遵循线性关系,而是在Mel频域上遵循近似线性关系。
梅尔频率倒谱系数考虑到了人类的听觉特征,先将线性频谱映射到基于听觉感知的Mel非线性频谱中,然后转换到倒谱上。普通频率转换到梅尔频率的关系式为:
c.矢量量化(VectorQuantization)
本系统利用矢量量化对提取的语音MFCC特征进行压缩。
VectorQuantization (VQ)是一种基于块编码规则的有损数据压缩方法。事实上,在 JPEG 和 MPEG-4 等多媒体压缩格式里都有 VQ 这一步。它的基本思想是:将若干个标量数据组构成一个矢量,然后在矢量空间给以整体量化,从而压缩了数据而不损失多少信息。
3 系统结构
本文整个系统的结构如下图:
–训练过程
首先对语音信号进行预处理,之后提取MFCC特征参数,利用矢量量化方法进行压缩,得到说话人发音的码本。同一说话人多次说同一内容,重复该训练过程,最终形成一个码本库。
–识别过程
在识别时,同样先对语音信号预处理,提取MFCC特征,比较本次特征和训练库码本之间的欧氏距离。当小于某个阈值,我们认定本次说话的说话人及说话内容与训练码本库中的一致,配对成功。
二、源代码
function varargout = test4(varargin)% TEST4 MATLAB code for test4.fig%TEST4, by itself, creates a new TEST4 or raises the existing%singleton*.%%H = TEST4 returns the handle to a new TEST4 or the handle to%the existing singleton*.%%TEST4('CALLBACK',hObject,eventData,handles,...) calls the local%function named CALLBACK in TEST4.M with the given input arguments.%%TEST4('Property','Value',...) creates a new TEST4 or raises the%existing singleton*. Starting from the left, property value pairs are%applied to the GUI before test4_OpeningFcn gets called. An%unrecognized property name or invalid value makes property application%stop. All inputs are passed to test4_OpeningFcn via varargin.%%*See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one%instance to run (singleton)".%% See also: GUIDE, GUIDATA, GUIHANDLES% Edit the above text to modify the response to help test4% Last Modified by GUIDE v2.5 17-Mar- 09:58:00% Begin initialization code - DO NOT EDITgui_Singleton = 1;gui_State = struct('gui_Name', mfilename, ...'gui_Singleton', gui_Singleton, ...'gui_OpeningFcn', @test4_OpeningFcn, ...'gui_OutputFcn', @test4_OutputFcn, ...'gui_LayoutFcn', [] , ...'gui_Callback', []);if nargin && ischar(varargin{1})gui_State.gui_Callback = str2func(varargin{1});endif nargout[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});elsegui_mainfcn(gui_State, varargin{:});end% End initialization code - DO NOT EDIT% --- Executes just before test4 is made visible.function test4_OpeningFcn(hObject, eventdata, handles, varargin)% This function has no output args, see OutputFcn.% hObject handle to figure% eventdata reserved - to be defined in a future version of MATLAB% handles structure with handles and user data (see GUIDATA)% varargin command line arguments to test4 (see VARARGIN)% Choose default command line output for test4handles.output = hObject;% Update handles structureguidata(hObject, handles);% UIWAIT makes test4 wait for user response (see UIRESUME)% uiwait(handles.figure1);% --- Outputs from this function are returned to the command line.function varargout = test4_OutputFcn(hObject, eventdata, handles) % varargout cell array for returning output args (see VARARGOUT);% hObject handle to figure% eventdata reserved - to be defined in a future version of MATLAB% handles structure with handles and user data (see GUIDATA)% Get default command line output from handles structurevarargout{1} = handles.output;% --- Executes on button press in pushbutton1.function pushbutton1_Callback(hObject, eventdata, handles)% hObject handle to pushbutton1 (see GCBO)% eventdata reserved - to be defined in a future version of MATLAB% handles structure with handles and user data (see GUIDATA)global thk1 thk2 thk3 global tlc1 tlc2 tlc3global tlyy1 tlyy2 tlyy3 global tqs1 tqs2 tqs3global tyqc1 tyqc2 tyqc3global startpos lenstartpos=601;len=399;[s,fs]=audioread('训练样本hk1.wav');thk1= MFCC2par(s,fs);thk1=thk1(startpos:startpos+len,1:12);[s,fs]=audioread('训练样本hk2.wav');thk2= MFCC2par(s,fs);thk2=thk2(startpos:startpos+len,1:12);[s,fs]=audioread('训练样本hk3.wav');thk3= MFCC2par(s,fs);thk3=thk3(startpos:startpos+len,1:12);[s,fs]=audioread('训练样本lc1.wav');tlc1= MFCC2par(s,fs);tlc1=tlc1(startpos:startpos+len,1:12);[s,fs]=audioread('训练样本lc2.wav');tlc2= MFCC2par(s,fs);tlc2=tlc2(startpos:startpos+len,1:12);[s,fs]=audioread('训练样本lc3.wav');tlc3= MFCC2par(s,fs);tlc3=tlc3(startpos:startpos+len,1:12);[s,fs]=audioread('训练样本lyy1.wav');tlyy1= MFCC2par(s,fs);tlyy1=tlyy1(startpos:startpos+len,1:12);[s,fs]=audioread('训练样本lyy2.wav');tlyy2= MFCC2par(s,fs);tlyy2=tlyy2(startpos:startpos+len,1:12);[s,fs]=audioread('训练样本lyy3.wav');tlyy3= MFCC2par(s,fs);tlyy3=tlyy3(startpos:startpos+len,1:12);[s,fs]=audioread('训练样本qs1.wav');tqs1= MFCC2par(s,fs);tqs1=tqs1(startpos:startpos+len,1:12);[s,fs]=audioread('训练样本qs2.wav');tqs2= MFCC2par(s,fs);tqs2=tqs2(startpos:startpos+len,1:12);[s,fs]=audioread('训练样本qs3.wav');tqs3= MFCC2par(s,fs);tqs3=tqs3(startpos:startpos+len,1:12);[s,fs]=audioread('训练样本yqc1.wav');tyqc1= MFCC2par(s,fs);tyqc1=tyqc1(startpos:startpos+len,1:12);[s,fs]=audioread('训练样本yqc2.wav');tyqc2= MFCC2par(s,fs);tyqc2=tyqc2(startpos:startpos+len,1:12);function getmfcc= MFCC2par( x,fs)%=========================================================% 无去噪及端点检测% Input:音频数据x,采样率fs% Output:(N,M)大小的特征参数矩阵 其中N为分帧个数,M为特征维度% 特征参数:M=24 倒谱系数12维,一阶差分12维%=========================================================%[x fs]=wavread(sound);%取单声道信号[~,etmp]=size(x);if (etmp==2)x=x(:,1);end%归一化mel滤波器组系数bank=melbankm(24,256,fs,0,0.5,'m');%Mel滤波器的阶数为24,fft变换的长度为256,采样频率为8000Hz bank=full(bank);bank=bank/max(bank(:));%[24*129]%设定DCT系数for k=1:12n=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=enframe(xx,256,80);%对x 256点分为一帧%计算每帧的MFCC参数for i=1:size(xx,1)y=xx(i,:);%取一帧数据s=y'.*hamming(256);t=abs(fft(s));%fft快速傅立叶变换 幅度谱t=t.^2; %能量谱%对fft参数进行mel滤波取对数再计算倒谱c1=dctcoef*log(bank*t(1:129));%对能量谱滤波及DCT %t(1:129)对一帧的前128个数(帧移为128)c2=c1.*w';%归一化倒谱%mfcc参数m(i,:)=c2';end