10l: comparison of char* ptrs with string literals
[mplayer.git] / libaf / af_volume.c
blob8485af55495dc0d0b4a92d8bce320d71c8176945
1 /*=============================================================================
2 //
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.
5 //
6 // Copyright 2002 Anders Johansson ajh@atri.curtin.edu.au
7 //
8 //=============================================================================
9 */
11 /* This audio filter changes the volume of the sound, and can be used
12 when the mixer doesn't support the PCM channel. It can handle
13 between 1 and 6 channels. The volume can be adjusted between -60dB
14 to +20dB and is set on a per channels basis. The is accessed through
15 AF_CONTROL_VOLUME_LEVEL.
17 The filter has support for soft-clipping, it is enabled by
18 AF_CONTROL_VOLUME_SOFTCLIPP. It has also a probing feature which
19 can be used to measure the power in the audio stream, both an
20 instantaneous value and the maximum value can be probed. The
21 probing is enable by AF_CONTROL_VOLUME_PROBE_ON_OFF and is done on a
22 per channel basis. The result from the probing is obtained using
23 AF_CONTROL_VOLUME_PROBE_GET and AF_CONTROL_VOLUME_PROBE_GET_MAX. The
24 probed values are calculated in dB.
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
31 #include <unistd.h>
32 #include <inttypes.h>
33 #include <math.h>
34 #include <limits.h>
36 #include "af.h"
38 // Data for specific instances of this filter
39 typedef struct af_volume_s
41 int enable[AF_NCH]; // Enable/disable / channel
42 float pow[AF_NCH]; // Estimated power level [dB]
43 float max[AF_NCH]; // Max Power level [dB]
44 float level[AF_NCH]; // Gain level for each channel
45 float time; // Forgetting factor for power estimate
46 int soft; // Enable/disable soft clipping
47 int fast; // Use fix-point volume control
48 }af_volume_t;
50 // Initialization and runtime control
51 static int control(struct af_instance_s* af, int cmd, void* arg)
53 af_volume_t* s = (af_volume_t*)af->setup;
55 switch(cmd){
56 case AF_CONTROL_REINIT:
57 // Sanity check
58 if(!arg) return AF_ERROR;
60 af->data->rate = ((af_data_t*)arg)->rate;
61 af->data->nch = ((af_data_t*)arg)->nch;
63 if(s->fast && (((af_data_t*)arg)->format != (AF_FORMAT_FLOAT_NE))){
64 af->data->format = AF_FORMAT_S16_NE;
65 af->data->bps = 2;
67 else{
68 // Cutoff set to 10Hz for forgetting factor
69 float x = 2.0*M_PI*15.0/(float)af->data->rate;
70 float t = 2.0-cos(x);
71 s->time = 1.0 - (t - sqrt(t*t - 1));
72 af_msg(AF_MSG_DEBUG0,"[volume] Forgetting factor = %0.5f\n",s->time);
73 af->data->format = AF_FORMAT_FLOAT_NE;
74 af->data->bps = 4;
76 return af_test_output(af,(af_data_t*)arg);
77 case AF_CONTROL_COMMAND_LINE:{
78 float v=0.0;
79 float vol[AF_NCH];
80 int i;
81 sscanf((char*)arg,"%f:%i", &v, &s->soft);
82 for(i=0;i<AF_NCH;i++) vol[i]=v;
83 return control(af,AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_SET, vol);
85 case AF_CONTROL_POST_CREATE:
86 s->fast = ((((af_cfg_t*)arg)->force & AF_INIT_FORMAT_MASK) ==
87 AF_INIT_FLOAT) ? 0 : 1;
88 return AF_OK;
89 case AF_CONTROL_VOLUME_ON_OFF | AF_CONTROL_SET:
90 memcpy(s->enable,(int*)arg,AF_NCH*sizeof(int));
91 return AF_OK;
92 case AF_CONTROL_VOLUME_ON_OFF | AF_CONTROL_GET:
93 memcpy((int*)arg,s->enable,AF_NCH*sizeof(int));
94 return AF_OK;
95 case AF_CONTROL_VOLUME_SOFTCLIP | AF_CONTROL_SET:
96 s->soft = *(int*)arg;
97 return AF_OK;
98 case AF_CONTROL_VOLUME_SOFTCLIP | AF_CONTROL_GET:
99 *(int*)arg = s->soft;
100 return AF_OK;
101 case AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_SET:
102 return af_from_dB(AF_NCH,(float*)arg,s->level,20.0,-200.0,60.0);
103 case AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_GET:
104 return af_to_dB(AF_NCH,s->level,(float*)arg,20.0);
105 case AF_CONTROL_VOLUME_PROBE | AF_CONTROL_GET:
106 return af_to_dB(AF_NCH,s->pow,(float*)arg,10.0);
107 case AF_CONTROL_VOLUME_PROBE_MAX | AF_CONTROL_GET:
108 return af_to_dB(AF_NCH,s->max,(float*)arg,10.0);
109 case AF_CONTROL_PRE_DESTROY:{
110 float m = 0.0;
111 int i;
112 if(!s->fast){
113 for(i=0;i<AF_NCH;i++)
114 m=max(m,s->max[i]);
115 af_to_dB(1, &m, &m, 10.0);
116 af_msg(AF_MSG_INFO,"[volume] The maximum volume was %0.2fdB \n", m);
118 return AF_OK;
121 return AF_UNKNOWN;
124 // Deallocate memory
125 static void uninit(struct af_instance_s* af)
127 if(af->data)
128 free(af->data);
129 if(af->setup)
130 free(af->setup);
133 // Filter data through filter
134 static af_data_t* play(struct af_instance_s* af, af_data_t* data)
136 af_data_t* c = data; // Current working data
137 af_volume_t* s = (af_volume_t*)af->setup; // Setup for this instance
138 int ch = 0; // Channel counter
139 register int nch = c->nch; // Number of channels
140 register int i = 0;
142 // Basic operation volume control only (used on slow machines)
143 if(af->data->format == (AF_FORMAT_S16_NE)){
144 int16_t* a = (int16_t*)c->audio; // Audio data
145 int len = c->len/2; // Number of samples
146 for(ch = 0; ch < nch ; ch++){
147 if(s->enable[ch]){
148 register int vol = (int)(255.0 * s->level[ch]);
149 for(i=ch;i<len;i+=nch){
150 register int x = (a[i] * vol) >> 8;
151 a[i]=clamp(x,SHRT_MIN,SHRT_MAX);
156 // Machine is fast and data is floating point
157 else if(af->data->format == (AF_FORMAT_FLOAT_NE)){
158 float* a = (float*)c->audio; // Audio data
159 int len = c->len/4; // Number of samples
160 for(ch = 0; ch < nch ; ch++){
161 // Volume control (fader)
162 if(s->enable[ch]){
163 float t = 1.0 - s->time;
164 for(i=ch;i<len;i+=nch){
165 register float x = a[i];
166 register float pow = x*x;
167 // Check maximum power value
168 if(pow > s->max[ch])
169 s->max[ch] = pow;
170 // Set volume
171 x *= s->level[ch];
172 // Peak meter
173 pow = x*x;
174 if(pow > s->pow[ch])
175 s->pow[ch] = pow;
176 else
177 s->pow[ch] = t*s->pow[ch] + pow*s->time; // LP filter
178 /* Soft clipping, the sound of a dream, thanks to Jon Wattes
179 post to Musicdsp.org */
180 if(s->soft)
181 x=af_softclip(x);
182 // Hard clipping
183 else
184 x=clamp(x,-1.0,1.0);
185 a[i] = x;
190 return c;
193 // Allocate memory and set function pointers
194 static int open(af_instance_t* af){
195 int i = 0;
196 af->control=control;
197 af->uninit=uninit;
198 af->play=play;
199 af->mul.n=1;
200 af->mul.d=1;
201 af->data=calloc(1,sizeof(af_data_t));
202 af->setup=calloc(1,sizeof(af_volume_t));
203 if(af->data == NULL || af->setup == NULL)
204 return AF_ERROR;
205 // Enable volume control and set initial volume to 0dB.
206 for(i=0;i<AF_NCH;i++){
207 ((af_volume_t*)af->setup)->enable[i] = 1;
208 ((af_volume_t*)af->setup)->level[i] = 1.0;
210 return AF_OK;
213 // Description of this filter
214 af_info_t af_info_volume = {
215 "Volume control audio filter",
216 "volume",
217 "Anders",
219 AF_FLAGS_NOT_REENTRANT,
220 open