[Mplayer-cvslog] CVS: main/libao2 pl_volnorm.c,NONE,1.1 Makefile,1.20,1.21 audio_plugin.h,1.8,1.9

pl pl at mplayer.dev.hu
Tue Mar 5 10:17:38 CET 2002


Update of /cvsroot/mplayer/main/libao2
In directory mplayer:/var/tmp.root/cvs-serv11135

Modified Files:
	Makefile audio_plugin.h 
Added Files:
	pl_volnorm.c 
Log Message:
volume normalizer plugin support


--- NEW FILE ---
/* Normalizer plugin
 *
 * Limitations:
 *  - only AFMT_S16_LE supported
 *  - no parameters yet => tweak the values by editing the #defines
 *
 * License: GPLv2
 * Author: pl <p_l at gmx.fr> (c) 2002 and beyond...
 *
 * Sources: some ideas from volnorm for xmms
 *
 * */

#define PLUGIN

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <math.h>	// for sqrt()

#include "audio_out.h"
#include "audio_plugin.h"
#include "audio_plugin_internal.h"
#include "afmt.h"

static ao_info_t info = {
        "Volume normalizer",
        "volnorm",
        "pl <p_l at gmx.fr>",
        ""
};

LIBAO_PLUGIN_EXTERN(volnorm)

// mul is the value by which the samples are scaled
// and has to be in [MUL_MIN, MUL_MAX]
#define MUL_INIT 1.0
#define MUL_MIN 0.1
#define MUL_MAX 15.0
static float mul;

// "history" value of the filter
static float lastavg;

// SMOOTH_* must be in ]0.0, 1.0[
// The new value accounts for SMOOTH_MUL in the value and history
#define SMOOTH_MUL 0.06
#define SMOOTH_LASTAVG 0.06

// ideal average level
#define MID_S16 (INT16_MAX * 0.25)

// silence level
#define SIL_S16 (INT16_MAX * 0.02)

// local data
static struct {
  int      inuse;     	// This plugin is in use TRUE, FALSE
  int      format;	// sample fomat
} pl_volnorm = {0, 0};


// minimal interface
static int control(int cmd,int arg){
  switch(cmd){
  case AOCONTROL_PLUGIN_SET_LEN:
    return CONTROL_OK;
  }
  return CONTROL_UNKNOWN;
}

// minimal interface
// open & setup audio device
// return: 1=success 0=fail
static int init(){
  switch(ao_plugin_data.format){
    case(AFMT_S16_LE):
      break;
    default:
      fprintf(stderr,"[pl_volnorm] Audio format not yet supported.\n");
      return 0;
  }

  pl_volnorm.format = ao_plugin_data.format;
  pl_volnorm.inuse = 1;

  reset();

  printf("[pl_volnorm] Normalizer plugin in use.\n");
  return 1;
}

// close plugin
static void uninit(){
  pl_volnorm.inuse=0;
}

// empty buffers
static void reset(){
  mul = MUL_INIT;
  switch(ao_plugin_data.format) {
    case(AFMT_S16_LE):
      lastavg = MID_S16;
      break;
    default:
      fprintf(stderr,"[pl_volnorm] internal inconsistency - please bugreport.\n");
      *(char *) 0 = 0;
  }
}

// processes 'ao_plugin_data.len' bytes of 'data'
// called for every block of data
static int play(){

  switch(pl_volnorm.format){
  case(AFMT_S16_LE): {

#define CLAMP(x,m,M) do { if ((x)<(m)) (x) = (m); else if ((x)>(M)) (x) = (M); } while(0)

    int16_t* data=(int16_t*)ao_plugin_data.data;
    int len=ao_plugin_data.len / 2; // 16 bits samples

    int32_t i;
    register int32_t tmp;
    register float curavg;
    float newavg;
    float neededmul;

    // average of the current samples
    curavg = 0.0;
    for (i = 0; i < len ; ++i) {
      tmp = data[i];
      curavg += tmp * tmp;
    }
    curavg = sqrt(curavg / (float) len);

    if (curavg > SIL_S16) {
      neededmul = MID_S16 / ( curavg * mul);
      mul = (1.0 - SMOOTH_MUL) * mul + SMOOTH_MUL * neededmul;

      // Clamp the mul coefficient
      CLAMP(mul, MUL_MIN, MUL_MAX);
    }

    // Scale & clamp the samples
    for (i=0; i < len ; ++i) {
      tmp = data[i] * mul;
      CLAMP(tmp, INT16_MIN, INT16_MAX);
      data[i] = tmp;
    }

    // Evaluation of newavg (not 100% accurate because of values clamping)
    newavg = mul * curavg;

#if 0
    printf("time = %d len = %d curavg = %6.0f lastavg = %6.0f newavg = %6.0f\n"
           " needed_m = %2.2f m = %2.2f\n\n",
            time(NULL), len, curavg, lastavg, newavg, neededmul, mul);
#endif

    lastavg = (1.0 - SMOOTH_LASTAVG) * lastavg + SMOOTH_LASTAVG * newavg;

    break;
  }
  default:
    return 0;
  }
  return 1;

}


Index: Makefile
===================================================================
RCS file: /cvsroot/mplayer/main/libao2/Makefile,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- Makefile	3 Mar 2002 14:17:53 -0000	1.20
+++ Makefile	5 Mar 2002 09:17:36 -0000	1.21
@@ -4,7 +4,7 @@
 LIBNAME = libao2.a
 
 # TODO: moveout ao_sdl.c so it's only used when SDL is detected
-SRCS=afmt.c audio_out.c ao_mpegpes.c ao_null.c ao_pcm.c ao_plugin.c pl_delay.c pl_format.c pl_surround.c remez.c pl_resample.c pl_volume.c pl_extrastereo.c $(OPTIONAL_SRCS)
+SRCS=afmt.c audio_out.c ao_mpegpes.c ao_null.c ao_pcm.c ao_plugin.c pl_delay.c pl_format.c pl_surround.c remez.c pl_resample.c pl_volume.c pl_extrastereo.c pl_volnorm.c $(OPTIONAL_SRCS)
 
 OBJS=$(SRCS:.c=.o)
 

Index: audio_plugin.h
===================================================================
RCS file: /cvsroot/mplayer/main/libao2/audio_plugin.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- audio_plugin.h	3 Mar 2002 14:17:53 -0000	1.8
+++ audio_plugin.h	5 Mar 2002 09:17:36 -0000	1.9
@@ -54,7 +54,7 @@
 // This block should not be available in the pl_xxxx files
 // due to compilation issues
 #ifndef PLUGIN
-#define NPL 6+1 // Number of PLugins ( +1 list ends with NULL )
+#define NPL 7+1 // Number of PLugins ( +1 list ends with NULL )
 // List of plugins 
 extern ao_plugin_functions_t audio_plugin_delay;
 extern ao_plugin_functions_t audio_plugin_format; 
@@ -62,6 +62,7 @@
 extern ao_plugin_functions_t audio_plugin_resample;
 extern ao_plugin_functions_t audio_plugin_volume;
 extern ao_plugin_functions_t audio_plugin_extrastereo;
+extern ao_plugin_functions_t audio_plugin_volnorm;
 
 
 #define AO_PLUGINS { \
@@ -71,6 +72,7 @@
    &audio_plugin_resample, \
    &audio_plugin_volume, \
    &audio_plugin_extrastereo, \
+   &audio_plugin_volnorm, \
    NULL \
 }
 #endif /* PLUGIN */




More information about the MPlayer-cvslog mailing list