avfilter/af_asoftclip: add two more useful options for finer filtering
This commit is contained in:
parent
1eb751955e
commit
7e3f20c43c
@ -2454,6 +2454,12 @@ It accepts the following values:
|
|||||||
@item erf
|
@item erf
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
@item threshold
|
||||||
|
Set threshold from where to start clipping. Default value is 0dB or 1.
|
||||||
|
|
||||||
|
@item output
|
||||||
|
Set gain applied to output. Default value is 0dB or 1.
|
||||||
|
|
||||||
@item param
|
@item param
|
||||||
Set additional parameter which controls sigmoid function.
|
Set additional parameter which controls sigmoid function.
|
||||||
|
|
||||||
|
@ -45,6 +45,8 @@ typedef struct ASoftClipContext {
|
|||||||
int type;
|
int type;
|
||||||
int oversample;
|
int oversample;
|
||||||
int64_t delay;
|
int64_t delay;
|
||||||
|
double threshold;
|
||||||
|
double output;
|
||||||
double param;
|
double param;
|
||||||
|
|
||||||
SwrContext *up_ctx;
|
SwrContext *up_ctx;
|
||||||
@ -71,6 +73,8 @@ static const AVOption asoftclip_options[] = {
|
|||||||
{ "quintic", NULL, 0, AV_OPT_TYPE_CONST, {.i64=ASC_QUINTIC},0, 0, A, "types" },
|
{ "quintic", NULL, 0, AV_OPT_TYPE_CONST, {.i64=ASC_QUINTIC},0, 0, A, "types" },
|
||||||
{ "sin", NULL, 0, AV_OPT_TYPE_CONST, {.i64=ASC_SIN}, 0, 0, A, "types" },
|
{ "sin", NULL, 0, AV_OPT_TYPE_CONST, {.i64=ASC_SIN}, 0, 0, A, "types" },
|
||||||
{ "erf", NULL, 0, AV_OPT_TYPE_CONST, {.i64=ASC_ERF}, 0, 0, A, "types" },
|
{ "erf", NULL, 0, AV_OPT_TYPE_CONST, {.i64=ASC_ERF}, 0, 0, A, "types" },
|
||||||
|
{ "threshold", "set softclip threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.000001, 1, A },
|
||||||
|
{ "output", "set softclip output gain", OFFSET(output), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.000001, 16, A },
|
||||||
{ "param", "set softclip parameter", OFFSET(param), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.01, 3, A },
|
{ "param", "set softclip parameter", OFFSET(param), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.01, 3, A },
|
||||||
{ "oversample", "set oversample factor", OFFSET(oversample), AV_OPT_TYPE_INT, {.i64=1}, 1, 32, F },
|
{ "oversample", "set oversample factor", OFFSET(oversample), AV_OPT_TYPE_INT, {.i64=1}, 1, 32, F },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
@ -108,13 +112,14 @@ static int query_formats(AVFilterContext *ctx)
|
|||||||
return ff_set_common_samplerates(ctx, formats);
|
return ff_set_common_samplerates(ctx, formats);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SQR(x) ((x) * (x))
|
|
||||||
|
|
||||||
static void filter_flt(ASoftClipContext *s,
|
static void filter_flt(ASoftClipContext *s,
|
||||||
void **dptr, const void **sptr,
|
void **dptr, const void **sptr,
|
||||||
int nb_samples, int channels,
|
int nb_samples, int channels,
|
||||||
int start, int end)
|
int start, int end)
|
||||||
{
|
{
|
||||||
|
float threshold = s->threshold;
|
||||||
|
float gain = s->output * threshold;
|
||||||
|
float factor = 1.f / threshold;
|
||||||
float param = s->param;
|
float param = s->param;
|
||||||
|
|
||||||
for (int c = start; c < end; c++) {
|
for (int c = start; c < end; c++) {
|
||||||
@ -124,53 +129,73 @@ static void filter_flt(ASoftClipContext *s,
|
|||||||
switch (s->type) {
|
switch (s->type) {
|
||||||
case ASC_HARD:
|
case ASC_HARD:
|
||||||
for (int n = 0; n < nb_samples; n++) {
|
for (int n = 0; n < nb_samples; n++) {
|
||||||
dst[n] = av_clipf(src[n], -1.f, 1.f);
|
dst[n] = av_clipf(src[n] * factor, -1.f, 1.f);
|
||||||
|
dst[n] *= gain;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ASC_TANH:
|
case ASC_TANH:
|
||||||
for (int n = 0; n < nb_samples; n++) {
|
for (int n = 0; n < nb_samples; n++) {
|
||||||
dst[n] = tanhf(src[n] * param);
|
dst[n] = tanhf(src[n] * factor * param);
|
||||||
|
dst[n] *= gain;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ASC_ATAN:
|
case ASC_ATAN:
|
||||||
for (int n = 0; n < nb_samples; n++)
|
for (int n = 0; n < nb_samples; n++) {
|
||||||
dst[n] = 2.f / M_PI * atanf(src[n] * param);
|
dst[n] = 2.f / M_PI * atanf(src[n] * factor * param);
|
||||||
|
dst[n] *= gain;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ASC_CUBIC:
|
case ASC_CUBIC:
|
||||||
for (int n = 0; n < nb_samples; n++) {
|
for (int n = 0; n < nb_samples; n++) {
|
||||||
if (FFABS(src[n]) >= 1.5f)
|
float sample = src[n] * factor;
|
||||||
dst[n] = FFSIGN(src[n]);
|
|
||||||
|
if (FFABS(sample) >= 1.5f)
|
||||||
|
dst[n] = FFSIGN(sample);
|
||||||
else
|
else
|
||||||
dst[n] = src[n] - 0.1481f * powf(src[n], 3.f);
|
dst[n] = sample - 0.1481f * powf(sample, 3.f);
|
||||||
|
dst[n] *= gain;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ASC_EXP:
|
case ASC_EXP:
|
||||||
for (int n = 0; n < nb_samples; n++)
|
for (int n = 0; n < nb_samples; n++) {
|
||||||
dst[n] = 2.f / (1.f + expf(-2.f * src[n])) - 1.;
|
dst[n] = 2.f / (1.f + expf(-2.f * src[n] * factor)) - 1.;
|
||||||
|
dst[n] *= gain;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ASC_ALG:
|
case ASC_ALG:
|
||||||
for (int n = 0; n < nb_samples; n++)
|
for (int n = 0; n < nb_samples; n++) {
|
||||||
dst[n] = src[n] / (sqrtf(param + src[n] * src[n]));
|
float sample = src[n] * factor;
|
||||||
|
|
||||||
|
dst[n] = sample / (sqrtf(param + sample * sample));
|
||||||
|
dst[n] *= gain;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ASC_QUINTIC:
|
case ASC_QUINTIC:
|
||||||
for (int n = 0; n < nb_samples; n++) {
|
for (int n = 0; n < nb_samples; n++) {
|
||||||
if (FFABS(src[n]) >= 1.25)
|
float sample = src[n] * factor;
|
||||||
dst[n] = FFSIGN(src[n]);
|
|
||||||
|
if (FFABS(sample) >= 1.25)
|
||||||
|
dst[n] = FFSIGN(sample);
|
||||||
else
|
else
|
||||||
dst[n] = src[n] - 0.08192f * powf(src[n], 5.f);
|
dst[n] = sample - 0.08192f * powf(sample, 5.f);
|
||||||
|
dst[n] *= gain;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ASC_SIN:
|
case ASC_SIN:
|
||||||
for (int n = 0; n < nb_samples; n++) {
|
for (int n = 0; n < nb_samples; n++) {
|
||||||
if (FFABS(src[n]) >= M_PI_2)
|
float sample = src[n] * factor;
|
||||||
dst[n] = FFSIGN(src[n]);
|
|
||||||
|
if (FFABS(sample) >= M_PI_2)
|
||||||
|
dst[n] = FFSIGN(sample);
|
||||||
else
|
else
|
||||||
dst[n] = sinf(src[n]);
|
dst[n] = sinf(sample);
|
||||||
|
dst[n] *= gain;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ASC_ERF:
|
case ASC_ERF:
|
||||||
for (int n = 0; n < nb_samples; n++) {
|
for (int n = 0; n < nb_samples; n++) {
|
||||||
dst[n] = erff(src[n]);
|
dst[n] = erff(src[n] * factor);
|
||||||
|
dst[n] *= gain;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -184,6 +209,9 @@ static void filter_dbl(ASoftClipContext *s,
|
|||||||
int nb_samples, int channels,
|
int nb_samples, int channels,
|
||||||
int start, int end)
|
int start, int end)
|
||||||
{
|
{
|
||||||
|
double threshold = s->threshold;
|
||||||
|
double gain = s->output * threshold;
|
||||||
|
double factor = 1. / threshold;
|
||||||
double param = s->param;
|
double param = s->param;
|
||||||
|
|
||||||
for (int c = start; c < end; c++) {
|
for (int c = start; c < end; c++) {
|
||||||
@ -193,53 +221,73 @@ static void filter_dbl(ASoftClipContext *s,
|
|||||||
switch (s->type) {
|
switch (s->type) {
|
||||||
case ASC_HARD:
|
case ASC_HARD:
|
||||||
for (int n = 0; n < nb_samples; n++) {
|
for (int n = 0; n < nb_samples; n++) {
|
||||||
dst[n] = av_clipd(src[n], -1., 1.);
|
dst[n] = av_clipd(src[n] * factor, -1., 1.);
|
||||||
|
dst[n] *= gain;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ASC_TANH:
|
case ASC_TANH:
|
||||||
for (int n = 0; n < nb_samples; n++) {
|
for (int n = 0; n < nb_samples; n++) {
|
||||||
dst[n] = tanh(src[n] * param);
|
dst[n] = tanh(src[n] * factor * param);
|
||||||
|
dst[n] *= gain;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ASC_ATAN:
|
case ASC_ATAN:
|
||||||
for (int n = 0; n < nb_samples; n++)
|
for (int n = 0; n < nb_samples; n++) {
|
||||||
dst[n] = 2. / M_PI * atan(src[n] * param);
|
dst[n] = 2. / M_PI * atan(src[n] * factor * param);
|
||||||
|
dst[n] *= gain;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ASC_CUBIC:
|
case ASC_CUBIC:
|
||||||
for (int n = 0; n < nb_samples; n++) {
|
for (int n = 0; n < nb_samples; n++) {
|
||||||
if (FFABS(src[n]) >= 1.5)
|
double sample = src[n] * factor;
|
||||||
dst[n] = FFSIGN(src[n]);
|
|
||||||
|
if (FFABS(sample) >= 1.5)
|
||||||
|
dst[n] = FFSIGN(sample);
|
||||||
else
|
else
|
||||||
dst[n] = src[n] - 0.1481 * pow(src[n], 3.);
|
dst[n] = sample - 0.1481 * pow(sample, 3.);
|
||||||
|
dst[n] *= gain;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ASC_EXP:
|
case ASC_EXP:
|
||||||
for (int n = 0; n < nb_samples; n++)
|
for (int n = 0; n < nb_samples; n++) {
|
||||||
dst[n] = 2. / (1. + exp(-2. * src[n])) - 1.;
|
dst[n] = 2. / (1. + exp(-2. * src[n] * factor)) - 1.;
|
||||||
|
dst[n] *= gain;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ASC_ALG:
|
case ASC_ALG:
|
||||||
for (int n = 0; n < nb_samples; n++)
|
for (int n = 0; n < nb_samples; n++) {
|
||||||
dst[n] = src[n] / (sqrt(param + src[n] * src[n]));
|
double sample = src[n] * factor;
|
||||||
|
|
||||||
|
dst[n] = sample / (sqrt(param + sample * sample));
|
||||||
|
dst[n] *= gain;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ASC_QUINTIC:
|
case ASC_QUINTIC:
|
||||||
for (int n = 0; n < nb_samples; n++) {
|
for (int n = 0; n < nb_samples; n++) {
|
||||||
if (FFABS(src[n]) >= 1.25)
|
double sample = src[n] * factor;
|
||||||
dst[n] = FFSIGN(src[n]);
|
|
||||||
|
if (FFABS(sample) >= 1.25)
|
||||||
|
dst[n] = FFSIGN(sample);
|
||||||
else
|
else
|
||||||
dst[n] = src[n] - 0.08192 * pow(src[n], 5.);
|
dst[n] = sample - 0.08192 * pow(sample, 5.);
|
||||||
|
dst[n] *= gain;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ASC_SIN:
|
case ASC_SIN:
|
||||||
for (int n = 0; n < nb_samples; n++) {
|
for (int n = 0; n < nb_samples; n++) {
|
||||||
if (FFABS(src[n]) >= M_PI_2)
|
double sample = src[n] * factor;
|
||||||
dst[n] = FFSIGN(src[n]);
|
|
||||||
|
if (FFABS(sample) >= M_PI_2)
|
||||||
|
dst[n] = FFSIGN(sample);
|
||||||
else
|
else
|
||||||
dst[n] = sin(src[n]);
|
dst[n] = sin(sample);
|
||||||
|
dst[n] *= gain;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ASC_ERF:
|
case ASC_ERF:
|
||||||
for (int n = 0; n < nb_samples; n++) {
|
for (int n = 0; n < nb_samples; n++) {
|
||||||
dst[n] = erf(src[n]);
|
dst[n] = erf(src[n] * factor);
|
||||||
|
dst[n] *= gain;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user