Index: libaf/af_volume.c =================================================================== RCS file: /cvsroot/mplayer/main/libaf/af_volume.c,v retrieving revision 1.15 diff -u -p -r1.15 af_volume.c --- libaf/af_volume.c 31 Jan 2005 11:43:36 -0000 1.15 +++ libaf/af_volume.c 20 Feb 2005 22:10:39 -0000 @@ -43,6 +43,9 @@ typedef struct af_volume_s float max[AF_NCH]; // Max Power level [dB] float level[AF_NCH]; // Gain level for each channel float time; // Forgetting factor for power estimate + int cmin[AF_NCH]; // clip lower bound + int cmax[AF_NCH]; // clip upper bound + int factor[AF_NCH]; // 65536 * scale factor int soft; // Enable/disable soft clipping int fast; // Use fix-point volume control }af_volume_t; @@ -66,6 +69,7 @@ static int control(struct af_instance_s* } else{ // Cutoff set to 10Hz for forgetting factor + s->fast = 0; float x = 2.0*M_PI*15.0/(float)af->data->rate; float t = 2.0-cos(x); s->time = 1.0 - (t - sqrt(t*t - 1)); @@ -99,7 +103,20 @@ static int control(struct af_instance_s* *(int*)arg = s->soft; return AF_OK; case AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_SET: - return af_from_dB(AF_NCH,(float*)arg,s->level,20.0,-200.0,60.0); + if (af_from_dB(AF_NCH,(float*)arg,s->level,20.0,-200.0,60.0) != AF_OK) + return AF_ERROR; + else { + int i; + for (i = 0; i != AF_NCH; i++) { + s->factor[i] = 65536.0 * s->level[i]; + if (s->factor[i]) { + s->cmax[i] = ((SHRT_MAX<<16) + 0x7fff) / s->factor[i]; + s->cmin[i] = -s->cmax[i] + ((SHRT_MAX+SHRT_MIN)<<16) / s->factor[i]; + } else + s->cmax[i] = s->cmin[i] = 0; + } + } + return AF_OK; case AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_GET: return af_to_dB(AF_NCH,s->level,(float*)arg,20.0); case AF_CONTROL_VOLUME_PROBE | AF_CONTROL_GET: @@ -145,10 +162,14 @@ static af_data_t* play(struct af_instanc int len = c->len/2; // Number of samples for(ch = 0; ch < nch ; ch++){ if(s->enable[ch]){ - register int vol = (int)(255.0 * s->level[ch]); + register int vol = s->factor[ch]; + int xmax = s->cmax[ch]; + int xmin = s->cmin[ch]; for(i=ch;i> 8; - a[i]=clamp(x,SHRT_MIN,SHRT_MAX); + int x = a[i]; + x = clamp(x, xmin, xmax); + x = (vol * x + 0x8000) >> 16; + a[i]=x; } } } @@ -192,6 +213,7 @@ static af_data_t* play(struct af_instanc // Allocate memory and set function pointers static int open(af_instance_t* af){ + af_volume_t* s; int i = 0; af->control=control; af->uninit=uninit; @@ -199,13 +221,16 @@ static int open(af_instance_t* af){ af->mul.n=1; af->mul.d=1; af->data=calloc(1,sizeof(af_data_t)); - af->setup=calloc(1,sizeof(af_volume_t)); + af->setup=s=calloc(1,sizeof(af_volume_t)); if(af->data == NULL || af->setup == NULL) return AF_ERROR; // Enable volume control and set initial volume to 0dB. for(i=0;isetup)->enable[i] = 1; - ((af_volume_t*)af->setup)->level[i] = 1.0; + s->enable[i] = 1; + s->level[i] = 1.0; + s->factor[i] = 65536; + s->cmin[i] = SHRT_MIN; + s->cmax[i] = SHRT_MAX; } return AF_OK; } @@ -216,6 +241,6 @@ af_info_t af_info_volume = { "volume", "Anders", "", - AF_FLAGS_NOT_REENTRANT, + 0, open };