mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-27 21:40:34 +00:00
avfilter/firequalizer: add cubic_interpolate function on gain
smoother version of gain_interpolate Signed-off-by: Muhammad Faiz <mfcc64@gmail.com>
This commit is contained in:
parent
0ad71ed6f9
commit
23b6f880d6
@ -2508,6 +2508,8 @@ and functions:
|
||||
@table @option
|
||||
@item gain_interpolate(f)
|
||||
interpolate gain on frequency f based on gain_entry
|
||||
@item cubic_interpolate(f)
|
||||
same as gain_interpolate, but smoother
|
||||
@end table
|
||||
This option is also available as command. Default is @code{gain_interpolate(f)}.
|
||||
|
||||
|
@ -354,6 +354,51 @@ static double gain_interpolate_func(void *p, double freq)
|
||||
return res[0].gain;
|
||||
}
|
||||
|
||||
static double cubic_interpolate_func(void *p, double freq)
|
||||
{
|
||||
AVFilterContext *ctx = p;
|
||||
FIREqualizerContext *s = ctx->priv;
|
||||
GainEntry *res;
|
||||
double x, x2, x3;
|
||||
double a, b, c, d;
|
||||
double m0, m1, m2, msum, unit;
|
||||
|
||||
if (!s->nb_gain_entry)
|
||||
return 0;
|
||||
|
||||
if (freq <= s->gain_entry_tbl[0].freq)
|
||||
return s->gain_entry_tbl[0].gain;
|
||||
|
||||
if (freq >= s->gain_entry_tbl[s->nb_gain_entry-1].freq)
|
||||
return s->gain_entry_tbl[s->nb_gain_entry-1].gain;
|
||||
|
||||
res = bsearch(&freq, &s->gain_entry_tbl, s->nb_gain_entry - 1, sizeof(*res), gain_entry_compare);
|
||||
av_assert0(res);
|
||||
|
||||
unit = res[1].freq - res[0].freq;
|
||||
m0 = res != s->gain_entry_tbl ?
|
||||
unit * (res[0].gain - res[-1].gain) / (res[0].freq - res[-1].freq) : 0;
|
||||
m1 = res[1].gain - res[0].gain;
|
||||
m2 = res != s->gain_entry_tbl + s->nb_gain_entry - 2 ?
|
||||
unit * (res[2].gain - res[1].gain) / (res[2].freq - res[1].freq) : 0;
|
||||
|
||||
msum = fabs(m0) + fabs(m1);
|
||||
m0 = msum > 0 ? (fabs(m0) * m1 + fabs(m1) * m0) / msum : 0;
|
||||
msum = fabs(m1) + fabs(m2);
|
||||
m1 = msum > 0 ? (fabs(m1) * m2 + fabs(m2) * m1) / msum : 0;
|
||||
|
||||
d = res[0].gain;
|
||||
c = m0;
|
||||
b = 3 * res[1].gain - m1 - 2 * c - 3 * d;
|
||||
a = res[1].gain - b - c - d;
|
||||
|
||||
x = (freq - res[0].freq) / unit;
|
||||
x2 = x * x;
|
||||
x3 = x2 * x;
|
||||
|
||||
return a * x3 + b * x2 + c * x + d;
|
||||
}
|
||||
|
||||
static const char *const var_names[] = {
|
||||
"f",
|
||||
"sr",
|
||||
@ -379,9 +424,9 @@ static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *g
|
||||
FIREqualizerContext *s = ctx->priv;
|
||||
AVFilterLink *inlink = ctx->inputs[0];
|
||||
const char *gain_entry_func_names[] = { "entry", NULL };
|
||||
const char *gain_func_names[] = { "gain_interpolate", NULL };
|
||||
const char *gain_func_names[] = { "gain_interpolate", "cubic_interpolate", NULL };
|
||||
double (*gain_entry_funcs[])(void *, double, double) = { entry_func, NULL };
|
||||
double (*gain_funcs[])(void *, double) = { gain_interpolate_func, NULL };
|
||||
double (*gain_funcs[])(void *, double) = { gain_interpolate_func, cubic_interpolate_func, NULL };
|
||||
double vars[VAR_NB];
|
||||
AVExpr *gain_expr;
|
||||
int ret, k, center, ch;
|
||||
|
Loading…
Reference in New Issue
Block a user