2 * Copyright (C) 2004 Alex Beregszaszi & Pierre Lombard
4 * This file is part of MPlayer.
6 * MPlayer is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * MPlayer is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 // 1: uses a 1 value memory and coefficients new=a*old+b*cur (with a+b=1)
33 // 2: uses several samples to smooth the variations (standard weighted mean
36 // Size of the memory array
37 // FIXME: should depend on the frequency of the data (should be a few seconds)
40 // If summing all the mem[].len is lower than MIN_SAMPLE_SIZE bytes, then we
41 // choose to ignore the computed value as it's not significant enough
42 // FIXME: should depend on the frequency of the data (0.5s maybe)
43 #define MIN_SAMPLE_SIZE 32000
45 // mul is the value by which the samples are scaled
46 // and has to be in [MUL_MIN, MUL_MAX]
52 // FIXME: should be relative to the level of the samples
53 #define SIL_S16 (SHRT_MAX * 0.01)
54 #define SIL_FLOAT (INT_MAX * 0.01) // FIXME
56 // smooth must be in ]0.0, 1.0[
57 #define SMOOTH_MUL 0.06
58 #define SMOOTH_LASTAVG 0.06
60 #define DEFAULT_TARGET 0.25
62 // Data for specific instances of this filter
63 typedef struct af_volume_s
65 int method
; // method used
68 float lastavg
; // history value of the filter
72 float avg
; // average level of the sample
73 int len
; // sample size (weight)
80 // Initialization and runtime control
81 static int control(struct af_instance_s
* af
, int cmd
, void* arg
)
83 af_volnorm_t
* s
= (af_volnorm_t
*)af
->setup
;
86 case AF_CONTROL_REINIT
:
88 if(!arg
) return AF_ERROR
;
90 af
->data
->rate
= ((af_data_t
*)arg
)->rate
;
91 af
->data
->nch
= ((af_data_t
*)arg
)->nch
;
93 if(((af_data_t
*)arg
)->format
== (AF_FORMAT_S16_NE
)){
94 af
->data
->format
= AF_FORMAT_S16_NE
;
97 af
->data
->format
= AF_FORMAT_FLOAT_NE
;
100 return af_test_output(af
,(af_data_t
*)arg
);
101 case AF_CONTROL_COMMAND_LINE
:{
103 float target
= DEFAULT_TARGET
;
104 sscanf((char*)arg
,"%d:%f", &i
, &target
);
105 if (i
!= 1 && i
!= 2)
108 s
->mid_s16
= ((float)SHRT_MAX
) * target
;
109 s
->mid_float
= ((float)INT_MAX
) * target
;
117 static void uninit(struct af_instance_s
* af
)
125 static void method1_int16(af_volnorm_t
*s
, af_data_t
*c
)
128 int16_t *data
= (int16_t*)c
->audio
; // Audio data
129 int len
= c
->len
/2; // Number of samples
130 float curavg
= 0.0, newavg
, neededmul
;
133 for (i
= 0; i
< len
; i
++)
138 curavg
= sqrt(curavg
/ (float) len
);
140 // Evaluate an adequate 'mul' coefficient based on previous state, current
141 // samples level, etc
143 if (curavg
> SIL_S16
)
145 neededmul
= s
->mid_s16
/ (curavg
* s
->mul
);
146 s
->mul
= (1.0 - SMOOTH_MUL
) * s
->mul
+ SMOOTH_MUL
* neededmul
;
148 // clamp the mul coefficient
149 s
->mul
= clamp(s
->mul
, MUL_MIN
, MUL_MAX
);
152 // Scale & clamp the samples
153 for (i
= 0; i
< len
; i
++)
155 tmp
= s
->mul
* data
[i
];
156 tmp
= clamp(tmp
, SHRT_MIN
, SHRT_MAX
);
160 // Evaulation of newavg (not 100% accurate because of values clamping)
161 newavg
= s
->mul
* curavg
;
163 // Stores computed values for future smoothing
164 s
->lastavg
= (1.0 - SMOOTH_LASTAVG
) * s
->lastavg
+ SMOOTH_LASTAVG
* newavg
;
167 static void method1_float(af_volnorm_t
*s
, af_data_t
*c
)
170 float *data
= (float*)c
->audio
; // Audio data
171 int len
= c
->len
/4; // Number of samples
172 float curavg
= 0.0, newavg
, neededmul
, tmp
;
174 for (i
= 0; i
< len
; i
++)
179 curavg
= sqrt(curavg
/ (float) len
);
181 // Evaluate an adequate 'mul' coefficient based on previous state, current
182 // samples level, etc
184 if (curavg
> SIL_FLOAT
) // FIXME
186 neededmul
= s
->mid_float
/ (curavg
* s
->mul
);
187 s
->mul
= (1.0 - SMOOTH_MUL
) * s
->mul
+ SMOOTH_MUL
* neededmul
;
189 // clamp the mul coefficient
190 s
->mul
= clamp(s
->mul
, MUL_MIN
, MUL_MAX
);
193 // Scale & clamp the samples
194 for (i
= 0; i
< len
; i
++)
197 // Evaulation of newavg (not 100% accurate because of values clamping)
198 newavg
= s
->mul
* curavg
;
200 // Stores computed values for future smoothing
201 s
->lastavg
= (1.0 - SMOOTH_LASTAVG
) * s
->lastavg
+ SMOOTH_LASTAVG
* newavg
;
204 static void method2_int16(af_volnorm_t
*s
, af_data_t
*c
)
207 int16_t *data
= (int16_t*)c
->audio
; // Audio data
208 int len
= c
->len
/2; // Number of samples
209 float curavg
= 0.0, newavg
, avg
= 0.0;
210 int tmp
, totallen
= 0;
212 for (i
= 0; i
< len
; i
++)
217 curavg
= sqrt(curavg
/ (float) len
);
219 // Evaluate an adequate 'mul' coefficient based on previous state, current
220 // samples level, etc
221 for (i
= 0; i
< NSAMPLES
; i
++)
223 avg
+= s
->mem
[i
].avg
* (float)s
->mem
[i
].len
;
224 totallen
+= s
->mem
[i
].len
;
227 if (totallen
> MIN_SAMPLE_SIZE
)
229 avg
/= (float)totallen
;
232 s
->mul
= s
->mid_s16
/ avg
;
233 s
->mul
= clamp(s
->mul
, MUL_MIN
, MUL_MAX
);
237 // Scale & clamp the samples
238 for (i
= 0; i
< len
; i
++)
240 tmp
= s
->mul
* data
[i
];
241 tmp
= clamp(tmp
, SHRT_MIN
, SHRT_MAX
);
245 // Evaulation of newavg (not 100% accurate because of values clamping)
246 newavg
= s
->mul
* curavg
;
248 // Stores computed values for future smoothing
249 s
->mem
[s
->idx
].len
= len
;
250 s
->mem
[s
->idx
].avg
= newavg
;
251 s
->idx
= (s
->idx
+ 1) % NSAMPLES
;
254 static void method2_float(af_volnorm_t
*s
, af_data_t
*c
)
257 float *data
= (float*)c
->audio
; // Audio data
258 int len
= c
->len
/4; // Number of samples
259 float curavg
= 0.0, newavg
, avg
= 0.0, tmp
;
262 for (i
= 0; i
< len
; i
++)
267 curavg
= sqrt(curavg
/ (float) len
);
269 // Evaluate an adequate 'mul' coefficient based on previous state, current
270 // samples level, etc
271 for (i
= 0; i
< NSAMPLES
; i
++)
273 avg
+= s
->mem
[i
].avg
* (float)s
->mem
[i
].len
;
274 totallen
+= s
->mem
[i
].len
;
277 if (totallen
> MIN_SAMPLE_SIZE
)
279 avg
/= (float)totallen
;
280 if (avg
>= SIL_FLOAT
)
282 s
->mul
= s
->mid_float
/ avg
;
283 s
->mul
= clamp(s
->mul
, MUL_MIN
, MUL_MAX
);
287 // Scale & clamp the samples
288 for (i
= 0; i
< len
; i
++)
291 // Evaulation of newavg (not 100% accurate because of values clamping)
292 newavg
= s
->mul
* curavg
;
294 // Stores computed values for future smoothing
295 s
->mem
[s
->idx
].len
= len
;
296 s
->mem
[s
->idx
].avg
= newavg
;
297 s
->idx
= (s
->idx
+ 1) % NSAMPLES
;
300 // Filter data through filter
301 static af_data_t
* play(struct af_instance_s
* af
, af_data_t
* data
)
303 af_volnorm_t
*s
= af
->setup
;
305 if(af
->data
->format
== (AF_FORMAT_S16_NE
))
308 method2_int16(s
, data
);
310 method1_int16(s
, data
);
312 else if(af
->data
->format
== (AF_FORMAT_FLOAT_NE
))
315 method2_float(s
, data
);
317 method1_float(s
, data
);
322 // Allocate memory and set function pointers
323 static int af_open(af_instance_t
* af
){
329 af
->data
=calloc(1,sizeof(af_data_t
));
330 af
->setup
=calloc(1,sizeof(af_volnorm_t
));
331 if(af
->data
== NULL
|| af
->setup
== NULL
)
334 ((af_volnorm_t
*)af
->setup
)->mul
= MUL_INIT
;
335 ((af_volnorm_t
*)af
->setup
)->lastavg
= ((float)SHRT_MAX
) * DEFAULT_TARGET
;
336 ((af_volnorm_t
*)af
->setup
)->idx
= 0;
337 ((af_volnorm_t
*)af
->setup
)->mid_s16
= ((float)SHRT_MAX
) * DEFAULT_TARGET
;
338 ((af_volnorm_t
*)af
->setup
)->mid_float
= ((float)INT_MAX
) * DEFAULT_TARGET
;
339 for (i
= 0; i
< NSAMPLES
; i
++)
341 ((af_volnorm_t
*)af
->setup
)->mem
[i
].len
= 0;
342 ((af_volnorm_t
*)af
->setup
)->mem
[i
].avg
= 0;
347 // Description of this filter
348 af_info_t af_info_volnorm
= {
349 "Volume normalizer filter",
351 "Alex Beregszaszi & Pierre Lombard",
353 AF_FLAGS_NOT_REENTRANT
,