Code covered by the BSD License  

Highlights from
Isolated Digits Record

image thumbnail

Isolated Digits Record

by

 

14 Feb 2014 (Updated )

Implements a speaker trained, template-based, isolated digit recognizer

Callbacks_dtw_isolated_digits_GUI25(f,C)
function Callbacks_dtw_isolated_digits_GUI25(f,C)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
x=C{1,1};
y=C{1,2};
a=C{1,3};
b=C{1,4};
u=C{1,5};
v=C{1,6};
m=C{1,7};
n=C{1,8};
lengthbutton=C{1,9};
widthbutton=C{1,10};
enterType=C{1,11};
enterString=C{1,12};
enterLabel=C{1,13};
noPanels=C{1,14};
noGraphicPanels=C{1,15};
noButtons=C{1,16};
labelDist=C{1,17};%distance that the label is below the button
noTitles=C{1,18};
buttonTextSize=C{1,19};
labelTextSize=C{1,20};
textboxFont=C{1,21};
textboxString=C{1,22};
textboxWeight=C{1,23};
textboxAngle=C{1,24};
labelHeight=C{1,25};
fileName=C{1,26};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%PANELS
for j=0:noPanels-1
uipanel('Parent',f,...
'Units','Normalized',...
'Position',[x(1+4*j) y(1+4*j) x(2+4*j)-x(1+4*j) y(3+4*j)-y(2+4*j)]);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%GRAPHIC PANELS
for i=0:noGraphicPanels-1
switch (i+1)
case 1
graphicPanel1 = axes('parent',f,...
'Units','Normalized',...
'Position',[a(1+4*i) b(1+4*i) a(2+4*i)-a(1+4*i) b(3+4*i)-b(2+4*i)],...
'GridLineStyle','--');
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%TITLE BOXES
for k=0:noTitles-1
switch (k+1)
case 1
titleBox1 = uicontrol('parent',f,...
'Units','Normalized',...
'Position',[u(1+4*k) v(1+4*k) u(2+4*k)-u(1+4*k) v(3+4*k)-v(2+4*k)],...
'Style','text',...
'FontSize',textboxFont{k+1},...
'String',textboxString(k+1),...
'FontWeight',textboxWeight{k+1},...
'FontAngle',textboxAngle{k+1});
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%BUTTONS
for i=0:(noButtons-1)
enterColor='w';
if strcmp(enterType{i+1},'pushbutton')==1 ||strcmp(enterType{i+1},'text')==1
enterColor='default';
end
if (strcmp(enterLabel{1,(i+1)},'')==0 &&...
        strcmp(enterLabel{1,(i+1)},'...')==0) %i.e. there is a label
%creating a label for some buttons
uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i)-labelDist-labelHeight(i+1) ...
(m(2+2*i)-m(1+2*i)) labelHeight(i+1)],...
'Style','text',...
'String',enterLabel{i+1},...
'FontSize', labelTextSize(i+1),...
'HorizontalAlignment','center');
end
switch (i+1)
case 1
button1=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button1Callback);
case 2
button2=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button2Callback);
case 3
button3=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button3Callback);
case 4
button4=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button4Callback);
case 5
button5=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button5Callback);
case 6
button6=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button6Callback);
case 7
button7=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button7Callback);
case 8
button8=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button8Callback);
case 9
button9=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button9Callback);
case 10
button10=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button10Callback);
case 11
button11=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button11Callback);
case 12
button12=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button12Callback);
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%USER CODE FOR THE VARIABLES AND CALLBACKS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Initialize Variables
    fsout=8000;
    Lm=40;
    L=320;
    Rm=10;
    R=80;
    Lcep=12;
    ibest=-1;
    i2best=-1;
    dbest=-1;
    d2best=-2;
    indext=1;
    index_iter=1;

%set a name for the GUI
set(f,'Name','dtw_isolated_digits');

% Callback for button1 -- Lm: frame length in msec
 function button1Callback(h,eventdata)
     Lm=str2num(get(button1,'string'));
      if (Lm < 1 || Lm > 100)
         waitfor(errordlg('The frame length must be between 1 and 100'));
         return;
     end
     L=round(Lm*fsout/1000);
 end

% Callback for button2 -- Rm: frame shift in msec
 function button2Callback(h,eventdata)
     Rm=str2num(get(button2,'string'));
      if (Rm < 1 || Rm > 100)
         waitfor(errordlg('The frame shift must be between 1 and 100'));
         return;
     end
     R=round(Rm*fsout/1000);
 end

% Callback for button3 -- Lcep: number of cepstral coefficients in samples
 function button3Callback(h,eventdata)
     Lcep=str2num(get(button3,'string'));
 end

% Callback for button4 -- indext: Test Digit Index (1-11,Z,O)
 function button4Callback(h,eventdata)
     indext=str2num(get(button4,'string'));
 end

% Callback for button5 -- index_iter: Test Digit Iteration
 function button5Callback(h,eventdata)
     index_iter=str2num(get(button5,'string'));
 end

% Callback for button6 -- ibest: best matching digit index
 function button6Callback(h,eventdata)
     set(button6,'string',num2str(ibest));
 end

% Callback for button7 -- dbest: best matching digit score
 function button7Callback(h,eventdata)
     set(button7,'string',num2str(dbest));
 end

% Callback for button8 -- i2best: second best matching digit index
 function button8Callback(h,eventdata)
     set(button8,'string',num2str(i2best));
 end

% Callback for button9 -- d2best: second best matching digit score
 function button9Callback(h,eventdata)
     set(button9,'string',num2str(d2best));
 end

% Callback for button10 -- Close GUI
 function button10Callback(h,eventdata)
% savefigure('compare_pitch_period1','d',300,'s',[10 6],'po','-dpdf');
% save figure in file example.bmp in current directory
     currentDir=pwd;
     currDir=strcat(currentDir,'\example');
     print('-dbitmap',currDir);
     close(gcf);
 end

% Callback for button11 -- Run DTW
 function button11Callback(h,eventdata)
     button1Callback(h,eventdata);
     button2Callback(h,eventdata);
     button3Callback(h,eventdata);
     button4Callback(h,eventdata);
     button5Callback(h,eventdata);
     
% loop on digits as reference
    digits{1}='zero';digits{2}='one';digits{3}='two';digits{4}='three';
    digits{5}='four';digits{6}='five';digits{7}='six';digits{8}='seven';
    digits{9}='eight';digits{10}='nine';digits{11}='oh';
    color=['b-';'g-';'r-';'c-';'m-';'y-';'k-';'b:';'g:';'r:';'c:'];

% define test digit for dtw matching
    tdigit=indext;
    
% index_iter in range 1-5 => use training set iteration; index_iter in
% range 6-10 => use testing set iteration of index_iter-5; otherwise warn
% about index_iter being out of range
    if (index_iter <= 5)
        filetest=[digits{tdigit},'_endpt_',num2str(index_iter),'.wav'];
    elseif (index_iter > 5 && index_iter <= 10)
        indexs=index_iter-5;
        filetest=[digits{tdigit},'_endpt_test_',num2str(indexs),'.wav'];
    else
        uiwait(msgbox('Iteration index out of range -- re-enter'));
    end
    
% initialize dbest, ibest, d2best, i2best
    dbest=1.e5; d2best=1.e5; ibest=0; i2best=0;
    
% set training index, ir, arbitrarily to iteration 1; ir can be in range
% 1-5
    ir=1;    
    for idigit=1:11
        fileref=[digits{idigit},'_endpt_',num2str(ir),'.wav'];
    
% open and analyze reference file
    [sref,fs,nbits]=wavread(fileref);
    fileref(find(fileref(:)=='_'))=' ';
    if (fs ~= fsout)
        [sref]=srconv(sref,fs,fsout);
    end
    cref=cepst(sref,fs,L,R,Lcep);
    nref=length(cref);
    
% open and analyze test file
    [stest,fs,nbits]=wavread(filetest);
    if (fs ~= fsout)
        [stest]=srconv(stest,fs,fsout);
    end
    ctest=cepst(stest,fs,L,R,Lcep);
    ntest=length(ctest);
    
% compare test and reference patterns using simple dtw
    [distance,paths,distances]=dtw_backtrack_dist(cref,nref,ctest,ntest,Lcep);
    distances=distances/ntest;
    
% keep track of best and second best distances and digits
    if (distance < dbest)
        d2best=dbest;
        i2best=ibest;
        dbest=distance;
        ibest=idigit;
    elseif (distance > dbest & distance < d2best)
        d2best=distance;
        i2best=idigit;
    end
    
% plot distance along best path
    if (idigit == 1)
        
% clear graphics Panel 1
        reset(graphicPanel1);
        axes(graphicPanel1);
        cla;
    
% plot accumulated distance curves for each of the 11 reference digits in
% graphics Panel 1
        filetestp=filetest;
        filetestp(find(filetestp(:)=='_'))=' ';
        stitle=sprintf('test:%s, L:%d, R:%d, Lcep:%d \n',filetestp,L,R,Lcep);
        color1=color(1,1:2);
        plot(1:ntest,distances,color1,'LineWidth',2);
        xlabel('Frame Number');ylabel('Accumulated Distance');grid on;
        hold on;
    else
        color1=color(idigit,1:2);
        plot(1:ntest,distances,color1,'LineWidth',2);
    end

% update boxes with best and second best digits and distances
    % set(button6,'string',num2str(ibest));
    set(button7,'string',num2str(dbest));
    set(button8,'string',num2str(i2best));
    set(button9,'string',num2str(d2best));
    end
    axis tight;title(stitle);
    legend('zero','one','two','three','four','five','six','seven','eight','nine','oh','Location','NorthWest');
    
% display correct and best matching digit information in titleBox1
    stitle=sprintf('test digit:%s, recognized digit:%s, dbest:%6.2f, second best:%s, d2best:%6.2f',...
        digits{indext},digits{ibest},dbest,digits{i2best},d2best); 
    set(titleBox1,'String',stitle);
    set(titleBox1,'FontSize',18);
    
    set(button4,'string',digits{indext});
    set(button6,'string',digits{ibest});
    set(button8,'string',digits{i2best});
 end

% Callback for button12 -- Record Speech
 function button12Callback(h,eventdata)
     button1Callback(h,eventdata);
     button2Callback(h,eventdata);
     button3Callback(h,eventdata);
     button4Callback(h,eventdata);
     button5Callback(h,eventdata);
     
 % recording parameters fs, nsec,ch,N=fs*nsec
     fs=8000;
     nsec=2;
     ch=1;
     N=fs*nsec;
     
% Begin recording after hitting OK on msg box
    uiwait(msgbox('Ready to Record -- Hit OK to Begin','Record','modal'));
   
% recording code -- use audiorecorder
    recobj=audiorecorder(fs,16,1);
    recordblocking(recobj,nsec);
    y=getaudiodata(recobj);

    ymin=min(y);
    ymax=max(y);
    ym=max(ymax,-ymin);
    xin=y/ym*32767;
    
% highpass filter to eliminate dc offset and 60 Hz hum and play out results
    y=highpass_filter_signal_GUI(y,fs);
    soundsc(y,fs);
    
 % setup graphics Panel 1
    reset(graphicPanel1);axes(graphicPanel1);cla;
    
% normalize y to range -1 to +1 and save as yn
    ynmax=max(abs(y));
    yn=y/ynmax;
    xpp=['Time in Samples; fs=',num2str(fs),' samples/second'];
    plot(0:length(yn)-1,yn,'k');xlabel(xpp);
    ylabel('Value');grid on;
    
% select starting and ending points of speech file using graphics cursors
    [X,Y]=ginput(2);
    ysav=y(round(X(1)):round(X(2)));
    clear y;
    y=ysav;

% loop on digits as reference
    digits{1}='zero';digits{2}='one';digits{3}='two';digits{4}='three';
    digits{5}='four';digits{6}='five';digits{7}='six';digits{8}='seven';
    digits{9}='eight';digits{10}='nine';digits{11}='oh';
    color=['b-';'g-';'r-';'c-';'m-';'y-';'k-';'b:';'g:';'r:';'c:'];

% define test digit for dtw matching
    tdigit=indext;
    
% initialize dbest, ibest, d2best, i2best
    dbest=1.e5; d2best=1.e5; ibest=0; i2best=0;
    for idigit=1:11
        for ir=index_iter:index_iter;
        fileref=[digits{idigit},'_endpt_',num2str(ir),'.wav'];
    
% open and analyze reference file
    [sref,fs,nbits]=wavread(fileref);
    fileref(find(fileref(:)=='_'))=' ';
    if (fs ~= fsout)
        [sref]=srconv(sref,fs,fsout);
    end
    cref=cepst(sref,fs,L,R,Lcep);
    nref=length(cref);
    
% open and analyze test file
    stest=y';
    ctest=cepst(stest,fs,L,R,Lcep);
    ntest=length(ctest);
    
% compare test and reference patterns using simple dtw
    [distance,paths,distances]=dtw_backtrack_dist(cref,nref,ctest,ntest,Lcep);
    distances=distances/ntest;
    
% keep track of best and second best distances and digits
    if (distance < dbest)
        d2best=dbest;
        i2best=ibest;
        dbest=distance;
        ibest=idigit;
    elseif (distance > dbest & distance < d2best)
        d2best=distance;
        i2best=idigit;
    end
    
% plot distance along best path
    if (idigit == 1)
        
% clear graphics Panel 1
        reset(graphicPanel1);
        axes(graphicPanel1);
        cla;
    
% plot accumulated distance curves for each of the 11 reference digits in
% graphics Panel 1
        filetest='run';
        filetestp=filetest;
        filetestp(find(filetestp(:)=='_'))=' ';
        stitle=sprintf('test:%s, L:%d, R:%d, Lcep:%d \n',filetestp,L,R,Lcep);
        color1=color(1,1:2);
        plot(1:ntest,distances,color1,'LineWidth',2);
        xlabel('Frame Number');ylabel('Accumulated Distance');grid on;
        hold on;
    else
        color1=color(idigit,1:2);
        plot(1:ntest,distances,color1,'LineWidth',2);
    end
        end

% update boxes with best and second best digits and distances
    set(button6,'string',num2str(ibest));
    set(button7,'string',num2str(dbest));
    set(button8,'string',num2str(i2best));
    set(button9,'string',num2str(d2best));
    end
    axis tight;title(stitle);
    legend('zero','one','two','three','four','five','six','seven','eight','nine','oh','Location','NorthWest');
    
% display correct and best matching digit information in titleBox1
    stitle=sprintf('test digit:%s, recognized digit:%s, dbest:%6.2f, second best:%s, d2best:%6.2f',...
        digits{indext},digits{ibest},dbest,digits{i2best},d2best); 
    set(titleBox1,'String',stitle);
    set(titleBox1,'FontSize',18);
    
    set(button4,'string',digits{indext});
    set(button6,'string',digits{ibest});
    set(button8,'string',digits{i2best});
 end
end

Contact us