avfilter/af_alimiter: add 3 more options

Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
Paul B Mahol 2015-12-06 14:57:05 +01:00
parent b0669e7ccf
commit 45b451c892
2 changed files with 27 additions and 9 deletions

View File

@ -833,9 +833,14 @@ that the delay it produces is the attack time you set.
The filter accepts the following options:
@table @option
@item level_in
Set input gain. Default is 1.
@item level_out
Set output gain. Default is 1.
@item limit
Don't let signals above this level pass the limiter. The removed amplitude is
added automatically. Default is 1.
Don't let signals above this level pass the limiter. Default is 1.
@item attack
The limiter will reach its attenuation level in this amount of time in
@ -853,6 +858,10 @@ time.
@item asc_level
Select how much the release time is affected by ASC, 0 means nearly no changes
in release time while 1 produces higher release times.
@item level
Auto level output signal. Default is enabled.
This normalizes audio back to 0dB if enabled.
@end table
Depending on picked setting it is recommended to upsample input 2x or 4x times

View File

@ -41,7 +41,10 @@ typedef struct AudioLimiterContext {
double attack;
double release;
double att;
double level_in;
double level_out;
int auto_release;
int auto_level;
double asc;
int asc_c;
int asc_pos;
@ -64,11 +67,14 @@ typedef struct AudioLimiterContext {
#define F AV_OPT_FLAG_FILTERING_PARAM
static const AVOption alimiter_options[] = {
{ "limit", "set limit", OFFSET(limit), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.0625, 1, A|F },
{ "attack", "set attack", OFFSET(attack), AV_OPT_TYPE_DOUBLE, {.dbl=5}, 0.1, 80, A|F },
{ "release", "set release", OFFSET(release), AV_OPT_TYPE_DOUBLE, {.dbl=50}, 1, 8000, A|F },
{ "asc", "enable asc", OFFSET(auto_release), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, A|F },
{ "asc_level", "set asc level", OFFSET(asc_coeff), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 1, A|F },
{ "level_in", "set input level", OFFSET(level_in), AV_OPT_TYPE_DOUBLE, {.dbl=1},.015625, 64, A|F },
{ "level_out", "set output level", OFFSET(level_out), AV_OPT_TYPE_DOUBLE, {.dbl=1},.015625, 64, A|F },
{ "limit", "set limit", OFFSET(limit), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.0625, 1, A|F },
{ "attack", "set attack", OFFSET(attack), AV_OPT_TYPE_DOUBLE, {.dbl=5}, 0.1, 80, A|F },
{ "release", "set release", OFFSET(release), AV_OPT_TYPE_DOUBLE, {.dbl=50}, 1, 8000, A|F },
{ "asc", "enable asc", OFFSET(auto_release), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, A|F },
{ "asc_level", "set asc level", OFFSET(asc_coeff), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 1, A|F },
{ "level", "auto level", OFFSET(auto_level), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, A|F },
{ NULL }
};
@ -118,6 +124,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
const double release = s->release;
const double limit = s->limit;
double *nextdelta = s->nextdelta;
double level = s->auto_level ? 1 / limit : 1;
const double level_out = s->level_out;
const double level_in = s->level_in;
int *nextpos = s->nextpos;
AVFrame *out;
double *buf;
@ -139,7 +148,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
double peak = 0;
for (c = 0; c < channels; c++) {
double sample = src[c];
double sample = src[c] * level_in;
buffer[s->pos + c] = sample;
peak = FFMAX(peak, fabs(sample));
@ -255,7 +264,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
s->delta = 0.;
for (c = 0; c < channels; c++)
dst[c] = av_clipd(dst[c], -limit, limit);
dst[c] = av_clipd(dst[c], -limit, limit) * level * level_out;
s->pos = (s->pos + channels) % buffer_size;
src += channels;