1 /*=============================================================================
3 // This software has been released under the terms of the GNU General Public
4 // license. See http://www.gnu.org/copyleft/gpl.html for details.
6 // Copyright 2004 Alex Beregszaszi & Pierre Lombard
8 //=============================================================================
23 // 1: uses a 1 value memory and coefficients new=a*old+b*cur (with a+b=1)
24 // 2: uses several samples to smooth the variations (standard weighted mean
27 // Size of the memory array
28 // FIXME: should depend on the frequency of the data (should be a few seconds)
31 // If summing all the mem[].len is lower than MIN_SAMPLE_SIZE bytes, then we
32 // choose to ignore the computed value as it's not significant enough
33 // FIXME: should depend on the frequency of the data (0.5s maybe)
34 #define MIN_SAMPLE_SIZE 32000
36 // mul is the value by which the samples are scaled
37 // and has to be in [MUL_MIN, MUL_MAX]
43 // FIXME: should be relative to the level of the samples
44 #define SIL_S16 (SHRT_MAX * 0.01)
45 #define SIL_FLOAT (INT_MAX * 0.01) // FIXME
47 // smooth must be in ]0.0, 1.0[
48 #define SMOOTH_MUL 0.06
49 #define SMOOTH_LASTAVG 0.06
51 #define DEFAULT_TARGET 0.25
53 // Data for specific instances of this filter
54 typedef struct af_volume_s
56 int method
; // method used
59 float lastavg
; // history value of the filter
63 float avg
; // average level of the sample
64 int len
; // sample size (weight)
71 // Initialization and runtime control
72 static int control(struct af_instance_s
* af
, int cmd
, void* arg
)
74 af_volnorm_t
* s
= (af_volnorm_t
*)af
->setup
;
77 case AF_CONTROL_REINIT
:
79 if(!arg
) return AF_ERROR
;
81 af
->data
->rate
= ((af_data_t
*)arg
)->rate
;
82 af
->data
->nch
= ((af_data_t
*)arg
)->nch
;
84 if(((af_data_t
*)arg
)->format
== (AF_FORMAT_S16_NE
)){
85 af
->data
->format
= AF_FORMAT_S16_NE
;
88 af
->data
->format
= AF_FORMAT_FLOAT_NE
;
91 return af_test_output(af
,(af_data_t
*)arg
);
92 case AF_CONTROL_COMMAND_LINE
:{
94 float target
= DEFAULT_TARGET
;
95 sscanf((char*)arg
,"%d:%f", &i
, &target
);
99 s
->mid_s16
= ((float)SHRT_MAX
) * target
;
100 s
->mid_float
= ((float)INT_MAX
) * target
;
108 static void uninit(struct af_instance_s
* af
)
116 static void method1_int16(af_volnorm_t
*s
, af_data_t
*c
)
119 int16_t *data
= (int16_t*)c
->audio
; // Audio data
120 int len
= c
->len
/2; // Number of samples
121 float curavg
= 0.0, newavg
, neededmul
;
124 for (i
= 0; i
< len
; i
++)
129 curavg
= sqrt(curavg
/ (float) len
);
131 // Evaluate an adequate 'mul' coefficient based on previous state, current
132 // samples level, etc
134 if (curavg
> SIL_S16
)
136 neededmul
= s
->mid_s16
/ (curavg
* s
->mul
);
137 s
->mul
= (1.0 - SMOOTH_MUL
) * s
->mul
+ SMOOTH_MUL
* neededmul
;
139 // clamp the mul coefficient
140 s
->mul
= clamp(s
->mul
, MUL_MIN
, MUL_MAX
);
143 // Scale & clamp the samples
144 for (i
= 0; i
< len
; i
++)
146 tmp
= s
->mul
* data
[i
];
147 tmp
= clamp(tmp
, SHRT_MIN
, SHRT_MAX
);
151 // Evaulation of newavg (not 100% accurate because of values clamping)
152 newavg
= s
->mul
* curavg
;
154 // Stores computed values for future smoothing
155 s
->lastavg
= (1.0 - SMOOTH_LASTAVG
) * s
->lastavg
+ SMOOTH_LASTAVG
* newavg
;
158 static void method1_float(af_volnorm_t
*s
, af_data_t
*c
)
161 float *data
= (float*)c
->audio
; // Audio data
162 int len
= c
->len
/4; // Number of samples
163 float curavg
= 0.0, newavg
, neededmul
, tmp
;
165 for (i
= 0; i
< len
; i
++)
170 curavg
= sqrt(curavg
/ (float) len
);
172 // Evaluate an adequate 'mul' coefficient based on previous state, current
173 // samples level, etc
175 if (curavg
> SIL_FLOAT
) // FIXME
177 neededmul
= s
->mid_float
/ (curavg
* s
->mul
);
178 s
->mul
= (1.0 - SMOOTH_MUL
) * s
->mul
+ SMOOTH_MUL
* neededmul
;
180 // clamp the mul coefficient
181 s
->mul
= clamp(s
->mul
, MUL_MIN
, MUL_MAX
);
184 // Scale & clamp the samples
185 for (i
= 0; i
< len
; i
++)
188 // Evaulation of newavg (not 100% accurate because of values clamping)
189 newavg
= s
->mul
* curavg
;
191 // Stores computed values for future smoothing
192 s
->lastavg
= (1.0 - SMOOTH_LASTAVG
) * s
->lastavg
+ SMOOTH_LASTAVG
* newavg
;
195 static void method2_int16(af_volnorm_t
*s
, af_data_t
*c
)
198 int16_t *data
= (int16_t*)c
->audio
; // Audio data
199 int len
= c
->len
/2; // Number of samples
200 float curavg
= 0.0, newavg
, avg
= 0.0;
201 int tmp
, totallen
= 0;
203 for (i
= 0; i
< len
; i
++)
208 curavg
= sqrt(curavg
/ (float) len
);
210 // Evaluate an adequate 'mul' coefficient based on previous state, current
211 // samples level, etc
212 for (i
= 0; i
< NSAMPLES
; i
++)
214 avg
+= s
->mem
[i
].avg
* (float)s
->mem
[i
].len
;
215 totallen
+= s
->mem
[i
].len
;
218 if (totallen
> MIN_SAMPLE_SIZE
)
220 avg
/= (float)totallen
;
223 s
->mul
= s
->mid_s16
/ avg
;
224 s
->mul
= clamp(s
->mul
, MUL_MIN
, MUL_MAX
);
228 // Scale & clamp the samples
229 for (i
= 0; i
< len
; i
++)
231 tmp
= s
->mul
* data
[i
];
232 tmp
= clamp(tmp
, SHRT_MIN
, SHRT_MAX
);
236 // Evaulation of newavg (not 100% accurate because of values clamping)
237 newavg
= s
->mul
* curavg
;
239 // Stores computed values for future smoothing
240 s
->mem
[s
->idx
].len
= len
;
241 s
->mem
[s
->idx
].avg
= newavg
;
242 s
->idx
= (s
->idx
+ 1) % NSAMPLES
;
245 static void method2_float(af_volnorm_t
*s
, af_data_t
*c
)
248 float *data
= (float*)c
->audio
; // Audio data
249 int len
= c
->len
/4; // Number of samples
250 float curavg
= 0.0, newavg
, avg
= 0.0, tmp
;
253 for (i
= 0; i
< len
; i
++)
258 curavg
= sqrt(curavg
/ (float) len
);
260 // Evaluate an adequate 'mul' coefficient based on previous state, current
261 // samples level, etc
262 for (i
= 0; i
< NSAMPLES
; i
++)
264 avg
+= s
->mem
[i
].avg
* (float)s
->mem
[i
].len
;
265 totallen
+= s
->mem
[i
].len
;
268 if (totallen
> MIN_SAMPLE_SIZE
)
270 avg
/= (float)totallen
;
271 if (avg
>= SIL_FLOAT
)
273 s
->mul
= s
->mid_float
/ avg
;
274 s
->mul
= clamp(s
->mul
, MUL_MIN
, MUL_MAX
);
278 // Scale & clamp the samples
279 for (i
= 0; i
< len
; i
++)
282 // Evaulation of newavg (not 100% accurate because of values clamping)
283 newavg
= s
->mul
* curavg
;
285 // Stores computed values for future smoothing
286 s
->mem
[s
->idx
].len
= len
;
287 s
->mem
[s
->idx
].avg
= newavg
;
288 s
->idx
= (s
->idx
+ 1) % NSAMPLES
;
291 // Filter data through filter
292 static af_data_t
* play(struct af_instance_s
* af
, af_data_t
* data
)
294 af_volnorm_t
*s
= af
->setup
;
296 if(af
->data
->format
== (AF_FORMAT_S16_NE
))
299 method2_int16(s
, data
);
301 method1_int16(s
, data
);
303 else if(af
->data
->format
== (AF_FORMAT_FLOAT_NE
))
306 method2_float(s
, data
);
308 method1_float(s
, data
);
313 // Allocate memory and set function pointers
314 static int open(af_instance_t
* af
){
321 af
->data
=calloc(1,sizeof(af_data_t
));
322 af
->setup
=calloc(1,sizeof(af_volnorm_t
));
323 if(af
->data
== NULL
|| af
->setup
== NULL
)
326 ((af_volnorm_t
*)af
->setup
)->mul
= MUL_INIT
;
327 ((af_volnorm_t
*)af
->setup
)->lastavg
= ((float)SHRT_MAX
) * DEFAULT_TARGET
;
328 ((af_volnorm_t
*)af
->setup
)->idx
= 0;
329 ((af_volnorm_t
*)af
->setup
)->mid_s16
= ((float)SHRT_MAX
) * DEFAULT_TARGET
;
330 ((af_volnorm_t
*)af
->setup
)->mid_float
= ((float)INT_MAX
) * DEFAULT_TARGET
;
331 for (i
= 0; i
< NSAMPLES
; i
++)
333 ((af_volnorm_t
*)af
->setup
)->mem
[i
].len
= 0;
334 ((af_volnorm_t
*)af
->setup
)->mem
[i
].avg
= 0;
339 // Description of this filter
340 af_info_t af_info_volnorm
= {
341 "Volume normalizer filter",
343 "Alex Beregszaszi & Pierre Lombard",
345 AF_FLAGS_NOT_REENTRANT
,