comparison libao2/pl_volnorm.c @ 4941:9a468a190c4c

volume normalizer plugin support
author pl
date Tue, 05 Mar 2002 09:17:36 +0000
parents
children acdff5b36ea9
comparison
equal deleted inserted replaced
4940:098970f06dc2 4941:9a468a190c4c
1 /* Normalizer plugin
2 *
3 * Limitations:
4 * - only AFMT_S16_LE supported
5 * - no parameters yet => tweak the values by editing the #defines
6 *
7 * License: GPLv2
8 * Author: pl <p_l@gmx.fr> (c) 2002 and beyond...
9 *
10 * Sources: some ideas from volnorm for xmms
11 *
12 * */
13
14 #define PLUGIN
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <inttypes.h>
19 #include <math.h> // for sqrt()
20
21 #include "audio_out.h"
22 #include "audio_plugin.h"
23 #include "audio_plugin_internal.h"
24 #include "afmt.h"
25
26 static ao_info_t info = {
27 "Volume normalizer",
28 "volnorm",
29 "pl <p_l@gmx.fr>",
30 ""
31 };
32
33 LIBAO_PLUGIN_EXTERN(volnorm)
34
35 // mul is the value by which the samples are scaled
36 // and has to be in [MUL_MIN, MUL_MAX]
37 #define MUL_INIT 1.0
38 #define MUL_MIN 0.1
39 #define MUL_MAX 15.0
40 static float mul;
41
42 // "history" value of the filter
43 static float lastavg;
44
45 // SMOOTH_* must be in ]0.0, 1.0[
46 // The new value accounts for SMOOTH_MUL in the value and history
47 #define SMOOTH_MUL 0.06
48 #define SMOOTH_LASTAVG 0.06
49
50 // ideal average level
51 #define MID_S16 (INT16_MAX * 0.25)
52
53 // silence level
54 #define SIL_S16 (INT16_MAX * 0.02)
55
56 // local data
57 static struct {
58 int inuse; // This plugin is in use TRUE, FALSE
59 int format; // sample fomat
60 } pl_volnorm = {0, 0};
61
62
63 // minimal interface
64 static int control(int cmd,int arg){
65 switch(cmd){
66 case AOCONTROL_PLUGIN_SET_LEN:
67 return CONTROL_OK;
68 }
69 return CONTROL_UNKNOWN;
70 }
71
72 // minimal interface
73 // open & setup audio device
74 // return: 1=success 0=fail
75 static int init(){
76 switch(ao_plugin_data.format){
77 case(AFMT_S16_LE):
78 break;
79 default:
80 fprintf(stderr,"[pl_volnorm] Audio format not yet supported.\n");
81 return 0;
82 }
83
84 pl_volnorm.format = ao_plugin_data.format;
85 pl_volnorm.inuse = 1;
86
87 reset();
88
89 printf("[pl_volnorm] Normalizer plugin in use.\n");
90 return 1;
91 }
92
93 // close plugin
94 static void uninit(){
95 pl_volnorm.inuse=0;
96 }
97
98 // empty buffers
99 static void reset(){
100 mul = MUL_INIT;
101 switch(ao_plugin_data.format) {
102 case(AFMT_S16_LE):
103 lastavg = MID_S16;
104 break;
105 default:
106 fprintf(stderr,"[pl_volnorm] internal inconsistency - please bugreport.\n");
107 *(char *) 0 = 0;
108 }
109 }
110
111 // processes 'ao_plugin_data.len' bytes of 'data'
112 // called for every block of data
113 static int play(){
114
115 switch(pl_volnorm.format){
116 case(AFMT_S16_LE): {
117
118 #define CLAMP(x,m,M) do { if ((x)<(m)) (x) = (m); else if ((x)>(M)) (x) = (M); } while(0)
119
120 int16_t* data=(int16_t*)ao_plugin_data.data;
121 int len=ao_plugin_data.len / 2; // 16 bits samples
122
123 int32_t i;
124 register int32_t tmp;
125 register float curavg;
126 float newavg;
127 float neededmul;
128
129 // average of the current samples
130 curavg = 0.0;
131 for (i = 0; i < len ; ++i) {
132 tmp = data[i];
133 curavg += tmp * tmp;
134 }
135 curavg = sqrt(curavg / (float) len);
136
137 if (curavg > SIL_S16) {
138 neededmul = MID_S16 / ( curavg * mul);
139 mul = (1.0 - SMOOTH_MUL) * mul + SMOOTH_MUL * neededmul;
140
141 // Clamp the mul coefficient
142 CLAMP(mul, MUL_MIN, MUL_MAX);
143 }
144
145 // Scale & clamp the samples
146 for (i=0; i < len ; ++i) {
147 tmp = data[i] * mul;
148 CLAMP(tmp, INT16_MIN, INT16_MAX);
149 data[i] = tmp;
150 }
151
152 // Evaluation of newavg (not 100% accurate because of values clamping)
153 newavg = mul * curavg;
154
155 #if 0
156 printf("time = %d len = %d curavg = %6.0f lastavg = %6.0f newavg = %6.0f\n"
157 " needed_m = %2.2f m = %2.2f\n\n",
158 time(NULL), len, curavg, lastavg, newavg, neededmul, mul);
159 #endif
160
161 lastavg = (1.0 - SMOOTH_LASTAVG) * lastavg + SMOOTH_LASTAVG * newavg;
162
163 break;
164 }
165 default:
166 return 0;
167 }
168 return 1;
169
170 }
171