mirror of
https://github.com/mpv-player/mpv
synced 2025-03-15 03:14:30 +01:00
Added soft clipping for software volume control
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@5064 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
54610a5997
commit
ead9372b40
@ -112,6 +112,7 @@ struct config ao_plugin_conf[]={
|
|||||||
{"fout", &ao_plugin_cfg.pl_resample_fout, CONF_TYPE_INT, CONF_MIN, 0, 0, NULL},
|
{"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},
|
{"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},
|
{"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}
|
{NULL, NULL, 0, 0, 0, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ typedef struct ao_plugin_cfg_s
|
|||||||
int pl_resample_fout; // Output frequency from resampling
|
int pl_resample_fout; // Output frequency from resampling
|
||||||
int pl_volume_volume; // Initial volume setting
|
int pl_volume_volume; // Initial volume setting
|
||||||
float pl_extrastereo_mul; // Stereo enhancer multiplier
|
float pl_extrastereo_mul; // Stereo enhancer multiplier
|
||||||
|
int pl_volume_softclip; // Enable soft clipping
|
||||||
} ao_plugin_cfg_t;
|
} ao_plugin_cfg_t;
|
||||||
|
|
||||||
extern ao_plugin_cfg_t ao_plugin_cfg;
|
extern ao_plugin_cfg_t ao_plugin_cfg;
|
||||||
@ -47,8 +48,9 @@ extern ao_plugin_cfg_t ao_plugin_cfg;
|
|||||||
AFMT_S16_LE, \
|
AFMT_S16_LE, \
|
||||||
0, \
|
0, \
|
||||||
48000, \
|
48000, \
|
||||||
255, \
|
101, \
|
||||||
2.5 \
|
2.5, \
|
||||||
|
0 \
|
||||||
};
|
};
|
||||||
|
|
||||||
// This block should not be available in the pl_xxxx files
|
// This block should not be available in the pl_xxxx files
|
||||||
|
@ -4,6 +4,14 @@
|
|||||||
|
|
||||||
#define PLUGIN
|
#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 <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -87,7 +95,7 @@ static int init(){
|
|||||||
of wether this plugin is in use or not. */
|
of wether this plugin is in use or not. */
|
||||||
pl_volume.inuse=1;
|
pl_volume.inuse=1;
|
||||||
// Tell the world what we are up to
|
// 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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,24 +108,54 @@ static void uninit(){
|
|||||||
static void reset(){
|
static void reset(){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SIGN(x) (x>0?1:-1)
|
||||||
// processes 'ao_plugin_data.len' bytes of 'data'
|
// processes 'ao_plugin_data.len' bytes of 'data'
|
||||||
// called for every block of data
|
// called for every block of data
|
||||||
static int play(){
|
static int play(){
|
||||||
register int i=0;
|
register int i=0;
|
||||||
|
register int vol=pl_volume.volume; // Logarithmic control sounds more natural
|
||||||
|
vol=(vol*vol*vol)>>12;
|
||||||
// Change the volume.
|
// Change the volume.
|
||||||
switch(pl_volume.format){
|
switch(pl_volume.format){
|
||||||
case(AFMT_U8):{
|
case(AFMT_U8):{
|
||||||
register uint8_t* data=(uint8_t*)ao_plugin_data.data;
|
register uint8_t* data=(uint8_t*)ao_plugin_data.data;
|
||||||
|
register int x;
|
||||||
for(i=0;i<ao_plugin_data.len;i++){
|
for(i=0;i<ao_plugin_data.len;i++){
|
||||||
data[i]=(((data[i]-128) * pl_volume.volume) >> 8) + 128;
|
x=((data[i]-128) * vol) >> 8;
|
||||||
|
if(x>MAX_S8)
|
||||||
|
data[i]=MAX_U8;
|
||||||
|
else if(x<MIN_S8)
|
||||||
|
data[i]=MIN_U8;
|
||||||
|
else{
|
||||||
|
if(ao_plugin_cfg.pl_volume_softclip)
|
||||||
|
data[i] = ((3*x - ((x*x*x) >> 14)) >> 1) + 128;
|
||||||
|
else
|
||||||
|
data[i] = x + 128;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(AFMT_S16_LE):{
|
case(AFMT_S16_LE):{
|
||||||
register int len=ao_plugin_data.len>>1;
|
register int len=ao_plugin_data.len>>1;
|
||||||
register int16_t* data=(int16_t*)ao_plugin_data.data;
|
register int16_t* data=(int16_t*)ao_plugin_data.data;
|
||||||
for(i=0;i<len;i++)
|
register int x;
|
||||||
data[i]=(data[i]* pl_volume.volume)>>8;
|
for(i=0;i<len;i++){
|
||||||
|
x=(data[i] * vol) >> 8;
|
||||||
|
if(x>MAX_S16)
|
||||||
|
data[i]=MAX_S16;
|
||||||
|
else if(x<MIN_S16)
|
||||||
|
data[i]=MIN_S16;
|
||||||
|
else{
|
||||||
|
if(ao_plugin_cfg.pl_volume_softclip){
|
||||||
|
int64_t t=x*x;
|
||||||
|
t=(t*x) >> 30;
|
||||||
|
data[i] = (3*x - (int)t) >> 1;
|
||||||
|
//data[i] = 2*x - SIGN(x)*((x*x)>>15);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
data[i] = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -126,8 +164,3 @@ static int play(){
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user