78#define OFFSET(x) offsetof(AudioNEqualizerContext, x)
79#define A AV_OPT_FLAG_AUDIO_PARAM
80#define V AV_OPT_FLAG_VIDEO_PARAM
81#define F AV_OPT_FLAG_FILTERING_PARAM
91 {
"colors",
"set channels curves colors",
OFFSET(colors),
AV_OPT_TYPE_STRING, {.str =
"red|green|blue|yellow|orange|lime|pink|magenta|brown" }, 0, 0,
V|
F },
107 memset(
out->data[0], 0,
s->h *
out->linesize[0]);
110 uint8_t fg[4] = { 0xff, 0xff, 0xff, 0xff };
118 for (
f = 0;
f <
s->w;
f++) {
119 double zr, zi, zr2, zi2;
125 w =
M_PI * (
s->fscale ? pow(
s->w - 1,
f /
s->w) :
f) / (
s->w - 1);
131 for (n = 0; n <
s->nb_filters; n++) {
132 if (
s->filters[n].channel != ch ||
133 s->filters[n].ignore)
142 Hr =
S->b4*(1-8*zr2*zi2) +
S->b2*(zr2-zi2) + zr*(
S->b1+
S->b3*(zr2-3*zi2))+
S->b0;
143 Hi = zi*(
S->b3*(3*zr2-zi2) +
S->b1 + 2*zr*(2*
S->b4*(zr2-zi2) +
S->b2));
144 Hmag *=
hypot(Hr, Hi);
145 Hr =
S->a4*(1-8*zr2*zi2) +
S->a2*(zr2-zi2) + zr*(
S->a1+
S->a3*(zr2-3*zi2))+
S->a0;
146 Hi = zi*(
S->a3*(3*zr2-zi2) +
S->a1 + 2*zr*(2*
S->a4*(zr2-zi2) +
S->a2));
147 Hmag /=
hypot(Hr, Hi);
151 v =
av_clip((1. + -20 * log10(Hmag) /
s->mag) *
s->h / 2, 0,
s->h - 1);
156 for (y = v; y <= prev_v; y++)
159 for (y = prev_v; y <= v; y++)
206 if (
s->draw_curves) {
232 if (
s->draw_curves) {
256 double si,
double g,
double g0,
259 if (c0 == 1 || c0 == -1) {
260 S->b0 = (
g*
g*beta*beta + 2*
g*g0*si*beta + g0*g0)/
D;
261 S->b1 = 2*c0*(
g*
g*beta*beta - g0*g0)/
D;
262 S->b2 = (
g*
g*beta*beta - 2*g0*
g*beta*si + g0*g0)/
D;
267 S->a1 = 2*c0*(beta*beta - 1)/
D;
268 S->a2 = (beta*beta - 2*beta*si + 1)/
D;
272 S->b0 = (
g*
g*beta*beta + 2*
g*g0*si*beta + g0*g0)/
D;
273 S->b1 = -4*c0*(g0*g0 +
g*g0*si*beta)/
D;
274 S->b2 = 2*(g0*g0*(1 + 2*c0*c0) -
g*
g*beta*beta)/
D;
275 S->b3 = -4*c0*(g0*g0 -
g*g0*si*beta)/
D;
276 S->b4 = (
g*
g*beta*beta - 2*
g*g0*si*beta + g0*g0)/
D;
279 S->a1 = -4*c0*(1 + si*beta)/
D;
280 S->a2 = 2*(1 + 2*c0*c0 - beta*beta)/
D;
281 S->a3 = -4*c0*(1 - si*beta)/
D;
282 S->a4 = (beta*beta - 2*si*beta + 1)/
D;
287 int N,
double w0,
double wb,
288 double G,
double Gb,
double G0)
290 double g, c0, g0, beta;
296 if (
G == 0 && G0 == 0) {
297 f->section[0].a0 = 1;
298 f->section[0].b0 = 1;
299 f->section[1].a0 = 1;
300 f->section[1].b0 = 1;
308 epsilon = sqrt((
G *
G - Gb * Gb) / (Gb * Gb - G0 * G0));
310 g0 = pow(G0, 1.0 /
N);
311 beta = pow(epsilon, -1.0 /
N) * tan(wb/2);
314 for (
i = 1;
i <=
L;
i++) {
315 double ui = (2.0 *
i - 1) /
N;
316 double si = sin(
M_PI *
ui / 2.0);
317 double Di = beta * beta + 2 * si * beta + 1;
324 double c,
double tetta_b,
325 double g0,
double si,
double b,
328 if (c0 == 1 || c0 == -1) {
329 S->b0 = (tetta_b*tetta_b*(
b*
b+g0*g0*
c*
c) + 2*g0*
b*si*tetta_b*tetta_b + g0*g0)/
D;
330 S->b1 = 2*c0*(tetta_b*tetta_b*(
b*
b+g0*g0*
c*
c) - g0*g0)/
D;
331 S->b2 = (tetta_b*tetta_b*(
b*
b+g0*g0*
c*
c) - 2*g0*
b*si*tetta_b + g0*g0)/
D;
336 S->a1 = 2*c0*(tetta_b*tetta_b*(
a*
a+
c*
c) - 1)/
D;
337 S->a2 = (tetta_b*tetta_b*(
a*
a+
c*
c) - 2*
a*si*tetta_b + 1)/
D;
341 S->b0 = ((
b*
b + g0*g0*
c*
c)*tetta_b*tetta_b + 2*g0*
b*si*tetta_b + g0*g0)/
D;
342 S->b1 = -4*c0*(g0*g0 + g0*
b*si*tetta_b)/
D;
343 S->b2 = 2*(g0*g0*(1 + 2*c0*c0) - (
b*
b + g0*g0*
c*
c)*tetta_b*tetta_b)/
D;
344 S->b3 = -4*c0*(g0*g0 - g0*
b*si*tetta_b)/
D;
345 S->b4 = ((
b*
b + g0*g0*
c*
c)*tetta_b*tetta_b - 2*g0*
b*si*tetta_b + g0*g0)/
D;
348 S->a1 = -4*c0*(1 +
a*si*tetta_b)/
D;
349 S->a2 = 2*(1 + 2*c0*c0 - (
a*
a +
c*
c)*tetta_b*tetta_b)/
D;
350 S->a3 = -4*c0*(1 -
a*si*tetta_b)/
D;
351 S->a4 = ((
a*
a +
c*
c)*tetta_b*tetta_b - 2*
a*si*tetta_b + 1)/
D;
356 int N,
double w0,
double wb,
357 double G,
double Gb,
double G0)
359 double a,
b, c0, g0, alfa, beta, tetta_b;
365 if (
G == 0 && G0 == 0) {
366 f->section[0].a0 = 1;
367 f->section[0].b0 = 1;
368 f->section[1].a0 = 1;
369 f->section[1].b0 = 1;
377 epsilon = sqrt((
G*
G - Gb*Gb) / (Gb*Gb - G0*G0));
379 alfa = pow(1.0/epsilon + sqrt(1 + 1/(epsilon*epsilon)), 1.0/
N);
380 beta = pow(
G/epsilon + Gb * sqrt(1 + 1/(epsilon*epsilon)), 1.0/
N);
381 a = 0.5 * (alfa - 1.0/alfa);
382 b = 0.5 * (beta - g0*g0*(1/beta));
386 for (
i = 1;
i <=
L;
i++) {
387 double ui = (2.0*
i-1.0)/
N;
388 double ci = cos(
M_PI*
ui/2.0);
389 double si = sin(
M_PI*
ui/2.0);
390 double Di = (
a*
a + ci*ci)*tetta_b*tetta_b + 2.0*
a*si*tetta_b + 1;
397 double c,
double tetta_b,
398 double g,
double si,
double b,
401 if (c0 == 1 || c0 == -1) {
402 S->b0 = (
g*
g*tetta_b*tetta_b + 2*tetta_b*
g*
b*si +
b*
b +
g*
g*
c*
c)/
D;
403 S->b1 = 2*c0*(
g*
g*tetta_b*tetta_b -
b*
b -
g*
g*
c*
c)/
D;
404 S->b2 = (
g*
g*tetta_b*tetta_b - 2*tetta_b*
g*
b*si +
b*
b +
g*
g*
c*
c)/
D;
409 S->a1 = 2*c0*(tetta_b*tetta_b -
a*
a -
c*
c)/
D;
410 S->a2 = (tetta_b*tetta_b - 2*tetta_b*
a*si +
a*
a +
c*
c)/
D;
414 S->b0 = (
g*
g*tetta_b*tetta_b + 2*
g*
b*si*tetta_b +
b*
b +
g*
g*
c*
c)/
D;
415 S->b1 = -4*c0*(
b*
b +
g*
g*
c*
c +
g*
b*si*tetta_b)/
D;
416 S->b2 = 2*((
b*
b +
g*
g*
c*
c)*(1 + 2*c0*c0) -
g*
g*tetta_b*tetta_b)/
D;
417 S->b3 = -4*c0*(
b*
b +
g*
g*
c*
c -
g*
b*si*tetta_b)/
D;
418 S->b4 = (
g*
g*tetta_b*tetta_b - 2*
g*
b*si*tetta_b +
b*
b +
g*
g*
c*
c)/
D;
421 S->a1 = -4*c0*(
a*
a +
c*
c +
a*si*tetta_b)/
D;
422 S->a2 = 2*((
a*
a +
c*
c)*(1 + 2*c0*c0) - tetta_b*tetta_b)/
D;
423 S->a3 = -4*c0*(
a*
a +
c*
c -
a*si*tetta_b)/
D;
424 S->a4 = (tetta_b*tetta_b - 2*
a*si*tetta_b +
a*
a +
c*
c)/
D;
429 int N,
double w0,
double wb,
430 double G,
double Gb,
double G0)
432 double a,
b, c0, tetta_b;
433 double epsilon,
g, eu, ew;
438 if (
G == 0 && G0 == 0) {
439 f->section[0].a0 = 1;
440 f->section[0].b0 = 1;
441 f->section[1].a0 = 1;
442 f->section[1].b0 = 1;
450 epsilon = sqrt((
G*
G - Gb*Gb) / (Gb*Gb - G0*G0));
452 eu = pow(epsilon + sqrt(1 + epsilon*epsilon), 1.0/
N);
453 ew = pow(G0*epsilon + Gb*sqrt(1 + epsilon*epsilon), 1.0/
N);
454 a = (eu - 1.0/eu)/2.0;
455 b = (ew -
g*
g/ew)/2.0;
459 for (
i = 1;
i <=
L;
i++) {
460 double ui = (2.0 *
i - 1.0)/
N;
461 double ci = cos(
M_PI *
ui / 2.0);
462 double si = sin(
M_PI *
ui / 2.0);
463 double Di = tetta_b*tetta_b + 2*
a*si*tetta_b +
a*
a + ci*ci;
475 else if(gain > -6 && gain < 6)
476 bw_gain = gain * 0.5;
489 else if(gain > -6 && gain < 6)
490 bw_gain = gain * 0.9;
503 else if(gain > -6 && gain < 6)
504 bw_gain = gain * 0.3;
518 double w0 =
hz_2_rad(
f->freq, sample_rate);
519 double wb =
hz_2_rad(
f->width, sample_rate);
542 if (
s->nb_filters >=
s->nb_allocated - 1) {
548 memcpy(
filters,
s->filters,
sizeof(*
s->filters) *
s->nb_allocated);
551 s->nb_allocated *= 2;
563 char *saveptr =
NULL;
583 s->filters[
s->nb_filters].type = 0;
584 if (sscanf(
arg,
"c%d f=%lf w=%lf g=%lf t=%d", &
s->filters[
s->nb_filters].channel,
585 &
s->filters[
s->nb_filters].freq,
586 &
s->filters[
s->nb_filters].width,
587 &
s->filters[
s->nb_filters].gain,
588 &
s->filters[
s->nb_filters].type) != 5 &&
589 sscanf(
arg,
"c%d f=%lf w=%lf g=%lf", &
s->filters[
s->nb_filters].channel,
590 &
s->filters[
s->nb_filters].freq,
591 &
s->filters[
s->nb_filters].width,
592 &
s->filters[
s->nb_filters].gain) != 4 ) {
597 if (
s->filters[
s->nb_filters].freq < 0 ||
599 s->filters[
s->nb_filters].ignore = 1;
601 if (
s->filters[
s->nb_filters].channel < 0 ||
603 s->filters[
s->nb_filters].ignore = 1;
617 char *res,
int res_len,
int flags)
623 if (!strcmp(cmd,
"change")) {
624 double freq,
width, gain;
627 if (sscanf(args,
"%d|f=%lf|w=%lf|g=%lf", &
filter, &freq, &
width, &gain) != 4)
636 s->filters[
filter].freq = freq;
638 s->filters[
filter].gain = gain;
654 out+=
S->b1 *
S->num[0] -
S->denum[0] *
S->a1;
655 out+=
S->b2 *
S->num[1] -
S->denum[1] *
S->a2;
656 out+=
S->b3 *
S->num[2] -
S->denum[2] *
S->a3;
657 out+=
S->b4 *
S->num[3] -
S->denum[3] *
S->a4;
659 S->num[3] =
S->num[2];
660 S->num[2] =
S->num[1];
661 S->num[1] =
S->num[0];
664 S->denum[3] =
S->denum[2];
665 S->denum[2] =
S->denum[1];
666 S->denum[1] =
S->denum[0];
686 int jobnr,
int nb_jobs)
693 for (
int i = 0;
i <
s->nb_filters;
i++) {
697 if (
f->gain == 0. ||
f->ignore)
699 if (
f->channel < start ||
721 if (!
ctx->is_disabled)
725 if (
s->draw_curves) {
756 .p.name =
"anequalizer",
757 .p.description =
NULL_IF_CONFIG_SMALL(
"Apply high-order audio parametric multi band equalizer."),
758 .p.priv_class = &anequalizer_class,
static int fn filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static enum AVSampleFormat sample_fmts[]
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
static const AVFilterPad inputs[]
static int config_input(AVFilterLink *inlink)
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
static int config_video(AVFilterLink *outlink)
static double chebyshev2_compute_bw_gain_db(double gain)
static int config_video(AVFilterLink *outlink)
static double section_process(FoSection *S, double in)
static void chebyshev1_fo_section(FoSection *S, double a, double c, double tetta_b, double g0, double si, double b, double D, double c0)
static void chebyshev2_bp_filter(EqualizatorFilter *f, int N, double w0, double wb, double G, double Gb, double G0)
static void chebyshev2_fo_section(FoSection *S, double a, double c, double tetta_b, double g, double si, double b, double D, double c0)
static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int config_input(AVFilterLink *inlink)
static double process_sample(FoSection *s1, double in)
static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
static void chebyshev1_bp_filter(EqualizatorFilter *f, int N, double w0, double wb, double G, double Gb, double G0)
static double butterworth_compute_bw_gain_db(double gain)
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
static void butterworth_fo_section(FoSection *S, double beta, double si, double g, double g0, double D, double c0)
static av_cold void uninit(AVFilterContext *ctx)
static void butterworth_bp_filter(EqualizatorFilter *f, int N, double w0, double wb, double G, double Gb, double G0)
static void draw_curves(AVFilterContext *ctx, AVFilterLink *inlink, AVFrame *out)
const FFFilter ff_af_anequalizer
static int add_filter(AudioNEqualizerContext *s, AVFilterLink *inlink)
static double chebyshev1_compute_bw_gain_db(double gain)
static double hz_2_rad(double x, double fs)
static const AVOption anequalizer_options[]
#define filters(fmt, type, inverse, clp, inverset, clip, one, clip_fn, packed)
int ff_append_outpad(AVFilterContext *f, AVFilterPad *p)
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Main libavfilter public API header.
#define flags(name, subs,...)
#define i(width, name, range_min, range_max)
#define fs(width, name, subs,...)
static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
int(* init)(AVBSFContext *ctx)
internal math functions header
static av_always_inline double ff_exp10(double x)
Compute 10^x for floating point values.
@ AV_OPT_TYPE_IMAGE_SIZE
Underlying C type is two consecutive integers.
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
@ AV_OPT_TYPE_INT
Underlying C type is int.
@ AV_OPT_TYPE_DOUBLE
Underlying C type is double.
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
#define AVFILTER_FLAG_DYNAMIC_OUTPUTS
The number of the filter outputs is not determined just by AVFilter.outputs.
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
#define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
Same as AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, except that the filter will have its filter_frame() c...
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
AVSampleFormat
Audio sample formats.
@ AV_SAMPLE_FMT_DBLP
double, planar
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok().
static av_cold void uninit(AVBitStreamFilterContext *ctx)
#define FILTER_INPUTS(array)
static int ff_slice_pos(int total, int jobnr, int nb_jobs)
Compute the boundary index for a slice when work of size total is split into nb_jobs slices.
#define AVFILTERPAD_FLAG_NEEDS_WRITABLE
The filter expects writable frames from its input link, duplicating data buffers if needed.
#define AVFILTER_DEFINE_CLASS(fname)
#define FILTER_QUERY_FUNC2(func)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static enum AVPixelFormat pix_fmts[]
static av_const double hypot(double x, double y)
void * av_calloc(size_t nmemb, size_t size)
Memory handling functions.
int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen, void *log_ctx)
Put the RGBA values that correspond to color_string in rgba_color.
AVPixelFormat
Pixel format.
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
int nb_channels
Number of channels in this layout.
Describe the class of an AVClass context structure.
A link between two filters.
int w
agreed upon image width
int h
agreed upon image height
AVFilterContext * src
source filter
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link.
int sample_rate
samples per second
AVChannelLayout ch_layout
channel layout of current buffer (see libavutil/channel_layout.h)
AVRational sample_aspect_ratio
agreed upon sample aspect ratio
AVFilterContext * dst
dest filter
A filter pad used for either input or output.
This structure describes decoded (raw) audio or video data.
int nb_samples
number of audio samples (per channel) described by this frame
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
AVChannelLayout ch_layout
Channel layout of the audio data.
uint8_t ** extended_data
pointers to the data planes/channels.
Rational number (pair of numerator and denominator).
EqualizatorFilter * filters
void(* filter)(uint8_t *src, ptrdiff_t stride, int qscale)
static AVFormatContext * ctx
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.