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