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
393 393
394 switch (s->format) {394 switch (s->format) {
395 case AV_SAMPLE_FMT_FLTP:395 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
396 for (int ch = 0; ch < s->nb_channels; ch++) {412 for (int ch = 0; ch < s->nb_channels; ch++) {
397 const float *tsrc = (const float *)s->ir[selir]->extended_data[!s->one2many * ch];413 const float *tsrc = (const float *)s->ir[selir]->extended_data[!s->one2many * ch];
398 float *time = (float *)s->norm_ir[selir]->extended_data[ch];414 float *time = (float *)s->norm_ir[selir]->extended_data[ch];
@@ -401,7 +417,7 @@ skip: · 2 unmodified lines
401 for (int i = FFMAX(1, s->length * nb_taps); i < nb_taps; i++)417 for (int i = FFMAX(1, s->length * nb_taps); i < nb_taps; i++)
402 time[i] = 0;418 time[i] = 0;
403 419
404 get_power_float(ctx, s, nb_taps, ch, time);420 ir_scale_float(ctx, s, nb_taps, ch, time, s->ch_gain[ch]);
405 421
406 for (int n = 0; n < s->nb_segments[selir]; n++) {422 for (int n = 0; n < s->nb_segments[selir]; n++) {
407 AudioFIRSegment *seg = &s->seg[selir][n];423 AudioFIRSegment *seg = &s->seg[selir][n];
@@ -417,6 +433,22 @@ skip: · 9 unmodified lines
417 }433 }
418 break;434 break;
419 case AV_SAMPLE_FMT_DBLP:435 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
420 for (int ch = 0; ch < s->nb_channels; ch++) {452 for (int ch = 0; ch < s->nb_channels; ch++) {
421 const double *tsrc = (const double *)s->ir[selir]->extended_data[!s->one2many * ch];453 const double *tsrc = (const double *)s->ir[selir]->extended_data[!s->one2many * ch];
422 double *time = (double *)s->norm_ir[selir]->extended_data[ch];454 double *time = (double *)s->norm_ir[selir]->extended_data[ch];
@@ -425,7 +457,8 @@ skip: · 2 unmodified lines
425 for (int i = FFMAX(1, s->length * nb_taps); i < nb_taps; i++)457 for (int i = FFMAX(1, s->length * nb_taps); i < nb_taps; i++)
426 time[i] = 0;458 time[i] = 0;
427 459
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
429 for (int n = 0; n < s->nb_segments[selir]; n++) {462 for (int n = 0; n < s->nb_segments[selir]; n++) {
430 AudioFIRSegment *seg = &s->seg[selir][n];463 AudioFIRSegment *seg = &s->seg[selir][n];
431 464
@@ -627,8 +660,9 @@ FF_ENABLE_DEPRECATION_WARNINGS · 195 unmodified lines
627 660
628 s->format = outlink->format;661 s->format = outlink->format;
629 s->nb_channels = outlink->ch_layout.nb_channels;662 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));
630 s->loading = av_calloc(ctx->inputs[0]->ch_layout.nb_channels, sizeof(*s->loading));664 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)
632 return AVERROR(ENOMEM);666 return AVERROR(ENOMEM);
633 667
634 s->fadein[0] = ff_get_audio_buffer(outlink, s->min_part_size);668 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
674 AudioFIRContext *s = ctx->priv;708 AudioFIRContext *s = ctx->priv;
675 709
676 av_freep(&s->fdsp);710 av_freep(&s->fdsp);
711 av_freep(&s->ch_gain);
677 av_freep(&s->loading);712 av_freep(&s->loading);
678 713
679 for (int i = 0; i < s->nb_irs; i++) {714 for (int i = 0; i < s->nb_irs; i++) {
@@ -812,13 +847,15 @@ static const AVOption afir_options[] = { · 132 unmodified lines
812 { "dry", "set dry gain", OFFSET(dry_gain), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, AFR },847 { "dry", "set dry gain", OFFSET(dry_gain), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, AFR },
813 { "wet", "set wet gain", OFFSET(wet_gain), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, AFR },848 { "wet", "set wet gain", OFFSET(wet_gain), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, AFR },
814 { "length", "set IR length", OFFSET(length), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, AF },849 { "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" },850 { "gtype", "set IR auto gain type",OFFSET(gtype), AV_OPT_TYPE_INT, {.i64=0}, -1, 4, AF|AV_OPT_FLAG_DEPRECATED, "gtype" },
816 { "none", "without auto gain", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "gtype" },851 { "none", "without auto gain", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF|AV_OPT_FLAG_DEPRECATED, "gtype" },
817 { "peak", "peak gain", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "gtype" },852 { "peak", "peak gain", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF|AV_OPT_FLAG_DEPRECATED, "gtype" },
818 { "dc", "DC gain", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "gtype" },853 { "dc", "DC gain", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF|AV_OPT_FLAG_DEPRECATED, "gtype" },
819 { "gn", "gain to noise", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "gtype" },854 { "gn", "gain to noise", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF|AV_OPT_FLAG_DEPRECATED, "gtype" },
820 { "ac", "AC gain", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "gtype" },855 { "ac", "AC gain", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF|AV_OPT_FLAG_DEPRECATED, "gtype" },
821 { "rms", "RMS gain", 0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, AF, "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 },
822 { "irgain", "set IR gain", OFFSET(ir_gain), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, AF },859 { "irgain", "set IR gain", OFFSET(ir_gain), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, AF },
823 { "irfmt", "set IR format", OFFSET(ir_format), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, AF, "irfmt" },860 { "irfmt", "set IR format", OFFSET(ir_format), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, AF, "irfmt" },
824 { "mono", "single channel", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "irfmt" },861 { "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
63 float dry_gain;63 float dry_gain;
64 float length;64 float length;
65 int gtype;65 int gtype;
66 float ir_norm;
67 float ir_link;
66 float ir_gain;68 float ir_gain;
67 int ir_format;69 int ir_format;
68 int ir_load;70 int ir_load;
@@ -87,6 +89,7 @@ typedef struct AudioFIRContext { · 18 unmodified lines
87 int nb_channels;89 int nb_channels;
88 int one2many;90 int one2many;
89 int *loading;91 int *loading;
92 double *ch_gain;
90 93
91 AudioFIRSegment seg[MAX_IR_STREAMS][1024];94 AudioFIRSegment seg[MAX_IR_STREAMS][1024];
92 95
libavfilter/afir_template.c+27−86
@@ -29,6 +29,8 @@ · 28 unmodified lines
29#undef HYPOT29#undef HYPOT
30#undef SAMPLE_FORMAT30#undef SAMPLE_FORMAT
31#undef TX_TYPE31#undef TX_TYPE
32#undef FABS
33#undef POW
32#if DEPTH == 3234#if DEPTH == 32
33#define SAMPLE_FORMAT float35#define SAMPLE_FORMAT float
34#define SQRT sqrtf36#define SQRT sqrtf
@@ -36,6 +38,8 @@ · 1 unmodified line
36#define ctype AVComplexFloat38#define ctype AVComplexFloat
37#define ftype float39#define ftype float
38#define TX_TYPE AV_TX_FLOAT_RDFT40#define TX_TYPE AV_TX_FLOAT_RDFT
41#define FABS fabsf
42#define POW powf
39#else43#else
40#define SAMPLE_FORMAT double44#define SAMPLE_FORMAT double
41#define SQRT sqrt45#define SQRT sqrt
@@ -43,6 +47,8 @@ · 1 unmodified line
43#define ctype AVComplexDouble47#define ctype AVComplexDouble
44#define ftype double48#define ftype double
45#define TX_TYPE AV_TX_DOUBLE_RDFT49#define TX_TYPE AV_TX_DOUBLE_RDFT
50#define FABS fabs
51#define POW pow
46#endif52#endif
47 53
48#define fn3(a,b) a##_##b54#define fn3(a,b) a##_##b
@@ -139,95 +145,32 @@ end: · 90 unmodified lines
139 av_free(mag);145 av_free(mag);
140}146}
141 147
142static int fn(get_power)(AVFilterContext *ctx, AudioFIRContext *s,148static ftype fn(ir_gain)(AVFilterContext *ctx, AudioFIRContext *s,
143 int cur_nb_taps, int ch,149 int cur_nb_taps, const ftype *time)
144 ftype *time)
145{150{
146 ftype ch_gain = 1;151 ftype ch_gain, sum = 0;
147 152
148 switch (s->gtype) {153 if (s->ir_norm < 0.f) {
149 case -1:
150 ch_gain = 1;154 ch_gain = 1;
151 break;155 } else if (s->ir_norm == 0.f) {
152 case 0:156 for (int i = 0; i < cur_nb_taps; i++)
153 {157 sum += time[i];
154 ftype sum = 0;158 ch_gain = 1. / sum;
155 159 } else {
156 for (int i = 0; i < cur_nb_taps; i++)160 ftype ir_norm = s->ir_norm;
157 sum += FFABS(time[i]);161
158 ch_gain = 1. / sum;162 for (int i = 0; i < cur_nb_taps; i++)
159 }163 sum += POW(FABS(time[i]), ir_norm);
160 break;164 ch_gain = 1. / POW(sum, 1. / ir_norm);
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;
229 }165 }
230 166
167 return ch_gain;
168}
169
170static void fn(ir_scale)(AVFilterContext *ctx, AudioFIRContext *s,
171 int cur_nb_taps, int ch,
172 ftype *time, ftype ch_gain)
173{
231 if (ch_gain != 1. || s->ir_gain != 1.) {174 if (ch_gain != 1. || s->ir_gain != 1.) {
232 ftype gain = ch_gain * s->ir_gain;175 ftype gain = ch_gain * s->ir_gain;
233 176
@@ -238,8 +181,6 @@ static int fn(get_power)(AVFilterContext *ctx, AudioFIRContext *s, · 4 unmodified lines
238 s->fdsp->vector_dmul_scalar(time, time, gain, FFALIGN(cur_nb_taps, 8));181 s->fdsp->vector_dmul_scalar(time, time, gain, FFALIGN(cur_nb_taps, 8));
239#endif182#endif
240 }183 }
241
242 return 0;
243}184}
244 185
245static void fn(convert_channel)(AVFilterContext *ctx, AudioFIRContext *s, int ch,186static 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