From ead9372b404a31ec231796338aed148e63ff3d77 Mon Sep 17 00:00:00 2001 From: anders Date: Wed, 13 Mar 2002 12:32:42 +0000 Subject: [PATCH] Added soft clipping for software volume control git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@5064 b3059339-0415-0410-9bf9-f77b7e298cf2 --- cfg-mplayer.h | 1 + libao2/audio_plugin.h | 6 +++-- libao2/pl_volume.c | 57 ++++++++++++++++++++++++++++++++++--------- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/cfg-mplayer.h b/cfg-mplayer.h index 172b49ff53..46906c4110 100644 --- a/cfg-mplayer.h +++ b/cfg-mplayer.h @@ -112,6 +112,7 @@ struct config ao_plugin_conf[]={ {"fout", &ao_plugin_cfg.pl_resample_fout, CONF_TYPE_INT, CONF_MIN, 0, 0, NULL}, {"volume", &ao_plugin_cfg.pl_volume_volume, CONF_TYPE_INT, CONF_RANGE, 0, 255, NULL}, {"mul", &ao_plugin_cfg.pl_extrastereo_mul, CONF_TYPE_FLOAT, CONF_MIN, 0, 0, NULL}, + {"softclip", &ao_plugin_cfg.pl_volume_softclip, CONF_TYPE_FLAG, 0, 0, 1, NULL}, {NULL, NULL, 0, 0, 0, 0, NULL} }; diff --git a/libao2/audio_plugin.h b/libao2/audio_plugin.h index 4d31c19bf2..2ff06591b5 100644 --- a/libao2/audio_plugin.h +++ b/libao2/audio_plugin.h @@ -37,6 +37,7 @@ typedef struct ao_plugin_cfg_s int pl_resample_fout; // Output frequency from resampling int pl_volume_volume; // Initial volume setting float pl_extrastereo_mul; // Stereo enhancer multiplier + int pl_volume_softclip; // Enable soft clipping } ao_plugin_cfg_t; extern ao_plugin_cfg_t ao_plugin_cfg; @@ -47,8 +48,9 @@ extern ao_plugin_cfg_t ao_plugin_cfg; AFMT_S16_LE, \ 0, \ 48000, \ - 255, \ - 2.5 \ + 101, \ + 2.5, \ + 0 \ }; // This block should not be available in the pl_xxxx files diff --git a/libao2/pl_volume.c b/libao2/pl_volume.c index 8c31cae92f..a6590cce16 100644 --- a/libao2/pl_volume.c +++ b/libao2/pl_volume.c @@ -4,6 +4,14 @@ #define PLUGIN +// Some limits +#define MIN_S16 -32650 +#define MAX_S16 32650 +#define MIN_U8 0 +#define MAX_U8 255 +#define MIN_S8 -128 +#define MAX_S8 127 + #include #include #include @@ -87,7 +95,7 @@ static int init(){ of wether this plugin is in use or not. */ pl_volume.inuse=1; // Tell the world what we are up to - printf("[pl_volume] Software volume control in use.\n"); + printf("[pl_volume] Software volume control in use%s.\n",ao_plugin_cfg.pl_volume_softclip?", soft clipping enabled":""); return 1; } @@ -100,24 +108,54 @@ static void uninit(){ static void reset(){ } +#define SIGN(x) (x>0?1:-1) // processes 'ao_plugin_data.len' bytes of 'data' // called for every block of data static int play(){ register int i=0; + register int vol=pl_volume.volume; // Logarithmic control sounds more natural + vol=(vol*vol*vol)>>12; // Change the volume. switch(pl_volume.format){ case(AFMT_U8):{ register uint8_t* data=(uint8_t*)ao_plugin_data.data; - for(i=0;i> 8) + 128; - } - break; + register int x; + for(i=0;i> 8; + if(x>MAX_S8) + data[i]=MAX_U8; + else if(x> 14)) >> 1) + 128; + else + data[i] = x + 128; + } + } + break; } case(AFMT_S16_LE):{ register int len=ao_plugin_data.len>>1; register int16_t* data=(int16_t*)ao_plugin_data.data; - for(i=0;i>8; + register int x; + for(i=0;i> 8; + if(x>MAX_S16) + data[i]=MAX_S16; + else if(x> 30; + data[i] = (3*x - (int)t) >> 1; + //data[i] = 2*x - SIGN(x)*((x*x)>>15); + } + else + data[i] = x; + } + } break; } default: @@ -126,8 +164,3 @@ static int play(){ return 1; } - - - - -