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