Daniel@0: function [pitch,salience]=CorrelogramPitch(correlogram, width, sr, low, high); Daniel@0: % pitch=CorrelogramPitch(correlogram, width [, sr, lowPitch, highPitch]) Daniel@0: % computes the pitch of a correlogram sequence by finding the time lag Daniel@0: % with the largest correlation energy. Daniel@0: % Daniel@0: % (c) 1998 Interval Research Corporation Daniel@0: Daniel@0: if nargin < 3; sr=22254.54; end; Daniel@0: if nargin < 4; low=0; end; Daniel@0: if nargin < 5; high=inf; end; Daniel@0: Daniel@0: dropLow = floor(sr/high); Daniel@0: if low > 0 Daniel@0: dropHigh = min(width,ceil(sr/low)); Daniel@0: else Daniel@0: dropHigh = width; Daniel@0: end Daniel@0: Daniel@0: [pixels frames] = size(correlogram); Daniel@0: channels = pixels/width; Daniel@0: if channels < 1 | floor(channels) ~= channels Daniel@0: error('Correlogram Size Error'); Daniel@0: end Daniel@0: Daniel@0: pitch = zeros(1,frames); Daniel@0: salience = zeros(1,frames); Daniel@0: for j=1:frames Daniel@0: % Get one frame from the correlogram, reshape it, and compute Daniel@0: % the sum (as a function of time lag) across all channels. Daniel@0: if channels == 1 Daniel@0: summary=reshape(correlogram(:,j),channels,width); Daniel@0: else Daniel@0: summary=sum(reshape(correlogram(:,j),channels,width)); Daniel@0: end Daniel@0: zeroLag = summary(1); Daniel@0: % Now we need to find the first pitch past the peak at zero Daniel@0: % lag. The following lines smooth the summary pitch a bit, then Daniel@0: % look for the first point where the summary goes back up. Daniel@0: % Everything up to this point is zeroed out. Daniel@0: windowLength=16; Daniel@0: sumfilt=filter(ones(1,windowLength),[1],summary); Daniel@0: sumdif=sumfilt(2:width)-sumfilt(1:width-1); Daniel@0: sumdif(1:windowLength) = zeros(1,windowLength); Daniel@0: valleys=find(sumdif>0); Daniel@0: summary(1:valleys(1)) = zeros(1,valleys(1)); Daniel@0: summary(1:dropLow) = zeros(1,dropLow); Daniel@0: summary(dropHigh:width) = zeros(1,width-dropHigh+1); Daniel@0: plot(summary); Daniel@0: drawnow; Daniel@0: % Now find the location of the biggest peak and call this the pitch Daniel@0: [m p] = max(summary); Daniel@0: pitch(j) = sr/(p-1); Daniel@0: salience(j) = m/zeroLag; Daniel@0: end