Code covered by the BSD License  

Highlights from
AMDF

image thumbnail

AMDF

by

 

29 Jan 2014 (Updated )

This exercise computes the short-time average magnitude difference function (AMDF) of a speech frame

Callbacks_amdf_GUI25(f,C,start_path)
function Callbacks_amdf_GUI25(f,C,start_path)
%SENSE COMPUTER AND SET FILE DELIMITER
switch(computer)				
    case 'MACI64',		char= '/';
    case 'GLNX86',  char='/';
    case 'PCWIN',	char= '\';
    case 'PCWIN64', char='\';
    case 'GLNXA64', char='/';
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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','--');
case 2
graphicPanel2 = 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);
case 13
button13=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',@button13Callback);
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%USER CODE FOR THE VARIABLES AND CALLBACKS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Initialize Variables
    clear ss;
    curr_file=1;
    fs=1;
    directory_name='abcd';
    wav_file_names='abce';
    fin_path='filename';
    file_info_string=' ';
    fname='output';
    nsamp=1;
    fwrite='out_amdf';
    ss=2000;
    Lm=40;
    L=400;
    R=100;
    Rm=10;
    imf=1;
    pdlow=5.0;
    pdhigh=12.5;
    pdhighm=12.5;
    pdlowm=5.0;
    xs=1;
    amdf=1;
    amdfmin=1;
    minvalue=0;
    M=100;
    amdfthresh=0.6;

% Name the GUI
    set(f,'Name','amdf_GUI');

% CALLBACKS
% Callback for button1 -- Get Speech Files Directory
 function button1Callback(h,eventdata)
     directory_name=uigetdir(start_path,'dialog_title');
     A=strvcat(strcat((directory_name),[char,'*.wav']));
     struct_filenames=dir(A);
     wav_file_names={struct_filenames.name};
     set(button2,'String',wav_file_names);
     
% once the popupmenu/drop down menu is created, by default, the first
% selection from the popupmenu/drop down menu id not called
    indexOfDrpDwnMenu=1;
    
% by default first option from the popupmenu/dropdown menu will be loaded
    [curr_file,fs]=loadSelection(directory_name,wav_file_names,indexOfDrpDwnMenu);
 end

% Callback for button2 -- Choose speech file for play and plot
 function button2Callback(h,eventdata)
     indexOfDrpDwnMenu=get(button2,'val');
     [curr_file,fs]=loadSelection(directory_name,wav_file_names,indexOfDrpDwnMenu);
 end

%*************************************************************************
% function -- load selection from designated directory and file
%
function [curr_file,fs]=loadSelection(directory_name,wav_file_names,...
    indexOfDrpDwnMenu);
%
% read in speech/audio file
% fin_path is the complete path of the .wav file that is selected
    fin_path=strcat(directory_name,char,strvcat(wav_file_names(indexOfDrpDwnMenu)));
    
% clear speech/audio file
    clear curr_file;
    
% read in speech/audio signal into curr_file; sampling rate is fs 
    [curr_file,fs]=wavread(fin_path);
    
% create title information with file, sampling rate, number of samples
    fname=wav_file_names(indexOfDrpDwnMenu);
    FS=num2str(fs);
    nsamp=num2str(length(curr_file));
    file_info_string=strcat('  file: ',fname,', fs: ',FS,' Hz, nsamp:',nsamp);
    
% read in filename (fname) from cell array
    fname=wav_file_names{indexOfDrpDwnMenu};
    
% correct filename for underbar characters
    fname(find(fname(:)=='_'))=' ';
end

% Callback for button3 -- ss: starting sample for single frame display
 function button3Callback(h,eventdata)
     ss=1; % str2num(get(button3,'string'));
     if (ss < 1 || ss > length(curr_file)-Lm*(fs/1000))
        waitfor(errordlg('ss must be between 1 and length of file'));
     end
 end

% Callback for button10 -- play speech file
 function button10Callback(h,eventdata)
     soundsc(curr_file,fs);
 end

% Callback for button4 -- Lm: frame duration in msec
 function button4Callback(h,eventdata)
     Lm=str2num(get(button4,'string'));
     if ~((Lm >= 1 && Lm <=100))
         waitfor(errordlg('Lm must be a positive numbser between 1 and 100'))
     end
 end

% Callback for button5 -- Rm: frame shift in msec
 function button5Callback(h,eventdata)
     Rm=str2num(get(button5,'string'));
     if ~((Rm >= 1 && Rm <=100))
         waitfor(errordlg('Rm must be a positive number between 1 and 100'))
     end
 end

% Callback for button6 -- imf: male/female switch; imf=1:male, imf=2:female
 function button6Callback(h,eventdata)
     imf=get(button6,'val');
 end

% Callback for button11 -- amdfthresh
 function button11Callback(h,eventdata)
     amdfthresh=str2num(get(button11,'string'));
     if ~((amdfthresh >= 0 && amdfthresh <= 1))
         waitfor(errordlg('amdfthresh must be a positive number between 0 and 1.0'))
     end
 end

% Callback for button7 -- select frame starting sample
 function button7Callback(h,eventdata)
     
% callbacks to buttons 2-6 for up-to-date data
    button2Callback(h,eventdata);
    ss=1; 
    Lm=str2num(get(button4,'string'));
    Rm=str2num(get(button5,'string'));
    imf=get(button6,'val');
    if (imf == 1)  % male range of pitch periods (msec)
        pdlowm=5.0; 
        pdhighm=12.5;
    elseif (imf == 2)  % female range of pitch periods (msec)
        pdlowm=2.9; 
        pdhighm=6.7;
    end
    
% plot entire range of speech and use graphics cursors to home in on
% selected starting sample; use graphics Panel 2 for interactive display
    ss=plot_speech_cursor(curr_file,1,1,graphicPanel2,fs);
    set(button3,'string',num2str(ss));
 end

% callback to button12 -- use current frame
    function button12Callback(h,eventdata)
        
% check for updates to parameters for amdf calculation
    button6Callback(h,eventdata)
    button11Callback(h,eventdata)
    
% use ss from value stored in button12
        ss=str2num(get(button3,'string'));
  
% fwrite=output text file with results of amdf analysis
    fclose('all');
    fwrite='out_amdf';
    fid=fopen(fwrite,'w');
    
% save filename information in output file
    fprintf(fid,'fname: %s, sampling rate: %d \n',fname,fs);
    
% amdf single frame
    Lm=str2num(get(button4,'string'));
    Rm=str2num(get(button5,'string'));
    
    [L,R,pdlow,pdhigh,xs,amdf,amdfmin,minvalue]=...
        amdf_frame(curr_file,fs,ss,Lm,Rm,pdlowm,pdhighm,fid);
    
% plotting pointer
	xv=[minvalue-1 minvalue-1];
	yv=[0 1];
        
% clear graphics Panel 2
    reset(graphicPanel2);
    axes(graphicPanel2);
    cla;
    
% plot frame of speech to graphics Panel 2
	n1=ss:ss+L-1;
	n2=ss:ss+L+pdhigh-1;
	plot(n1,xs(1:L),'r','LineWidth',2),hold on;
	plot(n2,xs(1:L+pdhigh),'b:','LineWidth',2),axis tight,grid on;
    xlab=['Sample Index; fs=',num2str(fs),' samples/second'];
	xlabel(xlab),ylabel('Amplitude'); legend('current speech frame','expanded speech frame');
    
% global pitch period estimation parameters to titleBox1 for pitch detector
	s1=sprintf('AMDF -- file: %s, ss: %d, frleng: %d,',fname,ss,L);
	s2=sprintf(' frshft: %d, minlag: %d, maxlag: %d',R,pdlow,pdhigh);
	stitle=strcat(s1,s2);
    set(titleBox1,'String',stitle);
    set(titleBox1,'FontSize',15);
    
% clear graphics Panel 1
    reset(graphicPanel1);
    axes(graphicPanel1);
    cla;
    
% plot amdf function for current frame to graphics Panel 1; show value for
% minimum amdf in allowed pitch period range
	plot(0:pdhigh-1,amdf,'b','LineWidth',2);
    xx=[0 pdhigh-1];  yy=[amdfthresh amdfthresh];
	hold on, plot(xx,yy,'r-','Linewidth',2); plot(xv,yv,'r','LineWidth',2);
	plot([pdlow pdlow],[0 1],'k:','LineWidth',2);
    xlab=['Lag in Samples; fs=',num2str(fs),' samples/second'];
	axis tight,grid on,xlabel(xlab),ylabel('AMDF Value');
	hold off;legend('amdf for current frame');
    end

% callback to button13 -- use next frame
    function button13Callback(h,eventdata)
    
% update starting sample
    ss=ss+R;
    set(button3,'string',num2str(ss));
    button12Callback(h,eventdata)
    end

% Callback for button8 -- run pitch detector
 function button8Callback(h,eventdata)
     
% play out speech file
    tsec=(0:length(curr_file)-1)/fs;

% callbacks to buttons 2-6 for up-to-date data
    button2Callback(h,eventdata);
    ss=1; % str2num(get(button3,'string'));
    Lm=str2num(get(button4,'string'));
    Rm=str2num(get(button5,'string'));
    imf=get(button6,'val');
    if (imf == 1)  % male range of pitch periods
        pdlow=5.0; 
        pdhigh=12.5;
    elseif (imf == 2)  % female range of pitch periods
        pdlow=2.9; 
        pdhigh=6.7;
    end

% fwrite=output text file with results of amdf analysis
    fclose('all');
    fwrite='out_amdf';
    fid=fopen(fwrite,'w');
    
% save filename information in output file
    fprintf(fid,'fname: %s, sampling rate: %d \n',fname,fs);
    
% amdf single frame
    [L,R,pdlow,pdhigh,period,amdfvals,ssv]=...
        amdf_pitch(curr_file,fs,ss,Lm,Rm,pdlow,pdhigh,fid,amdfthresh);
    
% print out amdf pitch detector parameters to titleBox1
	s1=sprintf('AMDF -- %s ',fname);
	s2=sprintf(' L: %d,R: %d, ',L,R);
	s3=sprintf(' minpd: %d, maxpd: %d',pdlow,pdhigh);
	stitle=strcat(s1,s2,s3);
    set(titleBox1,'String',stitle);
    set(titleBox1,'FontSize',15);
    
% plot pitch period contour on graphics Panel 2
    reset(graphicPanel2);
    axes(graphicPanel2);
    cla;  
	plot(ssv/fs,period,'b','LineWidth',2);
    tsec=['Time in Seconds; fs=',num2str(fs),' samples/second'];
    yl=['Pitch Period (samples at fs=',num2str(fs),' samples/second)'];
	axis tight, grid on, xlabel(tsec),ylabel(yl);
     
% plot amdf minimum value contour (confidence score contour) on graphics
% Panel 1
	reset(graphicPanel1);
    axes(graphicPanel1);
    cla;
	plot(ssv/fs,amdfvals,'g','LineWidth',2);hold on;
    xx=[ssv(1)/fs ssv(length(ssv))/fs];
    yy=[amdfthresh amdfthresh];
    plot(xx,yy,'r--','LineWidth',2);
	axis tight, grid on, xlabel(tsec),ylabel('AMDF Minimum Value');
    
% close up text file with pitch period estimates
    fclose(fid);
 end

% Callback for button9 -- close GUI
 function button9Callback(h,eventdata)
     fclose('all');
     close(gcf);
 end
end

Contact us