summaryrefslogtreecommitdiff
path: root/libavfilter/af_acrossover.c
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2020-11-26 15:36:16 +0100
committerPaul B Mahol <onemda@gmail.com>2020-11-26 15:44:14 +0100
commit68e452c3678d6253e16a8896aa8d376094aa9095 (patch)
tree2bbec7d2301ac2e07a0c5107efb65b74a5a7b040 /libavfilter/af_acrossover.c
parent029cf6a91ceb849f31f575111070a113c53b29ee (diff)
avfilter/af_acrossover: add missing allpass processing
Diffstat (limited to 'libavfilter/af_acrossover.c')
-rw-r--r--libavfilter/af_acrossover.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/libavfilter/af_acrossover.c b/libavfilter/af_acrossover.c
index 11785e017d..4f0dbbcfb3 100644
--- a/libavfilter/af_acrossover.c
+++ b/libavfilter/af_acrossover.c
@@ -47,6 +47,7 @@ typedef struct BiquadContext {
typedef struct CrossoverChannel {
BiquadContext lp[MAX_BANDS][20];
BiquadContext hp[MAX_BANDS][20];
+ BiquadContext ap[MAX_BANDS][MAX_BANDS][20];
} CrossoverChannel;
typedef struct AudioCrossoverContext {
@@ -184,6 +185,26 @@ static void set_hp(BiquadContext *b, double fc, double q, double sr)
b->a2 = -a2 / a0;
}
+static void set_ap(BiquadContext *b, double fc, double q, double sr)
+{
+ double omega = M_PI * fc / sr;
+ double cosine = cos(omega);
+ double alpha = sin(omega) / (2. * q);
+
+ double a0 = 1. + alpha;
+ double a1 = -2. * cosine;
+ double a2 = 1. - alpha;
+ double b0 = a2;
+ double b1 = a1;
+ double b2 = a0;
+
+ b->b0 = b0 / a0;
+ b->b1 = b1 / a0;
+ b->b2 = b2 / a0;
+ b->a1 = -a1 / a0;
+ b->a2 = -a2 / a0;
+}
+
static void calc_q_factors(int order, double *q)
{
double n = order / 2.;
@@ -221,6 +242,9 @@ static int config_input(AVFilterLink *inlink)
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);
+
+ for (int x = 0; x <= s->nb_splits; x++)
+ set_ap(&s->xover[ch].ap[x][band][n], s->splits[band], q[idx], sample_rate);
}
}
}
@@ -314,9 +338,19 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo
biquad_process(lp, dst, lsrc, nb_samples);
}
+
+ for (int aband = band + 1; aband < ctx->nb_outputs; aband++) {
+ for (int f = 0; f < s->filter_count / 2; f++) {
+ const double *src = (const double *)frames[band]->extended_data[ch];
+ double *dst = (double *)frames[band]->extended_data[ch];
+ BiquadContext *ap = &xover->ap[band][aband][f * 2 + (s->filter_count & 1)];
+
+ biquad_process(ap, dst, src, nb_samples);
+ }
+ }
}
- for (int band = 0; band < ctx->nb_outputs && s->filter_count & 1; band++) {
+ for (int band = 0; band < ctx->nb_outputs && (s->filter_count & 1); band++) {
if (band & 1) {
double *dst = (double *)frames[band]->extended_data[ch];