annotate 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
rev   line source
bleeck@4 1 % function out = PeakPicker(sig_in, params)
bleeck@4 2 %
bleeck@4 3 % Find the peaks of a signal and their neighbours
bleeck@4 4 %
bleeck@4 5 % INPUT VALUES:
bleeck@4 6 % sig_in Input signal
bleeck@4 7 % threshold dynamic threshold. Off if not used
bleeck@4 8 %
bleeck@4 9 %
bleeck@4 10 % RETURN VALUE:
bleeck@4 11 % out is an array of a struct
bleeck@4 12 % out.x x position of the Peak
bleeck@4 13 % out.t according time value
bleeck@4 14 % out.y y value of the peak
bleeck@4 15 % out.left.[x,t,y] left Minumum
bleeck@4 16 % out.right.[x,t,y] right Minumum
bleeck@4 17 %
bleeck@4 18 % (c) 2011, University of Southampton
bleeck@4 19 % Maintained by Stefan Bleeck (bleeck@gmail.com)
bleeck@4 20 % download of current version is on the soundsoftware site:
bleeck@4 21 % http://code.soundsoftware.ac.uk/projects/aimmat
bleeck@4 22 % documentation and everything is on http://www.acousticscale.org
bleeck@4 23
bleeck@4 24 function out = PeakPicker(sig_in,threshold)
bleeck@4 25 % threshold is the percentage of the maximum value of the signal,
bleeck@4 26 % under which a peak is not counted
bleeck@4 27
bleeck@4 28 if nargin <2
bleeck@4 29 threshold=0;
bleeck@4 30 end
bleeck@4 31
bleeck@4 32 plot_switch = 0;
bleeck@4 33
bleeck@4 34 % the original values befor filtering
bleeck@4 35 orig_values = getdata(sig_in)';
bleeck@4 36 values=getdata(sig_in)';
bleeck@4 37
bleeck@4 38 % ------------------- Find the local maxima ------------------------------
bleeck@4 39 % find x positions of ALL local maxima, incl. zero!!
bleeck@4 40 max_x = find((values >= [0 values(1:end-1)]) & (values > [values(2:end) 0]));
bleeck@4 41 max_y = orig_values(max_x);
bleeck@4 42 orig_max_y = orig_values(max_x);
bleeck@4 43
bleeck@4 44 % ------------------- Find the local minima -----------------------------
bleeck@4 45 min_x = find((values < [inf values(1:end-1)]) & (values <= [values(2:end) inf]));
bleeck@4 46 min_y = values(min_x);
bleeck@4 47
bleeck@4 48
bleeck@4 49 peakpos_x=[];
bleeck@4 50 for i=1:length(max_x),
bleeck@4 51 % only take the highest peak
bleeck@4 52 my = [max_y==max(max_y)]; % find the highest peak
bleeck@4 53 % peakpos_x(i) = max_x(my); % x pos of highest peak
bleeck@4 54 peakpos_x = [peakpos_x max_x(my)];
bleeck@4 55 max_y = max_y([max_y<max(max_y)]); % del max value in y domain
bleeck@4 56 max_x = max_x([max_x ~= peakpos_x(end)]); % and in x domain
bleeck@4 57 end
bleeck@4 58 peakpos_y = orig_values(peakpos_x); % extract the y vector
bleeck@4 59
bleeck@4 60 % maxima = cell(1, length(peakpos_x));
bleeck@4 61 maxima = [];
bleeck@4 62
bleeck@4 63 if plot_switch
bleeck@4 64 figure(123);
bleeck@4 65 clf
bleeck@4 66 plot(sig_in,'k');
bleeck@4 67 hold on;
bleeck@4 68 end
bleeck@4 69
bleeck@4 70 threshold_val=threshold*max(sig_in);
bleeck@4 71 counter=1;
bleeck@4 72
bleeck@4 73 % find the left end right minima that belong to a maximum
bleeck@4 74 for i=1:length(peakpos_x)
bleeck@4 75 y_val= orig_values(peakpos_x(i));
bleeck@4 76
bleeck@4 77 if y_val< threshold_val
bleeck@4 78 continue
bleeck@4 79 end
bleeck@4 80
bleeck@4 81 maxima{counter}.y =y_val;
bleeck@4 82 maxima{counter}.x = peakpos_x(i);
bleeck@4 83 maxima{counter}.t = bin2time(sig_in, maxima{i}.x);
bleeck@4 84 maxima{counter}.fre = 1/maxima{counter}.t;
bleeck@4 85
bleeck@4 86 if plot_switch
bleeck@4 87 plot(maxima{counter}.x,maxima{counter}.y,'go');
bleeck@4 88 end
bleeck@4 89 % find left and right minimum for this maximum
bleeck@4 90 maxima{counter}.left.x = max(min_x([min_x < maxima{counter}.x]));
bleeck@4 91 if isempty(maxima{counter}.left.x)
bleeck@4 92 maxima{counter}.left.x = 1;
bleeck@4 93 maxima{counter}.left.t = 0;
bleeck@4 94 maxima{counter}.left.y = orig_values(maxima{counter}.left.x);
bleeck@4 95 else
bleeck@4 96 maxima{counter}.left.y = orig_values(maxima{counter}.left.x);
bleeck@4 97 maxima{counter}.left.t = bin2time(sig_in, maxima{counter}.left.x);
bleeck@4 98 end
bleeck@4 99 maxima{counter}.right.x = min(min_x([min_x > maxima{counter}.x]));
bleeck@4 100 if isempty(maxima{counter}.right.x)
bleeck@4 101 maxima{counter}.right.x = length(orig_values);
bleeck@4 102 maxima{counter}.right.t = 0;
bleeck@4 103 maxima{counter}.right.y = orig_values(maxima{counter}.right.x);
bleeck@4 104 else
bleeck@4 105 maxima{counter}.right.y = orig_values(maxima{counter}.right.x);
bleeck@4 106 maxima{counter}.right.t = bin2time(sig_in, maxima{counter}.right.x);
bleeck@4 107 end
bleeck@4 108
bleeck@4 109 if plot_switch
bleeck@4 110 plot(maxima{counter}.right.x,maxima{counter}.right.y,'ro');
bleeck@4 111 plot(maxima{counter}.left.x,maxima{counter}.left.y,'ro');
bleeck@4 112 end
bleeck@4 113 counter=counter+1;
bleeck@4 114 end
bleeck@4 115
bleeck@4 116
bleeck@4 117 % umrechnung in die Darstellung, die wir brauchen:
bleeck@4 118 for i=1:counter-1
bleeck@4 119 logtime=maxima{i}.t;
bleeck@4 120 time=logtime2time(logtime);
bleeck@4 121 maxima{i}.t=time;
bleeck@4 122 maxima{i}.fre=1/time;
bleeck@4 123 maxima{i}.y=gettimevalue(sig_in,logtime);
bleeck@4 124
bleeck@4 125 left=maxima{i}.left;
bleeck@4 126 lefttime=logtime2time(left.t);
bleeck@4 127 maxima{i}.left.t=lefttime;
bleeck@4 128 maxima{i}.left.fre=1/lefttime;
bleeck@4 129 maxima{i}.left.y=gettimevalue(sig_in,left.t);
bleeck@4 130
bleeck@4 131 right=maxima{i}.right;
bleeck@4 132 righttime=logtime2time(right.t);
bleeck@4 133 maxima{i}.right.t=righttime;
bleeck@4 134 maxima{i}.right.fre=1/righttime;
bleeck@4 135 maxima{i}.right.y=gettimevalue(sig_in,right.t);
bleeck@4 136 end
bleeck@4 137
bleeck@4 138
bleeck@4 139 out = maxima;
bleeck@4 140
bleeck@4 141
bleeck@4 142
bleeck@4 143 function time=logtime2time(logtime)
bleeck@4 144 time=f2f(logtime,0,0.035,0.001,0.035,'linlog');
bleeck@4 145