DSPRelated.com
Code

Finding local maxima

Jeff T September 26, 20112 comments Coded in Matlab

The following code snippet is something that I put together for a school project some time ago.  In this project I was trying to apply some speech processing techniques to alter the pitch of a male speakers voice.  At the time I was searching for the formants and trying to move them manually in the frequency domain.

It became clear at the time that I would have to take each FFT frame and find the local maxima (all of them) and check their spacing.  Thus this function was born!  If you give it a 1-dimensional vector it will return both the indices in which each local maximum is found as well as it's amplitude.

I hope this code can find its way to other fun and exciting applications!

function [time,amp] = maxima(signal, thresh, len)
% Finds the local maximum values of the given signal.
% 
% Usage:  [IND,AMP] = MAXIMA(X, THRESH, N);
% 
%         X is the data 
%         THRESH is the threshold that signal must be greater
%            than in order to be counted. (Default = 0.0)
%         N is the number of points that need to be evaluated
%           (Defaults = LENGTH(X))
%         IND contains the indices of X that contain the maxima data
%         AMP contains the maxima amplitudes
%
% Author: sparafucile17 10/02/2003

if(exist('len') == 0)
    len = length(signal);
end
if(exist('thresh') == 0)
    thresh = 0.0;
end

%Initialize data
index = 1;
prev = signal(1);
local_time = 0;
local_amp = 0;
prev_slope = 1;  %allow a maxima point at the second sample

%prevent length error
if(len > length(signal))
   len = length(signal)
end

%Loop through data and find local maximums
for loop_i=2:len
   cur = signal(loop_i);
   slope = cur - prev;
   if((cur < prev) & (prev_slope > 0) & (cur > thresh))  %Positive slope and amplitude dips
      local_time(index) = loop_i-1;
      local_amp(index) = prev;
      index = index+1;
   end
   prev = cur;
   prev_slope = slope;
end

%After loop assign data to output variables
time = local_time;
amp = local_amp;