如何在MATLAB中使用MFCC方法进行语音识别?
我正在开发一个语音识别引擎,用于识别少数(10-14个)孤立单词。我正在使用MFCC(Mel频率倒谱系数)方法,并使用MATLAB进行处理。我指的是一篇研究论文、一个网站和其他来源。我已经提到了下面的链接。以下是我面临的主要问题:如何在MATLAB中使用MFCC方法进行语音识别?,matlab,speech-recognition,mfcc,filter-bank,Matlab,Speech Recognition,Mfcc,Filter Bank,我正在开发一个语音识别引擎,用于识别少数(10-14个)孤立单词。我正在使用MFCC(Mel频率倒谱系数)方法,并使用MATLAB进行处理。我指的是一篇研究论文、一个网站和其他来源。我已经提到了下面的链接。以下是我面临的主要问题: 知道我选择的44100Hz的采样频率是否正确 计算Mel滤波器组矩阵所选择的低频率=300Hz,高频率=8000Hz是否正确 我选择的帧大小=256,滤波器组(系数)数量=20是否适合我的应用 使用的预加重过滤器是否良好? 或者我应该使用巴特沃斯过滤器 处理前/过滤后
wordArray= {'begin', 'continue', 'exit', 'move', 'save', 'undo'};
% //NOT USING THESE REMAINING WORDS NOW :, 'a', 'b', 'c', 'd', 'one', 'two', 'three', 'four', 'a1', 'a2', 'a3', 'a4'};
SevenStep();
for j=1:6 %for all words in database
ADDITION=0;
disp(strcat('CHECKING FOR THE WORD: ',upper(wordArray{j})));
for i=1:15 % each word has 15 samples for testing the accuracy of system
[Value1]=SevenStepTestSample(strcat('C:\Users\Ray\Documents\BE Project\Phase-III\FreshAudioSamples\test\',wordArray{j},num2str(i),'.wav'));
Result1=strcmpi(Value1,wordArray{j});
%Result2=strcmpi(Value2,wordArray{j});
ADDITION=ADDITION+((Result1));
end
fprintf('%s\t%d\n',upper(wordArray{j}),ADDITION); %Used to display no. of words correctly identified out of 15
end
七步
function SevenStep()
tic
%-----------------------------------------------------------------INITIALISATION---------------------------------------------------------------%
path_start='C:\Users\Ray\Documents\BE Project\Phase-III\FreshAudioSamples\';
path_end='.wav';
alpha=0.97;
fs=44100; %frequency at which I have sampled my recorded samples
pad_length=120064;
numSamplesOfEachWord=30; %in database of samples
numOfWords=6;
frame_length=256; %How to choose an appropriate frame-size?
no_of_frames=pad_length/(int32(frame_length/2)); %since overlap is 50%
low_freq=300; %lower frequency for calculation of mel frequency filter bank (I'm unable to choose a correct one, and find the criteria for choosing it)
high_freq=8000; %upper frequency for calculation of mel frequency filter bank (I'm unable to choose a correct one, and find the criteria for choosing it)
no_of_coeffs=20; % This is no. of Mel-Filter banks to create. how to choose a approriate value for this?
%{
fnm = 'C:\Users\Ray\Documents\BE Project\Phase-III\trifbank.mat';
m1= matfile(fnm);
H=m1.H;
//Method 2 which I used to calculate when my Mel Frequency Filter Bank
(given below) was probably not working correctly
%}
%--------------------------------------------------PRE-PROCESSING FOR MEL FILTER BANK CREATION-----------------------------------------------%
low_linear=2595*log10(1+(low_freq/700));
high_linear=2595*log10(1+(high_freq/700));
band_length=(high_linear-low_linear)/(no_of_coeffs+1);
MelArray(no_of_coeffs+2,1)=zeros(); %to store mel frequencies to calculate mel frequency filter bank
LinearArray(no_of_coeffs+2,1)=zeros(); %to store linear frequencies to calculate mel frequency filter bank
FreqArray(no_of_coeffs+2,1)=zeros(); %to store frequency array to calculate mel frequency filter bank
%{
THIS ARRAY MAY HAVE WRONG VALUES DUE TO SELECTION of WRONG PARAMETERS LIKE low_freq, high_freq, frame_length (frame-size), no_of_coeffs (no. of filter banks). THIS IS MAJOR REASON BEHIND GENERATION OF NaN values in HMatrix
%}
HMatrix(no_of_coeffs,frame_length)=zeros(); %Hmk Matrix/ Filter Bank
%I'M VERY DOUBTFUL OF THE
%VALUES GENERATED BY THIS
%FILTER BANK
MelArray(1)=low_linear;
MelArray(no_of_coeffs+2)=high_linear;
LinearArray(1)=low_freq;
LinearArray(no_of_coeffs+2)=high_freq;
FreqArray(1)=floor((int32(frame_length)+1)*LinearArray(1)/fs);
FreqArray(no_of_coeffs+2)=floor((int32(frame_length)+1)*LinearArray(no_of_coeffs+2)/fs);
for m=1:no_of_coeffs
MelArray(m+1)=MelArray(m)+band_length;
LinearArray(m+1)=700*((power( 10,MelArray(m+1)/2595))-1);
FreqArray(m+1)=floor((int32(frame_length)+1)*LinearArray(m+1)/fs);
end
% THE MOST DOUBTFUL PART i.e. MEL FREQUENCY FILTER BANK MATRIX CREATION
%---------------------------------------------------------PROBABLE ERRONEOUS PART------------------------------------------------------------%
% I'M GETTING NaN values in this matrix probably due to choosing
% incorrect parameters for like upper freq, lower freq, frame-size, no.of filter banks, sampling frequency etc.
for k=1:frame_length
for m=1:no_of_coeffs
if(k<FreqArray(m))
HMatrix(m,k)=0;
elseif (FreqArray(m)<=k && k<=FreqArray(m+1))
HMatrix(m,k)=(k-FreqArray(m))/(FreqArray(m+1)-FreqArray(m));
elseif(FreqArray(m+1)<=k && k<=FreqArray(m+2))
HMatrix(m,k)=(FreqArray(m+2)-k)/(FreqArray(m+2)-FreqArray(m+1));
elseif (k>FreqArray(m+2))
HMatrix(m,k)=0;
end
end
end
%--------------------------------------------------------------------------------------------------------------------------------------------%
SM(no_of_frames,frame_length)=zeros();
FVector(no_of_frames,no_of_coeffs,numOfWords*numSamplesOfEachWord)=zeros();
LogFiltered(no_of_frames,no_of_coeffs)=zeros();
FinalResult(no_of_frames,no_of_coeffs)=zeros();
WindowValues=hamming(frame_length);
wordArray= {'begin\', 'continue\', 'exit\', 'move\', 'save\', 'undo\'};
% //NOT USING THESE REMAINING WORDS NOW : 'a\', 'b\', 'c\', 'd\', 'one\', 'two\', 'three\', 'four\', 'move\a1\', 'move\a2\', 'move\a3\', 'move\a4\'};
%{
//NOT USING THIS NOW
filenaming = 'C:\Users\Ray\Documents\BE Project\Phase-III\Normalising.mat';
m = matfile(filenaming);
Nrm=m.Nrm;
%}
%------------------------------------------------------------------TRAINING--------------------------------------------------------------------%
for i=1:numOfWords
for j=1:numSamplesOfEachWord
%----------------------------------------------------------READING WORD SAMPLE---------------------------------------------------%
SD=wavread(strcat(path_start,wordArray{i},num2str(j),path_end));
%SD=Nrm(j+(i-1)*numSamplesOfEachWord,:); //NOT USING THIS NOW
%SD=NoiseFilter(SD); % //NOT USING THIS NOW
%----------------------------------------------------PRE-EMPHASIS FILTER-------------------------------------------------------%
SD=filter([1 -alpha], 1, SD);
%------------------------------------------------------------PADDING-----------------------------------------------------------%
SD=pad(SD,pad_length); % function given at the end of this file
%-------------------------------------------------------FRAMING AND WINDOWING-------------------------------------------------------%
%----------------------------------------------------AND CALCULATING FFT OF OBATINED SAMPLES--------------------------------------------%
SD=reshape(SD,no_of_frames,frame_length/2);
for k=1:no_of_frames-1
temp=fft(([SD(k,:) SD(k+1,:)]'.*WindowValues)');
SM(k,:)=temp.*(conj(temp));
end
temp=fft(([SD(no_of_frames,:) zeros(1,frame_length/2)]'.*WindowValues)');
SM(no_of_frames,:)=temp.*(conj(temp));
%-------------------------------------------------APPLYING MEL - FILTER BANK AND LOG FILTERING--------------------------------------------%
for h=1:no_of_frames
for l=1:no_of_coeffs
LogFiltered(h,l) = log10(sum(SM(h,:).*HMatrix(l,:)));
end
end
%----------------------------------------------------------APPLYING DCT---------------------------------------------------------%
for indexing=1:no_of_frames
FinalResult(indexing,:)=dct(LogFiltered(indexing,:));
end
%---------------------------------------------------STORING TRAINING DATASET---------------------------------------------------%
FVector(1:no_of_frames,1:no_of_coeffs,j+(i-1)*numSamplesOfEachWord)=FinalResult;
end
end
save('SevenStep'); %Saving all variables to retrieve during running the program for SR
toc
end
function p=pad(x,full_length)
p = vertcat(x, zeros(full_length - length(x),1));
end
%{
NOT USING THIS NOW, BUT IF YOU CAN SUGGEST CHANGES IN THIS IT WOULD
APPRECIABLE
function Y=NoiseFilter(SD)
[B, A]= butter(2,0.01); % IS THIS CORRECT FOR MY SAMPLES?
X= filter(B, A, SD);
%figure; plot(SD);
X(abs(X)< 0.01) = 0;
%figure; plot(X);
%X=X(find(X,1,'first'):find(X,1,'last'));
Y=SD(find(X,1,'first'):find(X,1,'last')); % TAKING FROM ORIGINAL SAMPLE
%figure; plot(Y);
end
%}
函数SevenStep()
抽搐
%-----------------------------------------------------------------初始化-------------------------------------------------------------------%
路径\u start='C:\Users\Ray\Documents\BE Project\Phase III\FreshAudioSamples\';
路径_end='.wav';
α=0.97;
fs=44100;%我对记录的样本进行采样的频率
焊盘长度=120064;
numSamplesOfEachWord=30;%在样本数据库中
numOfWords=6;
帧长度=256;%如何选择合适的框架尺寸?
无帧数=焊盘长度/(int32(帧长度/2));%因为重叠是50%
低频率=300;%用于计算mel频率滤波器组的较低频率(我无法选择正确的滤波器组,并且无法找到选择它的标准)
高频=8000;%mel频率滤波器组计算的上限频率(我无法选择正确的频率,并找到选择它的标准)
无系数=20;%这是要创建的Mel过滤器组的数量。如何为此选择合适的值?
%{
fnm='C:\Users\Ray\Documents\BE Project\Phase III\trifbank.mat';
m1=matfile(fnm);
H=m1.H;
//方法2,当我的Mel频率滤波器组
(如下所示)可能无法正常工作
%}
%--------------------------------------------------MEL过滤器组创建的预处理-----------------------------------------%
低_线性=2595*log10(1+(低_频率/700));
高_线性=2595*log10(1+(高频/700));
频带长度=(高线性-低线性)/(无系数+1);
MelArray(无系数+2,1)=零();%存储mel频率以计算mel频率滤波器组
Linearray(无系数+2,1)=零();%存储线性频率以计算mel频率滤波器组
FreqArray(无系数+2,1)=零();%存储频率数组以计算mel频率滤波器组
%{
由于选择了错误的参数,例如low_freq、high_freq、frame_length(帧大小)、no_of_Coefs(滤波器组的数量),此数组可能具有错误的值。这是在HMatrix中生成NaN值的主要原因
%}
HMatrix(无系数,帧长度)=零();%Hmk矩阵/滤波器组
%我很怀疑这一点
%由此生成的值
%滤波器组
MelArray(1)=低_线性;
MELARY(无系数+2)=高线性;
线性阵列(1)=低频;
线性阵列(无系数+2)=高频;
FreqArray(1)=地板((int32(帧长度)+1)*线性阵列(1)/fs);
FreqArray(无系数+2)=地板((int32(帧长)+1)*线性阵列(无系数+2)/fs);
对于m=1:无系数
MELARY(m+1)=MELARY(m)+频带长度;
线性阵列(m+1)=700*((功率(10,矩阵(m+1)/2595))-1);
频率阵列(m+1)=地板((int32(帧长度)+1)*线性阵列(m+1)/fs);
结束
%最值得怀疑的部分,即MEL频率滤波器组矩阵的创建
%---------------------------------------------------------可能的错误部分---------------------------------------------------%
%我在这个矩阵中得到NaN值可能是因为选择了
%高频、低频、帧大小、滤波器组数量、采样频率等参数不正确。
对于k=1:帧长度
对于m=1:无系数
如果(k)这对于一个问题来说是宽泛的。你会问“建议我所犯的错误”。您是指输出不符合预期吗?它与您想要的有何区别?所有必要的代码都应该包含在问题中,而不是外部链接中。如果代码对于单个问题来说太多,您应该尝试缩小问题的焦点。是的,我指的是输出不符合演讲中的预期识别。单词被错误地识别。错误结果背后的主要原因是代码中HMatrix的错误计算。它生成了一个NaN值。原因也可能是错误地生成了频率数组。我添加了一个外部链接,因为有.mat文件,可能会有很多错误。因此,很容易如果读卡器可以访问.mat文件和变量,请理解。
function [StrVal1] =SevenStepTestSample(filename)
tic
alpha=0.97;
KVal=13; %The no. of values used for final comparison
pad_length=120064;
numSamplesOfEachWord=10;
numOfWords=6;
frame_length=256; %How to choose an appropriate frame-size?
no_of_frames=pad_length/(frame_length/2); %since overlap is 50%
no_of_coeffs=20; % This is no. of Mel-Filter banks to create. how to choose a approriate value for this?
wordArrayPrint= {'begin', 'continue', 'exit', 'move', 'save', 'undo'};
% NOT USING THE REMAINING WORDS FOR NOW :'a', 'b', 'c', 'd', 'one', 'two', 'three', 'four', 'a1', 'a2', 'a3', 'a4'};
filenm = 'C:\Users\Ray\Documents\BE Project\Phase-III\SevenStep.mat'; % This is the storage space of training set data
m = matfile(filenm);
FVector=m.FVector;
HMatrix=m.HMatrix;
WindowValues=m.WindowValues;
TSM(no_of_frames,frame_length)=zeros();
TLogFiltered(no_of_frames,no_of_coeffs)=zeros();
TFinalResult(no_of_frames,no_of_coeffs)=zeros();
[testSample,t1] = wavread(filename);
%{
WAS USING THIS FOR NORMALISATION OF VOICE SAMPLES, NOT USING IT NOW
tt=max(abs(testSample));
for j=1:length(testSample)
RD(j)=(testSample(j)/tt);
end
testSample=RD;
%}
% NOT USING THIS NOW : testSample=NoiseFilter(testSample);
testSample=filter([1 -alpha],1,testSample');
testSample = vertcat(testSample', zeros(pad_length - length(testSample),1));
testSample=reshape(testSample,no_of_frames,frame_length/2);
for k=1:no_of_frames-1
temp=fft(([testSample(k,:) testSample(k+1,:)]'.*WindowValues)');
TSM(k,:)=temp.*(conj(temp));
end
temp=fft(([testSample(no_of_frames,:) zeros(1,frame_length/2)]'.*WindowValues)');
TSM(no_of_frames,:)=temp.*(conj(temp));
for h=1:no_of_frames
for l=1:no_of_coeffs
TLogFiltered(h,l) = log10(sum(TSM(h,:).*HMatrix(l,:)));
end
end
for indexing=1:no_of_frames
TFinalResult(indexing,:)=dct(TLogFiltered(indexing,:));
end
errorArray = zeros(numOfWords*numSamplesOfEachWord,1);
for j=1:numOfWords*numSamplesOfEachWord
errorArray(j)= mean2(abs(TFinalResult(1:no_of_frames,2:KVal) - FVector(1:no_of_frames,2:KVal,j)));
end
%errorArray'
[err, index1] = min(errorArray);
%{
NOT USING THIS NOW: THIS CODE IS TO CALCULATE SECOND MINIMUM ASSUMING
THE FACT THAT NO TWO SAMPLES WILL GIVE SAME ERROR VALUE
[err,index2] = min(errorArray(errorArray>min(errorArray)));
if(index1<=index2)
index2=index2+1;
end
%}
for j=1:numOfWords
if (index1 >= (1+(j-1)*numSamplesOfEachWord) && index1 <= j*numSamplesOfEachWord)
StrVal1=upper(wordArrayPrint{j});
disp(StrVal1);
end
%{
if (index2 >= (1+(j-1)*numSamplesOfEachWord) && index2 <= j*numSamplesOfEachWord)
StrVal2=upper(wordArrayPrint{j});
end
%}
end
%fprintf('%s\t%s\n',StrVal1,StrVal2);
% save('SevenStepTestSample');
toc
end