Mercurial > hg > aimmat
comparison aim-mat/modules/usermodule/pitchstrength/PeakPicker.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 |
comparison
equal
deleted
inserted
replaced
3:20ada0af3d7d | 4:537f939baef0 |
---|---|
1 % | |
2 % function out = PeakPicker(sig_in, params) | |
3 % | |
4 % Find the peaks of a signal | |
5 % | |
6 % INPUT VALUES: | |
7 % sig_in Input signal | |
8 % params.dyn_thresh dynamic threshold. Off if not used | |
9 % params.smooth_sigma sigma for smoothing | |
10 % | |
11 % | |
12 % | |
13 % | |
14 % RETURN VALUE: | |
15 % out is an array of a struct | |
16 % out.x x position of the Peak | |
17 % out.t according time value | |
18 % out.y y value of the peak | |
19 % out.left.[x,t,y] left Minumum | |
20 % out.right.[x,t,y] right Minumum | |
21 % | |
22 % (c) 2003, University of Cambridge, Medical Research Council | |
23 % Christoph Lindner | |
24 % (c) 2011, University of Southampton | |
25 % Maintained by Stefan Bleeck (bleeck@gmail.com) | |
26 % download of current version is on the soundsoftware site: | |
27 % http://code.soundsoftware.ac.uk/projects/aimmat | |
28 % documentation and everything is on http://www.acousticscale.org | |
29 | |
30 function out = PeakPicker(sig_in, params) | |
31 | |
32 if nargin<2 | |
33 params=[]; | |
34 end | |
35 | |
36 % % % % ----- Other Parameters ----- | |
37 % % % % Lowpass param for the higpassfilter | |
38 % % % LP_sigma_for_HP_filter = getnrpoints(sig_in)/7; | |
39 % % % LP_sigma_for_smooth = 3; | |
40 % % % % min width of a peak: upper_threshold+lower_thresh | |
41 % % % upper_thresh = 0.02*getnrpoints(sig_in); | |
42 % % % lower_thresh = 0.03*getnrpoints(sig_in); | |
43 | |
44 % x is index or position in vector | |
45 % y is value of the | |
46 % t is the time domain wich is assigned to the x dimension | |
47 | |
48 % the original values befor filtering | |
49 orig_values = getdata(sig_in)'; | |
50 | |
51 if isfield(params,'smooth_sigma') | |
52 if (params.smooth_sigma~=0) | |
53 % smooth the curve to kill small side peaks | |
54 sig_in = smooth(sig_in, params.smooth_sigma); | |
55 end | |
56 end | |
57 | |
58 values=getdata(sig_in)'; | |
59 | |
60 % ------------------- Find the local maxima ------------------------------ | |
61 % find x positions of ALL local maxima, incl. zero!! | |
62 max_x = find((values >= [0 values(1:end-1)]) & (values > [values(2:end) 0])); | |
63 if isfield(params,'smooth_sigma') | |
64 if (params.smooth_sigma~=0) | |
65 % smoothing might have shifted the positions of maxima. | |
66 % Therefore the maximum is the highest of the neighbours in | |
67 % distance +- smooth_sigma | |
68 for i=1:length(max_x) | |
69 start = max_x(i)-params.smooth_sigma; | |
70 if start<1 | |
71 start=1; | |
72 end | |
73 stop = max_x(i)+params.smooth_sigma; | |
74 if stop>length(orig_values) | |
75 stop=length(orig_values); | |
76 end | |
77 m = find(orig_values(start:stop) == max(orig_values(start:stop))); | |
78 m=m(1); | |
79 max_x(i)=start-1+m; | |
80 end | |
81 end | |
82 end | |
83 max_y = orig_values(max_x); | |
84 orig_max_y = orig_values(max_x); | |
85 | |
86 % ------------------- Find the local minima ----------------------------- | |
87 min_x = find((values < [inf values(1:end-1)]) & (values <= [values(2:end) inf])); | |
88 min_y = values(min_x); | |
89 | |
90 | |
91 % peakpos_x=zeros(1,length(max_x)); | |
92 peakpos_x=[]; | |
93 for i=1:length(max_x), | |
94 % only take the highest peak | |
95 my = [max_y==max(max_y)]; % find the highest peak | |
96 % peakpos_x(i) = max_x(my); % x pos of highest peak | |
97 peakpos_x = [peakpos_x max_x(my)]; | |
98 max_y = max_y([max_y<max(max_y)]); % del max value in y domain | |
99 max_x = max_x([max_x ~= peakpos_x(end)]); % and in x domain | |
100 end | |
101 peakpos_y = orig_values(peakpos_x); % extract the y vector | |
102 | |
103 % --------------- Dynamic Threshold --------------------- | |
104 % works relativ to the mean | |
105 if isfield(params,'dyn_thresh') | |
106 if (params.dyn_thresh~=0) | |
107 % dynamic thresholding | |
108 m = mean(orig_values); | |
109 dthr = params.dyn_thresh.*m; | |
110 peakpos_x = peakpos_x([peakpos_y>=dthr]); | |
111 peakpos_y = peakpos_y([peakpos_y>=dthr]); | |
112 end | |
113 end | |
114 | |
115 maxima = cell(1, length(peakpos_x)); | |
116 % find the left end right minima that belong to a maximum | |
117 for i=1:length(peakpos_x) | |
118 maxima{i}.x = peakpos_x(i); | |
119 maxima{i}.t = bin2time(sig_in, maxima{i}.x); | |
120 maxima{i}.y = orig_values(peakpos_x(i)); | |
121 | |
122 % find left and right minimum for this maximum | |
123 maxima{i}.left.x = max(min_x([min_x < maxima{i}.x])); | |
124 if isempty(maxima{i}.left.x) | |
125 maxima{i}.left.x = 1; | |
126 maxima{i}.left.t = 0; | |
127 maxima{i}.left.y = orig_values(maxima{i}.left.x); | |
128 else | |
129 maxima{i}.left.y = orig_values(maxima{i}.left.x); | |
130 maxima{i}.left.t = bin2time(sig_in, maxima{i}.left.x); | |
131 end | |
132 maxima{i}.right.x = min(min_x([min_x > maxima{i}.x])); | |
133 if isempty(maxima{i}.right.x) | |
134 maxima{i}.right.x = length(orig_values); | |
135 maxima{i}.right.t = 0; | |
136 maxima{i}.right.y = orig_values(maxima{i}.right.x); | |
137 else | |
138 maxima{i}.right.y = orig_values(maxima{i}.right.x); | |
139 maxima{i}.right.t = bin2time(sig_in, maxima{i}.right.x); | |
140 end | |
141 end | |
142 | |
143 | |
144 out = maxima; | |
145 | |
146 |