diff aim-mat/modules/usermodule/pitchstrength/IPeakPicker.m @ 4:537f939baef0 tip

various bug fixes and changed copyright message
author Stefan Bleeck <bleeck@gmail.com>
date Tue, 16 Aug 2011 14:37:17 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/aim-mat/modules/usermodule/pitchstrength/IPeakPicker.m	Tue Aug 16 14:37:17 2011 +0100
@@ -0,0 +1,145 @@
+% function out = PeakPicker(sig_in, params)
+%
+%   Find the peaks of a signal and their neighbours
+%
+%   INPUT VALUES:
+%       sig_in                  Input signal
+%         threshold     dynamic threshold. Off if not used
+%                               
+%
+%   RETURN VALUE:
+%       out is an array of a struct
+%       out.x                    x position of the Peak
+%       out.t                    according time value
+%		out.y                    y value of the peak
+%       out.left.[x,t,y]         left Minumum
+%       out.right.[x,t,y]        right Minumum
+% 
+% (c) 2011, University of Southampton
+% Maintained by Stefan Bleeck (bleeck@gmail.com)
+% download of current version is on the soundsoftware site: 
+% http://code.soundsoftware.ac.uk/projects/aimmat
+% documentation and everything is on http://www.acousticscale.org
+
+function out = PeakPicker(sig_in,threshold)
+% threshold is the percentage of the maximum value of the signal,
+% under which a peak is not counted
+
+if nargin <2
+	threshold=0;
+end
+
+plot_switch = 0;
+
+% the original values befor filtering
+orig_values = getdata(sig_in)';
+values=getdata(sig_in)';
+
+% ------------------- Find the local maxima ------------------------------
+% find x positions of ALL local maxima, incl. zero!!
+max_x = find((values >= [0 values(1:end-1)]) & (values > [values(2:end) 0]));
+max_y = orig_values(max_x);
+orig_max_y = orig_values(max_x);
+
+% ------------------- Find the local minima -----------------------------
+min_x = find((values < [inf values(1:end-1)]) & (values <= [values(2:end) inf]));
+min_y = values(min_x);
+
+
+peakpos_x=[];
+for i=1:length(max_x),
+    % only take the highest peak 
+    my = [max_y==max(max_y)];  % find the highest peak
+%     peakpos_x(i) = max_x(my);   % x pos of highest peak
+    peakpos_x = [peakpos_x max_x(my)]; 
+    max_y = max_y([max_y<max(max_y)]);   % del max value in y domain
+    max_x = max_x([max_x ~= peakpos_x(end)]); % and in x domain
+end
+peakpos_y = orig_values(peakpos_x);  % extract the y vector 
+
+% maxima = cell(1, length(peakpos_x));
+maxima = [];
+
+if plot_switch
+	figure(123);
+	clf
+	plot(sig_in,'k');
+	hold on;
+end
+
+threshold_val=threshold*max(sig_in);
+counter=1;
+
+% find the left end right minima that belong to a maximum
+for i=1:length(peakpos_x)
+	y_val= orig_values(peakpos_x(i));
+	
+	if y_val< threshold_val
+		continue
+	end
+
+	maxima{counter}.y =y_val;
+	maxima{counter}.x = peakpos_x(i);
+	maxima{counter}.t = bin2time(sig_in, maxima{i}.x);
+	maxima{counter}.fre = 1/maxima{counter}.t;
+	
+	if plot_switch
+		plot(maxima{counter}.x,maxima{counter}.y,'go');
+	end    
+	% find left and right minimum for this maximum
+	maxima{counter}.left.x = max(min_x([min_x < maxima{counter}.x]));
+	if isempty(maxima{counter}.left.x)
+		maxima{counter}.left.x = 1;
+		maxima{counter}.left.t = 0;
+		maxima{counter}.left.y = orig_values(maxima{counter}.left.x);
+	else
+		maxima{counter}.left.y = orig_values(maxima{counter}.left.x);
+		maxima{counter}.left.t = bin2time(sig_in, maxima{counter}.left.x);
+	end
+	maxima{counter}.right.x = min(min_x([min_x > maxima{counter}.x]));
+	if isempty(maxima{counter}.right.x)
+		maxima{counter}.right.x = length(orig_values);
+		maxima{counter}.right.t = 0;
+		maxima{counter}.right.y = orig_values(maxima{counter}.right.x);
+	else
+		maxima{counter}.right.y = orig_values(maxima{counter}.right.x);
+		maxima{counter}.right.t = bin2time(sig_in, maxima{counter}.right.x);
+	end
+	
+	if plot_switch
+		plot(maxima{counter}.right.x,maxima{counter}.right.y,'ro');
+		plot(maxima{counter}.left.x,maxima{counter}.left.y,'ro');
+	end
+	counter=counter+1;
+end
+
+
+% umrechnung in die Darstellung, die wir brauchen:
+for i=1:counter-1
+	logtime=maxima{i}.t;
+	time=logtime2time(logtime);
+	maxima{i}.t=time;
+	maxima{i}.fre=1/time;
+	maxima{i}.y=gettimevalue(sig_in,logtime);
+
+	left=maxima{i}.left;
+	lefttime=logtime2time(left.t);
+	maxima{i}.left.t=lefttime;
+	maxima{i}.left.fre=1/lefttime;
+	maxima{i}.left.y=gettimevalue(sig_in,left.t);
+
+	right=maxima{i}.right;
+	righttime=logtime2time(right.t);
+	maxima{i}.right.t=righttime;
+	maxima{i}.right.fre=1/righttime;
+	maxima{i}.right.y=gettimevalue(sig_in,right.t);
+end
+
+
+out = maxima;
+
+
+
+function time=logtime2time(logtime)
+	time=f2f(logtime,0,0.035,0.001,0.035,'linlog');
+