mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2025-02-19 11:31:43 +00:00
avfilter/af_acrossover: add even more orders
This commit is contained in:
parent
bc529ea9bc
commit
cc74700a83
@ -523,7 +523,21 @@ The filter accepts the following options:
|
||||
Set split frequencies. Those must be positive and increasing.
|
||||
|
||||
@item order
|
||||
Set filter order, can be @var{2nd}, @var{4th} or @var{8th}.
|
||||
Set filter order. Availabe values are:
|
||||
|
||||
@table @samp
|
||||
@item 2nd
|
||||
@item 4th
|
||||
@item 6th
|
||||
@item 8th
|
||||
@item 10th
|
||||
@item 12th
|
||||
@item 14th
|
||||
@item 16th
|
||||
@item 18th
|
||||
@item 20th
|
||||
@end table
|
||||
|
||||
Default is @var{4th}.
|
||||
@end table
|
||||
|
||||
|
@ -45,8 +45,8 @@ typedef struct BiquadContext {
|
||||
} BiquadContext;
|
||||
|
||||
typedef struct CrossoverChannel {
|
||||
BiquadContext lp[MAX_BANDS][16];
|
||||
BiquadContext hp[MAX_BANDS][16];
|
||||
BiquadContext lp[MAX_BANDS][20];
|
||||
BiquadContext hp[MAX_BANDS][20];
|
||||
} CrossoverChannel;
|
||||
|
||||
typedef struct AudioCrossoverContext {
|
||||
@ -71,12 +71,17 @@ typedef struct AudioCrossoverContext {
|
||||
|
||||
static const AVOption acrossover_options[] = {
|
||||
{ "split", "set split frequencies", OFFSET(splits_str), AV_OPT_TYPE_STRING, {.str="500"}, 0, 0, AF },
|
||||
{ "order", "set order", OFFSET(order_opt), AV_OPT_TYPE_INT, {.i64=1}, 0, 4, AF, "m" },
|
||||
{ "order", "set order", OFFSET(order_opt), AV_OPT_TYPE_INT, {.i64=1}, 0, 9, AF, "m" },
|
||||
{ "2nd", "2nd order", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "m" },
|
||||
{ "4th", "4th order", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "m" },
|
||||
{ "8th", "8th order", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "m" },
|
||||
{ "12th", "12th order", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "m" },
|
||||
{ "16th", "16th order", 0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, AF, "m" },
|
||||
{ "6th", "6th order", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "m" },
|
||||
{ "8th", "8th order", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "m" },
|
||||
{ "10th", "10th order", 0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, AF, "m" },
|
||||
{ "12th", "12th order", 0, AV_OPT_TYPE_CONST, {.i64=5}, 0, 0, AF, "m" },
|
||||
{ "14th", "14th order", 0, AV_OPT_TYPE_CONST, {.i64=6}, 0, 0, AF, "m" },
|
||||
{ "16th", "16th order", 0, AV_OPT_TYPE_CONST, {.i64=7}, 0, 0, AF, "m" },
|
||||
{ "18th", "18th order", 0, AV_OPT_TYPE_CONST, {.i64=8}, 0, 0, AF, "m" },
|
||||
{ "20th", "20th order", 0, AV_OPT_TYPE_CONST, {.i64=9}, 0, 0, AF, "m" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@ -169,12 +174,10 @@ static void set_hp(BiquadContext *b, double fc, double q, double sr)
|
||||
|
||||
static void calc_q_factors(int order, double *q)
|
||||
{
|
||||
int num = 1, den = 4 * order;
|
||||
double n = order / 2.;
|
||||
|
||||
for (int i = 0; i < order; i++) {
|
||||
q[i] = fabs(1. / (2. * cos(num * M_PI / den)));
|
||||
num += 2;
|
||||
}
|
||||
for (int i = 0; i < n / 2; i++)
|
||||
q[i] = 1. / (-2. * cos(M_PI * (2. * (i + 1) + n - 1.) / (2. * n)));
|
||||
}
|
||||
|
||||
static int config_input(AVFilterLink *inlink)
|
||||
@ -182,20 +185,27 @@ static int config_input(AVFilterLink *inlink)
|
||||
AVFilterContext *ctx = inlink->dst;
|
||||
AudioCrossoverContext *s = ctx->priv;
|
||||
int sample_rate = inlink->sample_rate;
|
||||
double q[16] = { 0.5 };
|
||||
int first_order;
|
||||
double q[16];
|
||||
|
||||
s->xover = av_calloc(inlink->channels, sizeof(*s->xover));
|
||||
if (!s->xover)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
s->order = FFMAX(2, s->order_opt * 4);
|
||||
s->order = (s->order_opt + 1) * 2;
|
||||
s->filter_count = s->order / 2;
|
||||
calc_q_factors(s->filter_count / 2, q + (s->order == 2));
|
||||
first_order = s->filter_count & 1;
|
||||
calc_q_factors(s->order, q);
|
||||
|
||||
for (int ch = 0; ch < inlink->channels; ch++) {
|
||||
for (int band = 0; band <= s->nb_splits; band++) {
|
||||
for (int n = 0; n < s->filter_count; n++) {
|
||||
const int idx = (n + (s->order == 2)) / 2;
|
||||
if (first_order) {
|
||||
set_lp(&s->xover[ch].lp[band][0], s->splits[band], 0.5, sample_rate);
|
||||
set_hp(&s->xover[ch].hp[band][0], s->splits[band], 0.5, sample_rate);
|
||||
}
|
||||
|
||||
for (int n = first_order; n < s->filter_count; n++) {
|
||||
const int idx = s->filter_count / 2 - ((n + first_order) / 2 - first_order) - 1;
|
||||
|
||||
set_lp(&s->xover[ch].lp[band][n], s->splits[band], q[idx], sample_rate);
|
||||
set_hp(&s->xover[ch].hp[band][n], s->splits[band], q[idx], sample_rate);
|
||||
|
Loading…
x
Reference in New Issue
Block a user