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 //=============================================================================
22 // 1: uses a 1 value memory and coefficients new=a*old+b*cur (with a+b=1)
23 // 2: uses several samples to smooth the variations (standard weighted mean
26 // Size of the memory array
27 // FIXME: should depend on the frequency of the data (should be a few seconds)
30 // If summing all the mem[].len is lower than MIN_SAMPLE_SIZE bytes, then we
31 // choose to ignore the computed value as it's not significant enough
32 // FIXME: should depend on the frequency of the data (0.5s maybe)
33 #define MIN_SAMPLE_SIZE 32000
35 // mul is the value by which the samples are scaled
36 // and has to be in [MUL_MIN, MUL_MAX]
42 // FIXME: should be relative to the level of the samples
43 #define SIL_S16 (SHRT_MAX * 0.01)
44 #define SIL_FLOAT (INT_MAX * 0.01) // FIXME
46 // smooth must be in ]0.0, 1.0[
47 #define SMOOTH_MUL 0.06
48 #define SMOOTH_LASTAVG 0.06
50 #define DEFAULT_TARGET 0.25
52 // Data for specific instances of this filter
53 typedef struct af_volume_s
55 int method
; // method used
58 float lastavg
; // history value of the filter
62 float avg
; // average level of the sample
63 int len
; // sample size (weight)
70 // Initialization and runtime control
71 static int control(struct af_instance_s
* af
, int cmd
, void* arg
)
73 af_volnorm_t
* s
= (af_volnorm_t
*)af
->setup
;
76 case AF_CONTROL_REINIT
:
78 if(!arg
) return AF_ERROR
;
80 af
->data
->rate
= ((af_data_t
*)arg
)->rate
;
81 af
->data
->nch
= ((af_data_t
*)arg
)->nch
;
83 if(((af_data_t
*)arg
)->format
== (AF_FORMAT_S16_NE
)){
84 af
->data
->format
= AF_FORMAT_S16_NE
;
87 af
->data
->format
= AF_FORMAT_FLOAT_NE
;
90 return af_test_output(af
,(af_data_t
*)arg
);
91 case AF_CONTROL_COMMAND_LINE
:{
93 float target
= DEFAULT_TARGET
;
94 sscanf((char*)arg
,"%d:%f", &i
, &target
);
98 s
->mid_s16
= ((float)SHRT_MAX
) * target
;
99 s
->mid_float
= ((float)INT_MAX
) * target
;
107 static void uninit(struct af_instance_s
* af
)
115 static void method1_int16(af_volnorm_t
*s
, af_data_t
*c
)
118 int16_t *data
= (int16_t*)c
->audio
; // Audio data
119 int len
= c
->len
/2; // Number of samples
120 float curavg
= 0.0, newavg
, neededmul
;
123 for (i
= 0; i
< len
; i
++)
128 curavg
= sqrt(curavg
/ (float) len
);
130 // Evaluate an adequate 'mul' coefficient based on previous state, current
131 // samples level, etc
133 if (curavg
> SIL_S16
)
135 neededmul
= s
->mid_s16
/ (curavg
* s
->mul
);
136 s
->mul
= (1.0 - SMOOTH_MUL
) * s
->mul
+ SMOOTH_MUL
* neededmul
;
138 // clamp the mul coefficient
139 s
->mul
= clamp(s
->mul
, MUL_MIN
, MUL_MAX
);
142 // Scale & clamp the samples
143 for (i
= 0; i
< len
; i
++)
145 tmp
= s
->mul
* data
[i
];
146 tmp
= clamp(tmp
, SHRT_MIN
, SHRT_MAX
);
150 // Evaulation of newavg (not 100% accurate because of values clamping)
151 newavg
= s
->mul
* curavg
;
153 // Stores computed values for future smoothing
154 s
->lastavg
= (1.0 - SMOOTH_LASTAVG
) * s
->lastavg
+ SMOOTH_LASTAVG
* newavg
;
157 static void method1_float(af_volnorm_t
*s
, af_data_t
*c
)
160 float *data
= (float*)c
->audio
; // Audio data
161 int len
= c
->len
/4; // Number of samples
162 float curavg
= 0.0, newavg
, neededmul
, tmp
;
164 for (i
= 0; i
< len
; i
++)
169 curavg
= sqrt(curavg
/ (float) len
);
171 // Evaluate an adequate 'mul' coefficient based on previous state, current
172 // samples level, etc
174 if (curavg
> SIL_FLOAT
) // FIXME
176 neededmul
= s
->mid_float
/ (curavg
* s
->mul
);
177 s
->mul
= (1.0 - SMOOTH_MUL
) * s
->mul
+ SMOOTH_MUL
* neededmul
;
179 // clamp the mul coefficient
180 s
->mul
= clamp(s
->mul
, MUL_MIN
, MUL_MAX
);
183 // Scale & clamp the samples
184 for (i
= 0; i
< len
; i
++)
187 // Evaulation of newavg (not 100% accurate because of values clamping)
188 newavg
= s
->mul
* curavg
;
190 // Stores computed values for future smoothing
191 s
->lastavg
= (1.0 - SMOOTH_LASTAVG
) * s
->lastavg
+ SMOOTH_LASTAVG
* newavg
;
194 static void method2_int16(af_volnorm_t
*s
, af_data_t
*c
)
197 int16_t *data
= (int16_t*)c
->audio
; // Audio data
198 int len
= c
->len
/2; // Number of samples
199 float curavg
= 0.0, newavg
, avg
= 0.0;
200 int tmp
, totallen
= 0;
202 for (i
= 0; i
< len
; i
++)
207 curavg
= sqrt(curavg
/ (float) len
);
209 // Evaluate an adequate 'mul' coefficient based on previous state, current
210 // samples level, etc
211 for (i
= 0; i
< NSAMPLES
; i
++)
213 avg
+= s
->mem
[i
].avg
* (float)s
->mem
[i
].len
;
214 totallen
+= s
->mem
[i
].len
;
217 if (totallen
> MIN_SAMPLE_SIZE
)
219 avg
/= (float)totallen
;
222 s
->mul
= s
->mid_s16
/ avg
;
223 s
->mul
= clamp(s
->mul
, MUL_MIN
, MUL_MAX
);
227 // Scale & clamp the samples
228 for (i
= 0; i
< len
; i
++)
230 tmp
= s
->mul
* data
[i
];
231 tmp
= clamp(tmp
, SHRT_MIN
, SHRT_MAX
);
235 // Evaulation of newavg (not 100% accurate because of values clamping)
236 newavg
= s
->mul
* curavg
;
238 // Stores computed values for future smoothing
239 s
->mem
[s
->idx
].len
= len
;
240 s
->mem
[s
->idx
].avg
= newavg
;
241 s
->idx
= (s
->idx
+ 1) % NSAMPLES
;
244 static void method2_float(af_volnorm_t
*s
, af_data_t
*c
)
247 float *data
= (float*)c
->audio
; // Audio data
248 int len
= c
->len
/4; // Number of samples
249 float curavg
= 0.0, newavg
, avg
= 0.0, tmp
;
252 for (i
= 0; i
< len
; i
++)
257 curavg
= sqrt(curavg
/ (float) len
);
259 // Evaluate an adequate 'mul' coefficient based on previous state, current
260 // samples level, etc
261 for (i
= 0; i
< NSAMPLES
; i
++)
263 avg
+= s
->mem
[i
].avg
* (float)s
->mem
[i
].len
;
264 totallen
+= s
->mem
[i
].len
;
267 if (totallen
> MIN_SAMPLE_SIZE
)
269 avg
/= (float)totallen
;
270 if (avg
>= SIL_FLOAT
)
272 s
->mul
= s
->mid_float
/ avg
;
273 s
->mul
= clamp(s
->mul
, MUL_MIN
, MUL_MAX
);
277 // Scale & clamp the samples
278 for (i
= 0; i
< len
; i
++)
281 // Evaulation of newavg (not 100% accurate because of values clamping)
282 newavg
= s
->mul
* curavg
;
284 // Stores computed values for future smoothing
285 s
->mem
[s
->idx
].len
= len
;
286 s
->mem
[s
->idx
].avg
= newavg
;
287 s
->idx
= (s
->idx
+ 1) % NSAMPLES
;
290 // Filter data through filter
291 static af_data_t
* play(struct af_instance_s
* af
, af_data_t
* data
)
293 af_volnorm_t
*s
= af
->setup
;
295 if(af
->data
->format
== (AF_FORMAT_S16_NE
))
298 method2_int16(s
, data
);
300 method1_int16(s
, data
);
302 else if(af
->data
->format
== (AF_FORMAT_FLOAT_NE
))
305 method2_float(s
, data
);
307 method1_float(s
, data
);
312 // Allocate memory and set function pointers
313 static int af_open(af_instance_t
* af
){
319 af
->data
=calloc(1,sizeof(af_data_t
));
320 af
->setup
=calloc(1,sizeof(af_volnorm_t
));
321 if(af
->data
== NULL
|| af
->setup
== NULL
)
324 ((af_volnorm_t
*)af
->setup
)->mul
= MUL_INIT
;
325 ((af_volnorm_t
*)af
->setup
)->lastavg
= ((float)SHRT_MAX
) * DEFAULT_TARGET
;
326 ((af_volnorm_t
*)af
->setup
)->idx
= 0;
327 ((af_volnorm_t
*)af
->setup
)->mid_s16
= ((float)SHRT_MAX
) * DEFAULT_TARGET
;
328 ((af_volnorm_t
*)af
->setup
)->mid_float
= ((float)INT_MAX
) * DEFAULT_TARGET
;
329 for (i
= 0; i
< NSAMPLES
; i
++)
331 ((af_volnorm_t
*)af
->setup
)->mem
[i
].len
= 0;
332 ((af_volnorm_t
*)af
->setup
)->mem
[i
].avg
= 0;
337 // Description of this filter
338 af_info_t af_info_volnorm
= {
339 "Volume normalizer filter",
341 "Alex Beregszaszi & Pierre Lombard",
343 AF_FLAGS_NOT_REENTRANT
,