wolffd@0
|
1 function [pitch,salience]=CorrelogramPitch(correlogram, width, sr, low, high);
|
wolffd@0
|
2 % pitch=CorrelogramPitch(correlogram, width [, sr, lowPitch, highPitch])
|
wolffd@0
|
3 % computes the pitch of a correlogram sequence by finding the time lag
|
wolffd@0
|
4 % with the largest correlation energy.
|
wolffd@0
|
5 %
|
wolffd@0
|
6 % (c) 1998 Interval Research Corporation
|
wolffd@0
|
7
|
wolffd@0
|
8 if nargin < 3; sr=22254.54; end;
|
wolffd@0
|
9 if nargin < 4; low=0; end;
|
wolffd@0
|
10 if nargin < 5; high=inf; end;
|
wolffd@0
|
11
|
wolffd@0
|
12 dropLow = floor(sr/high);
|
wolffd@0
|
13 if low > 0
|
wolffd@0
|
14 dropHigh = min(width,ceil(sr/low));
|
wolffd@0
|
15 else
|
wolffd@0
|
16 dropHigh = width;
|
wolffd@0
|
17 end
|
wolffd@0
|
18
|
wolffd@0
|
19 [pixels frames] = size(correlogram);
|
wolffd@0
|
20 channels = pixels/width;
|
wolffd@0
|
21 if channels < 1 | floor(channels) ~= channels
|
wolffd@0
|
22 error('Correlogram Size Error');
|
wolffd@0
|
23 end
|
wolffd@0
|
24
|
wolffd@0
|
25 pitch = zeros(1,frames);
|
wolffd@0
|
26 salience = zeros(1,frames);
|
wolffd@0
|
27 for j=1:frames
|
wolffd@0
|
28 % Get one frame from the correlogram, reshape it, and compute
|
wolffd@0
|
29 % the sum (as a function of time lag) across all channels.
|
wolffd@0
|
30 if channels == 1
|
wolffd@0
|
31 summary=reshape(correlogram(:,j),channels,width);
|
wolffd@0
|
32 else
|
wolffd@0
|
33 summary=sum(reshape(correlogram(:,j),channels,width));
|
wolffd@0
|
34 end
|
wolffd@0
|
35 zeroLag = summary(1);
|
wolffd@0
|
36 % Now we need to find the first pitch past the peak at zero
|
wolffd@0
|
37 % lag. The following lines smooth the summary pitch a bit, then
|
wolffd@0
|
38 % look for the first point where the summary goes back up.
|
wolffd@0
|
39 % Everything up to this point is zeroed out.
|
wolffd@0
|
40 windowLength=16;
|
wolffd@0
|
41 sumfilt=filter(ones(1,windowLength),[1],summary);
|
wolffd@0
|
42 sumdif=sumfilt(2:width)-sumfilt(1:width-1);
|
wolffd@0
|
43 sumdif(1:windowLength) = zeros(1,windowLength);
|
wolffd@0
|
44 valleys=find(sumdif>0);
|
wolffd@0
|
45 summary(1:valleys(1)) = zeros(1,valleys(1));
|
wolffd@0
|
46 summary(1:dropLow) = zeros(1,dropLow);
|
wolffd@0
|
47 summary(dropHigh:width) = zeros(1,width-dropHigh+1);
|
wolffd@0
|
48 plot(summary);
|
wolffd@0
|
49 drawnow;
|
wolffd@0
|
50 % Now find the location of the biggest peak and call this the pitch
|
wolffd@0
|
51 [m p] = max(summary);
|
wolffd@0
|
52 pitch(j) = sr/(p-1);
|
wolffd@0
|
53 salience(j) = m/zeroLag;
|
wolffd@0
|
54 end
|