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
|