58 for (
int i = 0;
i < n / 2;
i++)
59 q[
i] = 1. / (-2. * cos(
M_PI * (2. * (
i + 1) + n - 1.) / (2. * n)));
67 double K = tan(
M_PI * w0);
70 s->bypass = w0 >= 0.5;
74 if (!strcmp(
ctx->filter->name,
"asubcut")) {
75 s->filter_count =
s->order / 2 + (
s->order & 1);
81 double omega = 2. * tan(
M_PI * w0);
83 coeffs->
b0 = 2. / (2. + omega);
84 coeffs->
b1 = -coeffs->
b0;
86 coeffs->
a1 = -(omega - 2.) / (2. + omega);
90 for (
int b = (
s->order & 1);
b < s->filter_count;
b++) {
92 const int idx =
b - (
s->order & 1);
93 double norm = 1.0 / (1.0 +
K / q[idx] +
K *
K);
96 coeffs->
b1 = -2.0 * coeffs->
b0;
97 coeffs->
b2 = coeffs->
b0;
98 coeffs->
a1 = -2.0 * (
K *
K - 1.0) * norm;
99 coeffs->
a2 = -(1.0 -
K / q[idx] +
K *
K) * norm;
101 }
else if (!strcmp(
ctx->filter->name,
"asupercut")) {
102 s->filter_count =
s->order / 2 + (
s->order & 1);
108 double omega = 2. * tan(
M_PI * w0);
110 coeffs->
b0 = omega / (2. + omega);
111 coeffs->
b1 = coeffs->
b0;
113 coeffs->
a1 = -(omega - 2.) / (2. + omega);
117 for (
int b = (
s->order & 1);
b < s->filter_count;
b++) {
119 const int idx =
b - (
s->order & 1);
120 double norm = 1.0 / (1.0 +
K / q[idx] +
K *
K);
122 coeffs->
b0 =
K *
K * norm;
123 coeffs->
b1 = 2.0 * coeffs->
b0;
124 coeffs->
b2 = coeffs->
b0;
125 coeffs->
a1 = -2.0 * (
K *
K - 1.0) * norm;
126 coeffs->
a2 = -(1.0 -
K / q[idx] +
K *
K) * norm;
128 }
else if (!strcmp(
ctx->filter->name,
"asuperpass")) {
129 double alpha, beta, gamma, theta;
133 s->filter_count =
s->order / 2;
134 d_E = (2. * tan(theta_0 / (2. *
s->qfactor))) / sin(theta_0);
136 for (
int b = 0;
b <
s->filter_count;
b += 2) {
137 double D = 2. * sin(((
b + 1) *
M_PI) / (2. *
s->filter_count));
138 double A = (1. + pow((d_E / 2.), 2)) / (
D * d_E / 2.);
139 double d = sqrt((d_E *
D) / (
A + sqrt(
A *
A - 1.)));
140 double B =
D * (d_E / 2.) / d;
141 double W =
B + sqrt(
B *
B - 1.);
143 for (
int j = 0; j < 2; j++) {
147 theta = 2. * atan(tan(theta_0 / 2.) /
W);
149 theta = 2. * atan(
W * tan(theta_0 / 2.));
151 beta = 0.5 * ((1. - (d / 2.) * sin(theta)) / (1. + (d / 2.) * sin(theta)));
152 gamma = (0.5 + beta) * cos(theta);
153 alpha = 0.5 * (0.5 - beta) * sqrt(1. + pow((
W - (1. /
W)) / d, 2.));
155 coeffs->
a1 = 2. * gamma;
156 coeffs->
a2 = -2. * beta;
162 }
else if (!strcmp(
ctx->filter->name,
"asuperstop")) {
163 double alpha, beta, gamma, theta;
167 s->filter_count =
s->order / 2;
168 d_E = (2. * tan(theta_0 / (2. *
s->qfactor))) / sin(theta_0);
170 for (
int b = 0;
b <
s->filter_count;
b += 2) {
171 double D = 2. * sin(((
b + 1) *
M_PI) / (2. *
s->filter_count));
172 double A = (1. + pow((d_E / 2.), 2)) / (
D * d_E / 2.);
173 double d = sqrt((d_E *
D) / (
A + sqrt(
A *
A - 1.)));
174 double B =
D * (d_E / 2.) / d;
175 double W =
B + sqrt(
B *
B - 1.);
177 for (
int j = 0; j < 2; j++) {
181 theta = 2. * atan(tan(theta_0 / 2.) /
W);
183 theta = 2. * atan(
W * tan(theta_0 / 2.));
185 beta = 0.5 * ((1. - (d / 2.) * sin(theta)) / (1. + (d / 2.) * sin(theta)));
186 gamma = (0.5 + beta) * cos(theta);
187 alpha = 0.5 * (0.5 + beta) * ((1. - cos(theta)) / (1. - cos(theta_0)));
189 coeffs->
a1 = 2. * gamma;
190 coeffs->
a2 = -2. * beta;
192 coeffs->
b1 = -4. *
alpha * cos(theta_0);
205#define FILTER(name, type) \
206static int filter_channels_## name(AVFilterContext *ctx, void *arg, \
207 int jobnr, int nb_jobs) \
209 ASuperCutContext *s = ctx->priv; \
210 ThreadData *td = arg; \
211 AVFrame *out = td->out; \
212 AVFrame *in = td->in; \
213 const int start = ff_slice_pos(in->ch_layout.nb_channels, jobnr, nb_jobs); \
214 const int end = ff_slice_pos(in->ch_layout.nb_channels, jobnr + 1, nb_jobs); \
215 const double level = s->level; \
217 for (int ch = start; ch < end; ch++) { \
218 const type *src = (const type *)in->extended_data[ch]; \
219 type *dst = (type *)out->extended_data[ch]; \
221 for (int b = 0; b < s->filter_count; b++) { \
222 BiquadCoeffs *coeffs = &s->coeffs[b]; \
223 const type a1 = coeffs->a1; \
224 const type a2 = coeffs->a2; \
225 const type b0 = coeffs->b0; \
226 const type b1 = coeffs->b1; \
227 const type b2 = coeffs->b2; \
228 type *w = ((type *)s->w->extended_data[ch]) + b * 2; \
230 for (int n = 0; n < in->nb_samples; n++) { \
231 type sin = b ? dst[n] : src[n] * level; \
232 type sout = sin * b0 + w[0]; \
234 w[0] = b1 * sin + w[1] + a1 * sout; \
235 w[1] = b2 * sin + a2 * sout; \
253 switch (inlink->format) {
254 case AV_SAMPLE_FMT_FLTP: s->filter_channels = filter_channels_fltp; break;
255 case AV_SAMPLE_FMT_DBLP: s->filter_channels = filter_channels_dblp; break;
297 char *res,
int res_len,
int flags)
315#define OFFSET(x) offsetof(ASuperCutContext, x)
316#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
337 .p.name =
"asupercut",
339 .p.priv_class = &asupercut_class,
362 .p.priv_class = &asubcut_class,
385 .p.name =
"asuperpass",
387 .p.priv_class = &asuperpass_asuperstop_class,
399 .p.name =
"asuperstop",
401 .p.priv_class = &asuperpass_asuperstop_class,
static enum AVSampleFormat sample_fmts[]
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 get_coeffs(AVFilterContext *ctx)
const FFFilter ff_af_asuperstop
static void calc_q_factors(int n, double *q)
static const AVOption asuperpass_asuperstop_options[]
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
#define FILTER(name, type)
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
static const AVOption asubcut_options[]
static av_cold void uninit(AVFilterContext *ctx)
const FFFilter ff_af_asupercut
const FFFilter ff_af_asuperpass
const FFFilter ff_af_asubcut
static const AVOption asupercut_options[]
const AVFilterPad ff_audio_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_AUDIO.
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
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)
Public libavutil channel layout APIs header.
static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
internal math functions header
@ AV_OPT_TYPE_INT
Underlying C type is int.
@ AV_OPT_TYPE_DOUBLE
Underlying C type is double.
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
AVSampleFormat
Audio sample formats.
@ AV_SAMPLE_FMT_FLTP
float, planar
@ AV_SAMPLE_FMT_DBLP
double, planar
static const int16_t alpha[]
static av_cold void uninit(AVBitStreamFilterContext *ctx)
#define FILTER_INPUTS(array)
#define FILTER_SAMPLEFMTS_ARRAY(array)
#define FILTER_OUTPUTS(array)
#define AVFILTER_DEFINE_CLASS_EXT(name, desc, options)
#define AVFILTER_DEFINE_CLASS(fname)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
int(* filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
int nb_channels
Number of channels in this layout.
Describe the class of an AVClass context structure.
A link between two filters.
int sample_rate
samples per second
AVChannelLayout ch_layout
channel layout of current buffer (see libavutil/channel_layout.h)
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
Used for passing data between threads.
static AVFormatContext * ctx