History

avfilter/af_afir: add irnorm and irlink options

Deprecate gtype option.

Paul B Mahol committed 2 years ago

Commit 5452cbd1 parent 07c303b4 files · +91 −119Browse files

Showing the changes to libavfilter (3 of 4 files). Show all

Unified · Split

3 files
  1. libavfilter/af_afir.c +47 −10
  2. libavfilter/af_afir.h +3 −0
  3. libavfilter/afir_template.c +27 −86
libavfilter/af_afir.c+47−10
@@ -393,6 +393,22 @@ skip: · 392 unmodified lines
393393
394394 switch (s->format) {
395395 case AV_SAMPLE_FMT_FLTP:
396+ for (int ch = 0; ch < s->nb_channels; ch++) {
397+ const float *tsrc = (const float *)s->ir[selir]->extended_data[!s->one2many * ch];
398+
399+ s->ch_gain[ch] = ir_gain_float(ctx, s, nb_taps, tsrc);
400+ }
401+
402+ if (s->ir_link) {
403+ float gain = +INFINITY;
404+
405+ for (int ch = 0; ch < s->nb_channels; ch++)
406+ gain = fminf(gain, s->ch_gain[ch]);
407+
408+ for (int ch = 0; ch < s->nb_channels; ch++)
409+ s->ch_gain[ch] = gain;
410+ }
411+
396412 for (int ch = 0; ch < s->nb_channels; ch++) {
397413 const float *tsrc = (const float *)s->ir[selir]->extended_data[!s->one2many * ch];
398414 float *time = (float *)s->norm_ir[selir]->extended_data[ch];
@@ -401,7 +417,7 @@ skip: · 2 unmodified lines
401417 for (int i = FFMAX(1, s->length * nb_taps); i < nb_taps; i++)
402418 time[i] = 0;
403419
404− get_power_float(ctx, s, nb_taps, ch, time);
420+ ir_scale_float(ctx, s, nb_taps, ch, time, s->ch_gain[ch]);
405421
406422 for (int n = 0; n < s->nb_segments[selir]; n++) {
407423 AudioFIRSegment *seg = &s->seg[selir][n];
@@ -417,6 +433,22 @@ skip: · 9 unmodified lines
417433 }
418434 break;
419435 case AV_SAMPLE_FMT_DBLP:
436+ for (int ch = 0; ch < s->nb_channels; ch++) {
437+ const double *tsrc = (const double *)s->ir[selir]->extended_data[!s->one2many * ch];
438+
439+ s->ch_gain[ch] = ir_gain_double(ctx, s, nb_taps, tsrc);
440+ }
441+
442+ if (s->ir_link) {
443+ double gain = +INFINITY;
444+
445+ for (int ch = 0; ch < s->nb_channels; ch++)
446+ gain = fmin(gain, s->ch_gain[ch]);
447+
448+ for (int ch = 0; ch < s->nb_channels; ch++)
449+ s->ch_gain[ch] = gain;
450+ }
451+
420452 for (int ch = 0; ch < s->nb_channels; ch++) {
421453 const double *tsrc = (const double *)s->ir[selir]->extended_data[!s->one2many * ch];
422454 double *time = (double *)s->norm_ir[selir]->extended_data[ch];
@@ -425,7 +457,8 @@ skip: · 2 unmodified lines
425457 for (int i = FFMAX(1, s->length * nb_taps); i < nb_taps; i++)
426458 time[i] = 0;
427459
428− get_power_double(ctx, s, nb_taps, ch, time);
460+ ir_scale_double(ctx, s, nb_taps, ch, time, s->ch_gain[ch]);
461+
429462 for (int n = 0; n < s->nb_segments[selir]; n++) {
430463 AudioFIRSegment *seg = &s->seg[selir][n];
431464
@@ -627,8 +660,9 @@ FF_ENABLE_DEPRECATION_WARNINGS · 195 unmodified lines
627660
628661 s->format = outlink->format;
629662 s->nb_channels = outlink->ch_layout.nb_channels;
663+ s->ch_gain = av_calloc(ctx->inputs[0]->ch_layout.nb_channels, sizeof(*s->ch_gain));
630664 s->loading = av_calloc(ctx->inputs[0]->ch_layout.nb_channels, sizeof(*s->loading));
631− if (!s->loading)
665+ if (!s->loading || !s->ch_gain)
632666 return AVERROR(ENOMEM);
633667
634668 s->fadein[0] = ff_get_audio_buffer(outlink, s->min_part_size);
@@ -674,6 +708,7 @@ static av_cold void uninit(AVFilterContext *ctx) · 39 unmodified lines
674708 AudioFIRContext *s = ctx->priv;
675709
676710 av_freep(&s->fdsp);
711+ av_freep(&s->ch_gain);
677712 av_freep(&s->loading);
678713
679714 for (int i = 0; i < s->nb_irs; i++) {
@@ -812,13 +847,15 @@ static const AVOption afir_options[] = { · 132 unmodified lines
812847 { "dry", "set dry gain", OFFSET(dry_gain), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, AFR },
813848 { "wet", "set wet gain", OFFSET(wet_gain), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, AFR },
814849 { "length", "set IR length", OFFSET(length), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, AF },
815− { "gtype", "set IR auto gain type",OFFSET(gtype), AV_OPT_TYPE_INT, {.i64=0}, -1, 4, AF, "gtype" },
816− { "none", "without auto gain", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "gtype" },
817− { "peak", "peak gain", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "gtype" },
818− { "dc", "DC gain", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "gtype" },
819− { "gn", "gain to noise", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "gtype" },
820− { "ac", "AC gain", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "gtype" },
821− { "rms", "RMS gain", 0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, AF, "gtype" },
850+ { "gtype", "set IR auto gain type",OFFSET(gtype), AV_OPT_TYPE_INT, {.i64=0}, -1, 4, AF|AV_OPT_FLAG_DEPRECATED, "gtype" },
851+ { "none", "without auto gain", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF|AV_OPT_FLAG_DEPRECATED, "gtype" },
852+ { "peak", "peak gain", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF|AV_OPT_FLAG_DEPRECATED, "gtype" },
853+ { "dc", "DC gain", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF|AV_OPT_FLAG_DEPRECATED, "gtype" },
854+ { "gn", "gain to noise", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF|AV_OPT_FLAG_DEPRECATED, "gtype" },
855+ { "ac", "AC gain", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF|AV_OPT_FLAG_DEPRECATED, "gtype" },
856+ { "rms", "RMS gain", 0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, AF|AV_OPT_FLAG_DEPRECATED, "gtype" },
857+ { "irnorm", "set IR norm", OFFSET(ir_norm), AV_OPT_TYPE_FLOAT, {.dbl=1}, -1, 2, AF },
858+ { "irlink", "set IR link", OFFSET(ir_link), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, AF },
822859 { "irgain", "set IR gain", OFFSET(ir_gain), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, AF },
823860 { "irfmt", "set IR format", OFFSET(ir_format), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, AF, "irfmt" },
824861 { "mono", "single channel", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "irfmt" },
libavfilter/af_afir.h+3−0
@@ -63,6 +63,8 @@ typedef struct AudioFIRContext { · 62 unmodified lines
6363 float dry_gain;
6464 float length;
6565 int gtype;
66+ float ir_norm;
67+ float ir_link;
6668 float ir_gain;
6769 int ir_format;
6870 int ir_load;
@@ -87,6 +89,7 @@ typedef struct AudioFIRContext { · 18 unmodified lines
8789 int nb_channels;
8890 int one2many;
8991 int *loading;
92+ double *ch_gain;
9093
9194 AudioFIRSegment seg[MAX_IR_STREAMS][1024];
9295
libavfilter/afir_template.c+27−86
@@ -29,6 +29,8 @@ · 28 unmodified lines
2929 #undef HYPOT
3030 #undef SAMPLE_FORMAT
3131 #undef TX_TYPE
32+#undef FABS
33+#undef POW
3234 #if DEPTH == 32
3335 #define SAMPLE_FORMAT float
3436 #define SQRT sqrtf
@@ -36,6 +38,8 @@ · 1 unmodified line
3638 #define ctype AVComplexFloat
3739 #define ftype float
3840 #define TX_TYPE AV_TX_FLOAT_RDFT
41+#define FABS fabsf
42+#define POW powf
3943 #else
4044 #define SAMPLE_FORMAT double
4145 #define SQRT sqrt
@@ -43,6 +47,8 @@ · 1 unmodified line
4347 #define ctype AVComplexDouble
4448 #define ftype double
4549 #define TX_TYPE AV_TX_DOUBLE_RDFT
50+#define FABS fabs
51+#define POW pow
4652 #endif
4753
4854 #define fn3(a,b) a##_##b
@@ -139,95 +145,32 @@ end: · 90 unmodified lines
139145 av_free(mag);
140146 }
141147
142−static int fn(get_power)(AVFilterContext *ctx, AudioFIRContext *s,
143− int cur_nb_taps, int ch,
144− ftype *time)
148+static ftype fn(ir_gain)(AVFilterContext *ctx, AudioFIRContext *s,
149+ int cur_nb_taps, const ftype *time)
145150 {
146− ftype ch_gain = 1;
151+ ftype ch_gain, sum = 0;
147152
148− switch (s->gtype) {
149− case -1:
153+ if (s->ir_norm < 0.f) {
150154 ch_gain = 1;
151− break;
152− case 0:
153− {
154− ftype sum = 0;
155−
156− for (int i = 0; i < cur_nb_taps; i++)
157− sum += FFABS(time[i]);
158− ch_gain = 1. / sum;
159− }
160− break;
161− case 1:
162− {
163− ftype sum = 0;
164−
165− for (int i = 0; i < cur_nb_taps; i++)
166− sum += time[i];
167− ch_gain = 1. / sum;
168− }
169− break;
170− case 2:
171− {
172− ftype sum = 0;
173−
174− for (int i = 0; i < cur_nb_taps; i++)
175− sum += time[i] * time[i];
176− ch_gain = 1. / SQRT(sum);
177− }
178− break;
179− case 3:
180− case 4:
181− {
182− ftype *inc, *outc, scale, power;
183− AVTXContext *tx;
184− av_tx_fn tx_fn;
185− int ret, size;
186−
187− size = 1 << av_ceil_log2_c(cur_nb_taps);
188− inc = av_calloc(size + 2, sizeof(SAMPLE_FORMAT));
189− outc = av_calloc(size + 2, sizeof(SAMPLE_FORMAT));
190− if (!inc || !outc) {
191− av_free(outc);
192− av_free(inc);
193− break;
194− }
195−
196− scale = 1.;
197− ret = av_tx_init(&tx, &tx_fn, TX_TYPE, 0, size, &scale, 0);
198− if (ret < 0) {
199− av_free(outc);
200− av_free(inc);
201− break;
202− }
203−
204− {
205− memcpy(inc, time, cur_nb_taps * sizeof(SAMPLE_FORMAT));
206− tx_fn(tx, outc, inc, sizeof(SAMPLE_FORMAT));
207−
208− power = 0;
209− if (s->gtype == 3) {
210− for (int i = 0; i < size / 2 + 1; i++)
211− power = FFMAX(power, HYPOT(outc[i * 2], outc[i * 2 + 1]));
212− } else {
213− ftype sum = 0;
214− for (int i = 0; i < size / 2 + 1; i++)
215− sum += HYPOT(outc[i * 2], outc[i * 2 + 1]);
216− power = SQRT(sum / (size / 2 + 1));
217− }
218−
219− ch_gain = 1. / power;
220− }
221−
222− av_tx_uninit(&tx);
223− av_free(outc);
224− av_free(inc);
225− }
226− break;
227− default:
228− return AVERROR_BUG;
155+ } else if (s->ir_norm == 0.f) {
156+ for (int i = 0; i < cur_nb_taps; i++)
157+ sum += time[i];
158+ ch_gain = 1. / sum;
159+ } else {
160+ ftype ir_norm = s->ir_norm;
161+
162+ for (int i = 0; i < cur_nb_taps; i++)
163+ sum += POW(FABS(time[i]), ir_norm);
164+ ch_gain = 1. / POW(sum, 1. / ir_norm);
229165 }
230166
167+ return ch_gain;
168+}
169+
170+static void fn(ir_scale)(AVFilterContext *ctx, AudioFIRContext *s,
171+ int cur_nb_taps, int ch,
172+ ftype *time, ftype ch_gain)
173+{
231174 if (ch_gain != 1. || s->ir_gain != 1.) {
232175 ftype gain = ch_gain * s->ir_gain;
233176
@@ -238,8 +181,6 @@ static int fn(get_power)(AVFilterContext *ctx, AudioFIRContext *s, · 4 unmodified lines
238181 s->fdsp->vector_dmul_scalar(time, time, gain, FFALIGN(cur_nb_taps, 8));
239182 #endif
240183 }
241−
242− return 0;
243184 }
244185
245186 static void fn(convert_channel)(AVFilterContext *ctx, AudioFIRContext *s, int ch,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t