1 /*****************************************************************
2 * gavl - a general purpose audio/video processing library
3 *
4 * Copyright (c) 2001 - 2011 Members of the Gmerlin project
5 * gmerlin-general@lists.sourceforge.net
6 * http://gmerlin.sourceforge.net
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * *****************************************************************/
21
22 #include <stdlib.h>
23 #include <math.h>
24 #include <string.h>
25
26
27 #include <gavl.h>
28
29 struct gavl_peak_detector_s
30 {
31 int64_t min_i[GAVL_MAX_CHANNELS];
32 int64_t max_i[GAVL_MAX_CHANNELS];
33 double min_d[GAVL_MAX_CHANNELS];
34 double max_d[GAVL_MAX_CHANNELS];
35 double abs_d[GAVL_MAX_CHANNELS];
36
37 gavl_audio_format_t format;
38 void (*update_channel)(gavl_peak_detector_t*,void*,int num, int offset,
39 int advance, int channel);
40 void (*update)(gavl_peak_detector_t*, gavl_audio_frame_t*);
41 };
42
update_none(gavl_peak_detector_t * pd,gavl_audio_frame_t * f)43 static void update_none(gavl_peak_detector_t*pd, gavl_audio_frame_t*f)
44 {
45 int i;
46 for(i = 0; i < pd->format.num_channels; i++)
47 {
48 pd->update_channel(pd, f->channels.s_8[i], f->valid_samples,
49 0, 1, i);
50 }
51 }
52
update_all(gavl_peak_detector_t * pd,gavl_audio_frame_t * f)53 static void update_all(gavl_peak_detector_t*pd, gavl_audio_frame_t*f)
54 {
55 int i;
56 for(i = 0; i < pd->format.num_channels; i++)
57 {
58 pd->update_channel(pd, f->samples.s_8,
59 f->valid_samples,
60 i, pd->format.num_channels, i);
61 }
62 }
63
update_2(gavl_peak_detector_t * pd,gavl_audio_frame_t * f)64 static void update_2(gavl_peak_detector_t*pd, gavl_audio_frame_t*f)
65 {
66 int i;
67 for(i = 0; i < pd->format.num_channels/2; i++)
68 {
69 pd->update_channel(pd, f->samples.s_8,
70 f->valid_samples,
71 0, 2, 2*i);
72 pd->update_channel(pd, f->samples.s_8,
73 f->valid_samples,
74 1, 2, 2*i+1);
75 }
76 if(pd->format.num_channels % 2)
77 pd->update_channel(pd, f->channels.s_8[pd->format.num_channels-1],
78 f->valid_samples, 0, 1, pd->format.num_channels-1);
79 }
80
update_channel_u8(gavl_peak_detector_t * pd,void * _samples,int num,int offset,int advance,int channel)81 static void update_channel_u8(gavl_peak_detector_t * pd, void * _samples,
82 int num, int offset,
83 int advance, int channel)
84 {
85 int i;
86 uint8_t * samples = (uint8_t *)_samples;
87 samples += offset;
88 for(i = 0; i < num; i++)
89 {
90 if(*samples > pd->max_i[channel]) pd->max_i[channel] = *samples;
91 if(*samples < pd->min_i[channel]) pd->min_i[channel] = *samples;
92 samples += advance;
93 }
94 pd->min_d[channel] = (double)((int)pd->min_i[channel]-0x80) / 128.0;
95 pd->max_d[channel] = (double)((int)pd->max_i[channel]-0x80) / 127.0;
96 }
97
update_channel_s8(gavl_peak_detector_t * pd,void * _samples,int num,int offset,int advance,int channel)98 static void update_channel_s8(gavl_peak_detector_t * pd, void * _samples,
99 int num, int offset,
100 int advance, int channel)
101 {
102 int i;
103 int8_t * samples = (int8_t *)_samples;
104 samples += offset;
105 for(i = 0; i < num; i++)
106 {
107 if(*samples > pd->max_i[channel]) pd->max_i[channel] = *samples;
108 if(*samples < pd->min_i[channel]) pd->min_i[channel] = *samples;
109 samples += advance;
110 }
111 pd->min_d[channel] = (double)((int)pd->min_i[channel]) / 128.0;
112 pd->max_d[channel] = (double)((int)pd->max_i[channel]) / 127.0;
113 }
114
update_channel_u16(gavl_peak_detector_t * pd,void * _samples,int num,int offset,int advance,int channel)115 static void update_channel_u16(gavl_peak_detector_t * pd, void * _samples,
116 int num, int offset,
117 int advance, int channel)
118 {
119 int i;
120 uint16_t * samples = (uint16_t *)_samples;
121 samples += offset;
122 for(i = 0; i < num; i++)
123 {
124 if(*samples > pd->max_i[channel]) pd->max_i[channel] = *samples;
125 if(*samples < pd->min_i[channel]) pd->min_i[channel] = *samples;
126 samples += advance;
127 }
128 pd->min_d[channel] = (double)((int)pd->min_i[channel]-0x8000) / 32768.0;
129 pd->max_d[channel] = (double)((int)pd->max_i[channel]-0x8000) / 32767.0;
130 }
131
update_channel_s16(gavl_peak_detector_t * pd,void * _samples,int num,int offset,int advance,int channel)132 static void update_channel_s16(gavl_peak_detector_t * pd, void * _samples,
133 int num, int offset,
134 int advance, int channel)
135 {
136 int i;
137 int16_t * samples = (int16_t *)_samples;
138 samples += offset;
139 for(i = 0; i < num; i++)
140 {
141 if(*samples > pd->max_i[channel]) pd->max_i[channel] = *samples;
142 if(*samples < pd->min_i[channel]) pd->min_i[channel] = *samples;
143 samples += advance;
144 }
145 pd->min_d[channel] = (double)((int)pd->min_i[channel]) / 32768.0;
146 pd->max_d[channel] = (double)((int)pd->max_i[channel]) / 32767.0;
147 }
148
update_channel_s32(gavl_peak_detector_t * pd,void * _samples,int num,int offset,int advance,int channel)149 static void update_channel_s32(gavl_peak_detector_t * pd, void * _samples,
150 int num, int offset,
151 int advance, int channel)
152 {
153 int i;
154 int32_t * samples = (int32_t *)_samples;
155 samples += offset;
156 for(i = 0; i < num; i++)
157 {
158 if(*samples > pd->max_i[channel]) pd->max_i[channel] = *samples;
159 if(*samples < pd->min_i[channel]) pd->min_i[channel] = *samples;
160 samples += advance;
161 }
162 pd->min_d[channel] = (double)((int)pd->min_i[channel]) / 2147483648.0;
163 pd->max_d[channel] = (double)((int)pd->max_i[channel]) / 2147483647.0;
164 }
165
update_channel_float(gavl_peak_detector_t * pd,void * _samples,int num,int offset,int advance,int channel)166 static void update_channel_float(gavl_peak_detector_t * pd, void * _samples,
167 int num, int offset,
168 int advance, int channel)
169 {
170 int i;
171 float * samples = (float*)_samples;
172 samples += offset;
173 for(i = 0; i < num; i++)
174 {
175 if(*samples > pd->max_d[channel]) pd->max_d[channel] = *samples;
176 if(*samples < pd->min_d[channel]) pd->min_d[channel] = *samples;
177 samples += advance;
178 }
179 }
180
update_channel_double(gavl_peak_detector_t * pd,void * _samples,int num,int offset,int advance,int channel)181 static void update_channel_double(gavl_peak_detector_t * pd, void * _samples,
182 int num, int offset,
183 int advance, int channel)
184 {
185 int i;
186 double * samples = (double*)_samples;
187 samples += offset;
188 for(i = 0; i < num; i++)
189 {
190 if(*samples > pd->max_d[channel]) pd->max_d[channel] = *samples;
191 if(*samples < pd->min_d[channel]) pd->min_d[channel] = *samples;
192 samples += advance;
193 }
194 }
195
gavl_peak_detector_create()196 gavl_peak_detector_t * gavl_peak_detector_create()
197 {
198 gavl_peak_detector_t * ret;
199 ret = calloc(1, sizeof(*ret));
200 return ret;
201 }
202
203
gavl_peak_detector_destroy(gavl_peak_detector_t * pd)204 void gavl_peak_detector_destroy(gavl_peak_detector_t *pd)
205 {
206 free(pd);
207 }
208
209
gavl_peak_detector_set_format(gavl_peak_detector_t * pd,const gavl_audio_format_t * format)210 void gavl_peak_detector_set_format(gavl_peak_detector_t *pd,
211 const gavl_audio_format_t * format)
212 {
213 gavl_audio_format_copy(&pd->format, format);
214 switch(pd->format.interleave_mode)
215 {
216 case GAVL_INTERLEAVE_NONE:
217 pd->update = update_none;
218 break;
219 case GAVL_INTERLEAVE_ALL:
220 pd->update = update_all;
221 break;
222 case GAVL_INTERLEAVE_2:
223 pd->update = update_2;
224 break;
225 }
226 switch(pd->format.sample_format)
227 {
228 case GAVL_SAMPLE_U8:
229 pd->update_channel = update_channel_u8;
230 break;
231 case GAVL_SAMPLE_S8:
232 pd->update_channel = update_channel_s8;
233 break;
234 case GAVL_SAMPLE_U16:
235 pd->update_channel = update_channel_u16;
236 break;
237 case GAVL_SAMPLE_S16:
238 pd->update_channel = update_channel_s16;
239 break;
240 case GAVL_SAMPLE_S32:
241 pd->update_channel = update_channel_s32;
242 break;
243 case GAVL_SAMPLE_FLOAT:
244 pd->update_channel = update_channel_float;
245 break;
246 case GAVL_SAMPLE_DOUBLE:
247 pd->update_channel = update_channel_double;
248 break;
249 case GAVL_SAMPLE_NONE:
250 break;
251 }
252 gavl_peak_detector_reset(pd);
253 }
254
gavl_peak_detector_update(gavl_peak_detector_t * pd,gavl_audio_frame_t * frame)255 void gavl_peak_detector_update(gavl_peak_detector_t *pd,
256 gavl_audio_frame_t * frame)
257 {
258 int i;
259 pd->update(pd, frame);
260
261 for(i = 0; i < pd->format.num_channels; i++)
262 {
263 pd->abs_d[i] = (pd->max_d[i] > fabs(pd->min_d[i])) ?
264 pd->max_d[i] : fabs(pd->min_d[i]);
265 }
266 }
267
gavl_peak_detector_get_peak(gavl_peak_detector_t * pd,double * min,double * max,double * abs)268 void gavl_peak_detector_get_peak(gavl_peak_detector_t * pd,
269 double * min, double * max,
270 double * abs)
271 {
272 int i;
273 double min1 = 0.0, max1 = 0.0, abs1 = 0.0;
274
275 for(i = 0; i < pd->format.num_channels; i++)
276 {
277 if(pd->min_d[i] < min1)
278 min1 = pd->min_d[i];
279
280 if(pd->max_d[i] > max1)
281 max1 = pd->max_d[i];
282
283 if(pd->abs_d[i] > abs1)
284 abs1 = pd->abs_d[i];
285 }
286 if(min)
287 *min = min1;
288 if(max)
289 *max = max1;
290 if(abs)
291 *abs = abs1;
292 }
293
gavl_peak_detector_get_peaks(gavl_peak_detector_t * pd,double * min,double * max,double * abs)294 void gavl_peak_detector_get_peaks(gavl_peak_detector_t * pd,
295 double * min, double * max,
296 double * abs)
297 {
298 if(min)
299 memcpy(min, pd->min_d, pd->format.num_channels * sizeof(*min));
300 if(max)
301 memcpy(max, pd->max_d, pd->format.num_channels * sizeof(*max));
302 if(abs)
303 memcpy(abs, pd->abs_d, pd->format.num_channels * sizeof(*max));
304 }
305
gavl_peak_detector_reset(gavl_peak_detector_t * pd)306 void gavl_peak_detector_reset(gavl_peak_detector_t * pd)
307 {
308 int i;
309 switch(pd->format.sample_format)
310 {
311 case GAVL_SAMPLE_U8:
312 for(i = 0; i < pd->format.num_channels; i++)
313 {
314 pd->min_i[i] = 0x80;
315 pd->max_i[i] = 0x80;
316 }
317 break;
318 case GAVL_SAMPLE_U16:
319 for(i = 0; i < pd->format.num_channels; i++)
320 {
321 pd->min_i[i] = 0x8000;
322 pd->max_i[i] = 0x8000;
323 }
324 break;
325 case GAVL_SAMPLE_S8:
326 case GAVL_SAMPLE_S16:
327 case GAVL_SAMPLE_S32:
328 for(i = 0; i < pd->format.num_channels; i++)
329 {
330 pd->min_i[i] = 0x0;
331 pd->max_i[i] = 0x0;
332 }
333 break;
334 case GAVL_SAMPLE_FLOAT:
335 case GAVL_SAMPLE_DOUBLE:
336 case GAVL_SAMPLE_NONE:
337 break;
338 }
339 for(i = 0; i < pd->format.num_channels; i++)
340 {
341 pd->min_d[i] = 0.0;
342 pd->max_d[i] = 0.0;
343 pd->abs_d[i] = 0.0;
344 }
345 }
346