www.pudn.com > audioProcessingtoolbox.rar > ptrackfcn.m


function [rawpitch, pitch, framedY, aveEng] = ptrackfcn(y, fs, plotopt, pitchparam) 
 
% PTRACKFCN : Pitch Tracking Function 
%    Usage [rawpitch, pitch, framedY, aveEng] = ptrackfcn(y, fs, plotopt, pitchparam). 
%  
% Gavins 2001/10/15 
% Gavins 2002/9/17 refined. 
 
if nargin==0, selfdemo; return; end; 
if nargin<3, plotopt =1 ; end; 
if nargin<4,  
   pitchparam.frameSize = 320; 
   pitchparam.overlap = 0; 
   pitchparam.maxFreq = 600; 
   pitchparam.lowpassOrder = 5; 
   pitchparam.clipThred = 0.25; 
   pitchparam.maxThred = 0.1; 
   pitchparam.engthred = 0.2; 
end; 
 
% Shift mean to zero. 
y = y-mean(y); 
% Send to low-pass filter (Hamming window used by default) 
maxFreq = pitchparam.maxFreq; %Assumed that frequency of human's speech is most 1K Hz. 
b = fir1(pitchparam.lowpassOrder, maxFreq/(fs/2)); 
y = filter(b, 1, y); 
 
% Frame blocking then computing average energy and zero crossing rate. 
% Pitch tracking : center clipping, localmaxima, period extraction. 
frameSize = pitchparam.frameSize; 
overLap   = pitchparam.overlap; 
framedY   = buffer2mex(y, frameSize, overLap); %function buffer in Signal toolbox 
frameNum  = size(framedY,2); 
seqCRLen  = frameSize*2-1; 
sequenceCR= zeros(frameNum,seqCRLen); 
clipThred = pitchparam.clipThred; 
maxThred  = pitchparam.maxThred; 
engThred  = pitchparam.engthred; 
 
% Computing energy and using "min+(max-min)*0.2" rule to define threshold. 
aveEng = getaveEnergy(framedY,frameSize); 
%[a,b]  = sort(aveEng); 
%c = fliplr(b); 
%engThred = min(aveEng)+(mean(aveEng(c(1:round(length(c)*0.2)))) - min(aveEng)) *0.2; 
engThred = engThred*mean(aveEng)*0.1; 
 
rawpitch = zeros(frameNum,1); 
for i = 1 : frameNum, 
   sequenceCR(i,:) = atcorr(framedY(:,i)); 
   sequenceCR(i,:) = centclip(sequenceCR(i,:), clipThred); 
   sequenceCR(i,:) = localmax(sequenceCR(i,:), maxThred); 
   %Energy太小的音框不考慮求取pitch 
   if aveEng(i) > engThred ,  
      rawpitch(i) = freqExtract(sequenceCR(i,:), fs); 
   else 
      rawpitch(i) = 0; 
   end; 
end; 
pitch    = pitchTrim(rawpitch); 
semitone = frq2smtn(pitch); 
 
% ====== Plot pitch figure. 
if plotopt, 
   time = (1:frameNum)*(frameSize-overLap)/fs; 
    
   figure; 
   subplot(5,1,1);  
   plot((1:length(y))/fs, y);axis tight; 
   xlabel('time');ylabel('Amplitude'); 
   title(['(PCM Signal)']); 
   
   subplot(5,1,2); 
   plot(time, aveEng);axis tight; 
   xlabel('time');ylabel('Average Energy'); 
    
   subplot(5,1,3); 
   plot(time, rawpitch,'b-',time,rawpitch,'r*');axis tight; 
   xlabel('time');ylabel('Raw Pitch'); 
    
   subplot(5,1,4); 
   plot(time,pitch(1:length(time)),'b-',time,pitch(1:length(time)),'r*'); 
   axis([-inf inf 0 max(pitch)]); 
   xlabel('time');ylabel('Pitch refined'); 
    
   subplot(5,1,5); 
   plot(time,semitone(1:length(time)),'b-',time,semitone(1:length(time)),'r*'); 
   axis([-inf inf 0 max(semitone)]); 
   xlabel('time');ylabel('Pitch to Semitone'); 
end; 
 
function selfdemo 
filename = 'test.wav'; 
plotopt = 1 ; 
[y, fs] = wavread(filename); 
[pitch, semitone] = ptrackfcn(y, fs, plotopt); 
 
% ====================================================% 
%                   Sub function                      % 
% ====================================================% 
% Short term average energy 
function aveEng = getaveEnergy(matrix,vectorLen) 
%aveEng = log(sum(power(matrix,2))/vectorLen); 
aveEng = sum(power(matrix,2)); 
 
% Short term autocorrelation 
function sequenceCR = atcorr(vector) 
vectorLen  = length(vector); 
vectorCOPY = vector; %vector duplicate 
sequenceCR = zeros(1,vectorLen); 
for i = 1 : vectorLen, 
   sequenceCR(i) = sum(vector(i:vectorLen).*vectorCOPY(1:vectorLen-i+1)); 
end; 
sequenceCR = [fliplr(sequenceCR(2:end)) sequenceCR]; %Sequence must be symmetric 
 
% Short term center clipping 
function sequenceCR = centclip(vector,clipThred) 
vectorLen = length(vector); 
sequenceCR = zeros(1,vectorLen); 
clipvalue = max(abs(vector))*clipThred; 
temp = abs(vector)-clipvalue; 
index = find(temp>0); 
sequenceCR(index) = temp(index).*sign(vector(index)); 
 
% Short term localmaximum 
function sequenceCR = localmax(vector,maxThred) 
vectorLen = length(vector); 
sequenceCR = zeros(1,vectorLen); 
maxvalue = max(abs(vector))*maxThred; 
b = [vector 0]; 
c = [0 vector]; 
index1 = find([b - c]>0); 
index2 = find([b - c]<=0); 
b(index1) = 1; 
b(index2) = 0; 
maxIndex  = find(diff(b)<0); 
Index  = maxIndex(find(vector(maxIndex)>maxvalue)); 
sequenceCR(1,Index) = 1; 
 
% Short term frequency extraction 
function rawpitch = freqExtract(vector,fs) 
period = max(diff(find(vector~=0))); 
if isempty(period), rawpitch = 0; return; end; 
rawpitch = 1/(period/fs); 
 
% Pitch fine tuning(trimming) 
function trimedPitch = pitchTrim(rawpitch) 
temp = buffer(rawpitch, 5, 2); 
new  = median(temp,1); 
trimedPitch = reshape([new'*ones(1,3)]',length(new)*3,1); 
whichmin = min(length(trimedPitch), length(rawpitch)); 
trimedPitch = trimedPitch(1:whichmin);