Code covered by the BSD License  

Highlights from
Log Harmonic Product Spectrum

image thumbnail

Log Harmonic Product Spectrum

by

 

30 Jan 2014 (Updated )

Plots a sequence of frames of both HPS and LHPS

Callbacks_log_harmonic_GUI25(f,C,start_path)
function Callbacks_log_harmonic_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','--');
case 3
graphicPanel3 = 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);
case 14
button14=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',@button14Callback);
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%USER CODE FOR THE VARIABLES AND CALLBACKS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Initialize Variables
    curr_file=1;
    fs=8000;
    directory_name='abcd';
    wav_file_names='abce';
    fin_path='filename';
    fname='output';
    nsamp=1;
    ss=8000;
    es=8800;
    istart=1;
    Lm=40;
    L=400;
    Rm=10;
    R=100;
    nframes=20;
    nlayers=5;
    nfft=10000;
    xin=[];
    y=[];
    addnoise=1;
    x=[];

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

% 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);
    xin=curr_file*32768;
    
% 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};
end

% Callback for button12 -- Play Speech File
    function button12Callback(h,eventdata)
        soundsc(curr_file,fs);
    end

 % Callback for button3 -- fs: sampling rate of signal processing
 function button3Callback(h,eventdata)
     set(button3,'string',num2str(fs));
 end

% Callback for button4 -- addnoise: add noise at 0 dB snr option; 1 for no
%    noise, 2 for add noise
 function button4Callback(h,eventdata)
     addnoise=get(button4,'val');
 end

% Callback for button5 -- ss: waterfall first frame starting sample
 function button5Callback(h,eventdata)
     ss=str2num(get(button5,'string'));
 end

% Callback for button6 -- nframes: number of frames to plot in waterfall
 function button6Callback(h,eventdata)
     nframes=str2num(get(button6,'string'));
     if (nframes < 1 || nframes > 30)
         waitfor(errordlg('The number of frames must be between 1 and 30'));
         return;
     end
 end

% Callback for button7 -- Lm: analysis frame length in samples
 function button7Callback(h,eventdata)
     Lm=str2num(get(button7,'string'));
      if (Lm < 1 || Lm > 100)
         waitfor(errordlg('The frame length must be between 1 and 100'));
         return;
     end
 end

% Callback for button8 -- Rm: analysis frame shift in samples
 function button8Callback(h,eventdata)
     Rm=str2num(get(button8,'string'));
     if (Rm < 1 || Rm > 100)
         waitfor(errordlg('The frame duration must be between 1 and 100'));
         return;
     end
 end

% Callback for button9 -- nlayers: number of layers of log harmonic
%    spectrum calculation
 function button9Callback(h,eventdata)
     nlayers=str2num(get(button9,'string'));
     if (nlayers < 1 || nlayers > 10)
         waitfor(errordlg('The number of layers must be between 1 and 10'));
         return;
     end
 end

% Callback for button10 -- get frame starting sample
 function button10Callback(h,eventdata)
     
% check editable buttons for changes
    button3Callback(h,eventdata); % fs -- processing rate
    button4Callback(h,eventdata); % no noise/noise option
    button5Callback(h,eventdata); % ss -- starting sample for waterfall plot
    button6Callback(h,eventdata); % nframes for waterfall plot
    button7Callback(h,eventdata); % Lm -- frame length in msec
    button8Callback(h,eventdata); % Rm -- frame shift in msec
    button9Callback(h,eventdata); % nlayers -- number of layers in calculation
    
% convert Lm and Rm from msec to samples at original rate
    L=round(Lm*fs/1000);
    R=round(Rm*fs/1000);
 
% initialize waveform location for analysis
    istart=1;
    ss=1;
    
% save speech file in x
    x=curr_file;
    
% plot entire speech waveform in graphics Panel 3; use graphical
% cursor to choose an expanded region of speech around chosen sample
    ss=plot_speech_cursor(x,ss,curr_file,istart,graphicPanel3);
    
% set button5 with value of ss
    set(button5,'string',num2str(ss));

% plot expanded region of speech waterfall in graphics Panel 3; 
    es=ss+(nframes-1)*R+L-1;
    reset(graphicPanel3);
    axis(graphicPanel3);
    cla;
    plot(ss:es,x(ss:es),'b','LineWidth',2);
    xpp=['Time in Samples; fs=',num2str(fs),' samples/second'];
    xlabel(xpp);ylabel('Amplitude');axis tight; grid on;
    
fprintf('fs:%d, ss:%d, fs:%d, addnoise:%d, nframes:%d \n',fs,ss,fs,addnoise,nframes);
fprintf('Lm:%d, Rm:%d, nlayers:%d, nfft:%d, fname:%s \n',Lm,Rm,nlayers,nfft,fname);
 end

% Callback for button13 -- Run Current Waterfall
    function button13Callback(h,eventdata)
        
% plot expanded region of speech waterfall in graphics Panel 3; 
    button3Callback(h,eventdata);  % fs: sampling rate of speech file
    button4Callback(h,eventdata);  % addnoise: add noise option
    button5Callback(h,eventdata);  % ss: waterfall plot starting sample
    button6Callback(h,eventdata);  % nframes: number of frames in waterfall
    button7Callback(h,eventdata);  % Lm: frame duration in msec
    L=round(Lm*fs/1000);
    button8Callback(h,eventdata);  % Rm: frame shift in msec
    R=round(Rm*fs/1000);
    button9Callback(h,eventdata);  % nlayers: number of waterfall layers
    
% calculate frame end using updated parameters
    es=ss+(nframes-1)*R+L-1;
    reset(graphicPanel3);
    axes(graphicPanel3);
    cla;
    plot(ss:es,x(ss:es),'b','LineWidth',2);
    xpp=['Time in Samples; fs=',num2str(fs),' samples/second'];
    xlabel(xpp);ylabel('Amplitude');axis tight; grid on;
    
% function to setup log harmonic plots 
    setup_log_harmonic_plots(xin,fs,ss,addnoise,nframes,Lm,Rm,...
        nlayers,nfft,fname);    
 end

%**********************************************************************
function setup_log_harmonic_plots(xin,fs,ss,addnoise,nframes,Lm,Rm,...
        nlayers,nfft,fname)
%
% set up signal processing for computing log harmonic plots
%
    clearvars y ye yf ys yfs x1 X1 loghp linhp;
    
% save speech in y
    y=xin;
    ly=length(y);
    
% convert Lm and Rm from msec to samples at processing rate
    L=round(Lm*fs/1000);
    R=round(Rm*fs/1000);

% design highpass filter for eliminating DC, hum
    n=300*fs/10000;
    fl1=40*fs/10000;
    fh1=80*fs/10000;
    bhp=hpf(n,fl1,fh1,fs,0);
    n=n+1;
    
% highpass filter the speech file and compensate for the linear phase delay
    ye=[y; zeros(1,n)'];
    yf=filter(bhp,1,ye);
    yf=yf((n-1)/2+1:ly+(n-1)/2);
    
% scale files
    ys=y/max(max(y),-min(y));
    yfs=yf/max(max(yf),-min(yf));
    
    sssav=ss;
    
% option to add noise at 0 dB SNR if addnoise = 2; otherwise skip step
% first calculate signal sigma value
    if (addnoise == 2)
        sigmas=sqrt(sum(ys.^2)/length(ys));
        noise=rand(length(ys),1)-0.5;
        sigman=sqrt(sum(noise.^2)/length(noise));
        fprintf('sigmas:%f, sigman: %f \n',sigmas,sigman);
        ys=ys+noise*sigmas/sigman;
        yfs=yfs+noise*sigmas/sigman;
    end
    
% set frequency range for plots
        frlow=0;
        frhigh=500;
    
for iplot=1:2
    if (iplot == 1)
% clear graphics Panel 1
        reset(graphicPanel1);
        axes(graphicPanel1);
        cla;
    else
% clear graphics Panel 2
        reset(graphicPanel2);
        axes(graphicPanel2);
        cla;
    end
    hold on;
    fa=0:fs/nfft:500;
    
% determine range to zero out
    indexlow=floor(frlow/fs*nfft)+1;
    indexhigh=floor(frhigh/fs*nfft)+1;
    
% label plot using title
    stitle=sprintf(' file:%s, ss:%d, es:%d, L: %d, R: %d, nfft:%d, nlayers:%d',...
        fname,ss,es,L,R,nfft,nlayers);
    
% loop for nframes worth of data
% initialize log harmonic product spectrum
    loghp=zeros(nfft/2,1);
    offset=0;
    for index=1:nframes
        x1=yfs(ss:ss+L-1);
        x1=x1/max(max(x1),-min(x1));
        x1=x1.*hamming(L);
        
% calculate log spectrum for current frame
        X1=20*log(abs(fft(x1,nfft)));
        loghp(1:nfft/2)=loghp(1:nfft/2)+X1(1:nfft/2);

 % sum up frequency scaled replicas of log spectrum
        iskip=2;
        while (iskip <= nlayers)
            indend=floor(nfft/(2*iskip))+1;
            loghp(1:indend)=loghp(1:indend)...
                +X1(1:iskip:(indend-1)*iskip+1);
            iskip=iskip+1;
        end
        
        linhp=exp(loghp/2);
        linhp=linhp/max(linhp(indexlow:indexhigh));
        
% plot log harmonic spectrum of frame on graphics Panel 1 or linear
% harmonic spectrum of frame on graphics Panel 2
        if (iplot == 1)
            plot(fa(indexlow+1:indexhigh-1),loghp(indexlow+1:indexhigh-1)+...
                offset,'k','LineWidth',2);
            loghmax=max(loghp(1:length(fa)));
            loghmin=min(loghp(1:length(fa)));
            offset=offset-loghmin+loghmax;
        else
            plot(fa(indexlow+1:indexhigh-1),linhp(indexlow+1:indexhigh-1)+...
                offset,'k','LineWidth',2);
            loghmax=max(exp(loghp(1:length(fa)))/2);
            loghmin=min(exp(loghp(1:length(fa)))/2);
            offset=offset+1.2;
        end;
        
% update ss and loop
        ss=ss+R;
        loghp=zeros(nfft/2,1);
    end
    ss=sssav;
    axis tight,xlabel('Frequency (Hz)');
    grid on;
    if (iplot == 1) title('log HPS');
    else title('HPS');
    end
end

% display filename info and signal processing parameters on titleBox1
    stitle1=strcat('HPS/log HPS Plots -- ',stitle);
    set(titleBox1,'string',stitle1);
    set(titleBox1,'FontSize',15);
end

% Callback for button14 -- Run Next Waterfall
    function button14Callback(h,eventdata)
        button3Callback(h,eventdata);  %  fs: speech sampling rate
        button5Callback(h,eventdata);  % ss: current waterfall starting sample
        button6Callback(h,eventdata);  % nframes: number of frames in waterfall
        button7Callback(h,eventdata);  % Lm: frame length in msec
        L=round(Lm*fs/10000);
        button8Callback(h,eventdata);  % Rm: frame shift in msec
        R=round(Rm*fs/1000);
    ss=ss+(nframes-1)*R;
    set(button5,'string',num2str(ss));
    es=ss+(nframes-1)*R+L-1;
    
    reset(graphicPanel3);
    axes(graphicPanel3);
    cla;
    plot(ss:es,x(ss:es),'b','LineWidth',2);
    xpp=['Time in Samples; fs=',num2str(fs),' samples/second'];
    xlabel(xpp);ylabel('Amplitude');axis tight; grid on;
    button13Callback(h,eventdata)
    end

% Callback for button11 -- close GUI
 function button11Callback(h,eventdata)
     close(gcf);
 end
end

Contact us