History

avfilter/firequalizer: add dumpfile and dumpscale option

Muhammad Faiz committed 10 years ago

Commit d3be1861 parent acd74f92 files · +90 −14Browse files

Unified · Split

2 files
  1. doc/filters.texi +7 −0
  2. libavfilter/af_firequalizer.c +83 −14
doc/filters.texi+7−0
@@ -2576,6 +2576,13 @@ logarithmic (in octave scale where 20 Hz is 0) frequency, linear gain · 2575 unmodified lines
2576@item loglog2576@item loglog
2577logarithmic frequency, logarithmic gain2577logarithmic frequency, logarithmic gain
2578@end table2578@end table
2579
2580@item dumpfile
2581Set file for dumping, suitable for gnuplot.
2582
2583@item dumpscale
2584Set scale for dumpfile. Acceptable values are same with scale option.
2585Default is linlog.
2579@end table2586@end table
2580 2587
2581@subsection Examples2588@subsection Examples
libavfilter/af_firequalizer.c+83−14
@@ -65,6 +65,7 @@ typedef struct { · 64 unmodified lines
65typedef struct {65typedef struct {
66 const AVClass *class;66 const AVClass *class;
67 67
68 RDFTContext *analysis_rdft;
68 RDFTContext *analysis_irdft;69 RDFTContext *analysis_irdft;
69 RDFTContext *rdft;70 RDFTContext *rdft;
70 RDFTContext *irdft;71 RDFTContext *irdft;
@@ -72,6 +73,7 @@ typedef struct { · 1 unmodified line
72 int rdft_len;73 int rdft_len;
73 74
74 float *analysis_buf;75 float *analysis_buf;
76 float *dump_buf;
75 float *kernel_tmp_buf;77 float *kernel_tmp_buf;
76 float *kernel_buf;78 float *kernel_buf;
77 float *conv_buf;79 float *conv_buf;
@@ -93,6 +95,8 @@ typedef struct { · 15 unmodified lines
93 int multi;95 int multi;
94 int zero_phase;96 int zero_phase;
95 int scale;97 int scale;
98 char *dumpfile;
99 int dumpscale;
96 100
97 int nb_gain_entry;101 int nb_gain_entry;
98 int gain_entry_err;102 int gain_entry_err;
@@ -126,6 +130,8 @@ static const AVOption firequalizer_options[] = { · 27 unmodified lines
126 { "linlog", "linear-freq logarithmic-gain", 0, AV_OPT_TYPE_CONST, { .i64 = SCALE_LINLOG }, 0, 0, FLAGS, "scale" },130 { "linlog", "linear-freq logarithmic-gain", 0, AV_OPT_TYPE_CONST, { .i64 = SCALE_LINLOG }, 0, 0, FLAGS, "scale" },
127 { "loglin", "logarithmic-freq linear-gain", 0, AV_OPT_TYPE_CONST, { .i64 = SCALE_LOGLIN }, 0, 0, FLAGS, "scale" },131 { "loglin", "logarithmic-freq linear-gain", 0, AV_OPT_TYPE_CONST, { .i64 = SCALE_LOGLIN }, 0, 0, FLAGS, "scale" },
128 { "loglog", "logarithmic-freq logarithmic-gain", 0, AV_OPT_TYPE_CONST, { .i64 = SCALE_LOGLOG }, 0, 0, FLAGS, "scale" },132 { "loglog", "logarithmic-freq logarithmic-gain", 0, AV_OPT_TYPE_CONST, { .i64 = SCALE_LOGLOG }, 0, 0, FLAGS, "scale" },
133 { "dumpfile", "set dump file", OFFSET(dumpfile), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS },
134 { "dumpscale", "set dump scale", OFFSET(dumpscale), AV_OPT_TYPE_INT, { .i64 = SCALE_LINLOG }, 0, NB_SCALE-1, FLAGS, "scale" },
129 { NULL }135 { NULL }
130};136};
131 137
@@ -133,12 +139,14 @@ AVFILTER_DEFINE_CLASS(firequalizer); · 1 unmodified line
133 139
134static void common_uninit(FIREqualizerContext *s)140static void common_uninit(FIREqualizerContext *s)
135{141{
142 av_rdft_end(s->analysis_rdft);
136 av_rdft_end(s->analysis_irdft);143 av_rdft_end(s->analysis_irdft);
137 av_rdft_end(s->rdft);144 av_rdft_end(s->rdft);
138 av_rdft_end(s->irdft);145 av_rdft_end(s->irdft);
139 s->analysis_irdft = s->rdft = s->irdft = NULL;146 s->analysis_rdft = s->analysis_irdft = s->rdft = s->irdft = NULL;
140 147
141 av_freep(&s->analysis_buf);148 av_freep(&s->analysis_buf);
149 av_freep(&s->dump_buf);
142 av_freep(&s->kernel_tmp_buf);150 av_freep(&s->kernel_tmp_buf);
143 av_freep(&s->kernel_buf);151 av_freep(&s->kernel_buf);
144 av_freep(&s->conv_buf);152 av_freep(&s->conv_buf);
@@ -223,6 +231,53 @@ static void fast_convolute(FIREqualizerContext *s, const float *kernel_buf, floa · 78 unmodified lines
223 }231 }
224}232}
225 233
234static void dump_fir(AVFilterContext *ctx, FILE *fp, int ch)
235{
236 FIREqualizerContext *s = ctx->priv;
237 int rate = ctx->inputs[0]->sample_rate;
238 int xlog = s->dumpscale == SCALE_LOGLIN || s->dumpscale == SCALE_LOGLOG;
239 int ylog = s->dumpscale == SCALE_LINLOG || s->dumpscale == SCALE_LOGLOG;
240 int x;
241 int center = s->fir_len / 2;
242 double delay = s->zero_phase ? 0.0 : (double) center / rate;
243 double vx, ya, yb;
244
245 s->analysis_buf[0] *= s->rdft_len/2;
246 for (x = 1; x <= center; x++) {
247 s->analysis_buf[x] *= s->rdft_len/2;
248 s->analysis_buf[s->analysis_rdft_len - x] *= s->rdft_len/2;
249 }
250
251 if (ch)
252 fprintf(fp, "\n\n");
253
254 fprintf(fp, "# time[%d] (time amplitude)\n", ch);
255
256 for (x = center; x > 0; x--)
257 fprintf(fp, "%15.10f %15.10f\n", delay - (double) x / rate, (double) s->analysis_buf[s->analysis_rdft_len - x]);
258
259 for (x = 0; x <= center; x++)
260 fprintf(fp, "%15.10f %15.10f\n", delay + (double)x / rate , (double) s->analysis_buf[x]);
261
262 av_rdft_calc(s->analysis_rdft, s->analysis_buf);
263
264 fprintf(fp, "\n\n# freq[%d] (frequency desired_gain actual_gain)\n", ch);
265
266 for (x = 0; x <= s->analysis_rdft_len/2; x++) {
267 int i = (x == s->analysis_rdft_len/2) ? 1 : 2 * x;
268 vx = (double)x * rate / s->analysis_rdft_len;
269 if (xlog)
270 vx = log2(0.05*vx);
271 ya = s->dump_buf[i];
272 yb = s->analysis_buf[i];
273 if (ylog) {
274 ya = 20.0 * log10(fabs(ya));
275 yb = 20.0 * log10(fabs(yb));
276 }
277 fprintf(fp, "%17.10f %17.10f %17.10f\n", vx, ya, yb);
278 }
279}
280
226static double entry_func(void *p, double freq, double gain)281static double entry_func(void *p, double freq, double gain)
227{282{
228 AVFilterContext *ctx = p;283 AVFilterContext *ctx = p;
@@ -332,6 +387,7 @@ static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *g · 103 unmodified lines
332 int ret, k, center, ch;387 int ret, k, center, ch;
333 int xlog = s->scale == SCALE_LOGLIN || s->scale == SCALE_LOGLOG;388 int xlog = s->scale == SCALE_LOGLIN || s->scale == SCALE_LOGLOG;
334 int ylog = s->scale == SCALE_LINLOG || s->scale == SCALE_LOGLOG;389 int ylog = s->scale == SCALE_LINLOG || s->scale == SCALE_LOGLOG;
390 FILE *dump_fp = NULL;
335 391
336 s->nb_gain_entry = 0;392 s->nb_gain_entry = 0;
337 s->gain_entry_err = 0;393 s->gain_entry_err = 0;
@@ -352,10 +408,14 @@ static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *g · 14 unmodified lines
352 if (ret < 0)408 if (ret < 0)
353 return ret;409 return ret;
354 410
411 if (s->dumpfile && (!s->dump_buf || !s->analysis_rdft || !(dump_fp = fopen(s->dumpfile, "w"))))
412 av_log(ctx, AV_LOG_WARNING, "dumping failed.\n");
413
355 vars[VAR_CHS] = inlink->channels;414 vars[VAR_CHS] = inlink->channels;
356 vars[VAR_CHLAYOUT] = inlink->channel_layout;415 vars[VAR_CHLAYOUT] = inlink->channel_layout;
357 vars[VAR_SR] = inlink->sample_rate;416 vars[VAR_SR] = inlink->sample_rate;
358 for (ch = 0; ch < inlink->channels; ch++) {417 for (ch = 0; ch < inlink->channels; ch++) {
418 float *rdft_buf = s->kernel_tmp_buf + ch * s->rdft_len;
359 double result;419 double result;
360 vars[VAR_CH] = ch;420 vars[VAR_CH] = ch;
361 vars[VAR_CHID] = av_channel_layout_extract_channel(inlink->channel_layout, ch);421 vars[VAR_CHID] = av_channel_layout_extract_channel(inlink->channel_layout, ch);
@@ -380,6 +440,9 @@ static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *g · 18 unmodified lines
380 s->analysis_buf[2*k+1] = 0.0;440 s->analysis_buf[2*k+1] = 0.0;
381 }441 }
382 442
443 if (s->dump_buf)
444 memcpy(s->dump_buf, s->analysis_buf, s->analysis_rdft_len * sizeof(*s->analysis_buf));
445
383 av_rdft_calc(s->analysis_irdft, s->analysis_buf);446 av_rdft_calc(s->analysis_irdft, s->analysis_buf);
384 center = s->fir_len / 2;447 center = s->fir_len / 2;
385 448
@@ -421,35 +484,36 @@ static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *g · 35 unmodified lines
421 av_assert0(0);484 av_assert0(0);
422 }485 }
423 s->analysis_buf[k] *= (2.0/s->analysis_rdft_len) * (2.0/s->rdft_len) * win;486 s->analysis_buf[k] *= (2.0/s->analysis_rdft_len) * (2.0/s->rdft_len) * win;
487 if (k)
488 s->analysis_buf[s->analysis_rdft_len - k] = s->analysis_buf[k];
424 }489 }
425 490
426 for (k = 0; k < center - k; k++) {491 memset(s->analysis_buf + center + 1, 0, (s->analysis_rdft_len - s->fir_len) * sizeof(*s->analysis_buf));
427 float tmp = s->analysis_buf[k];492 memcpy(rdft_buf, s->analysis_buf + s->analysis_rdft_len - center, center * sizeof(*s->analysis_buf));
428 s->analysis_buf[k] = s->analysis_buf[center - k];493 memcpy(rdft_buf + center, s->analysis_buf, (s->rdft_len - center) * sizeof(*s->analysis_buf));
429 s->analysis_buf[center - k] = tmp;494 av_rdft_calc(s->rdft, rdft_buf);
430 }
431
432 for (k = 1; k <= center; k++)
433 s->analysis_buf[center + k] = s->analysis_buf[center - k];
434
435 memset(s->analysis_buf + s->fir_len, 0, (s->rdft_len - s->fir_len) * sizeof(*s->analysis_buf));
436 av_rdft_calc(s->rdft, s->analysis_buf);
437 495
438 for (k = 0; k < s->rdft_len; k++) {496 for (k = 0; k < s->rdft_len; k++) {
439 if (isnan(s->analysis_buf[k]) || isinf(s->analysis_buf[k])) {497 if (isnan(rdft_buf[k]) || isinf(rdft_buf[k])) {
440 av_log(ctx, AV_LOG_ERROR, "filter kernel contains nan or infinity.\n");498 av_log(ctx, AV_LOG_ERROR, "filter kernel contains nan or infinity.\n");
441 av_expr_free(gain_expr);499 av_expr_free(gain_expr);
500 if (dump_fp)
501 fclose(dump_fp);
442 return AVERROR(EINVAL);502 return AVERROR(EINVAL);
443 }503 }
444 }504 }
445 505
446 memcpy(s->kernel_tmp_buf + ch * s->rdft_len, s->analysis_buf, s->rdft_len * sizeof(*s->analysis_buf));506 if (dump_fp)
507 dump_fir(ctx, dump_fp, ch);
508
447 if (!s->multi)509 if (!s->multi)
448 break;510 break;
449 }511 }
450 512
451 memcpy(s->kernel_buf, s->kernel_tmp_buf, (s->multi ? inlink->channels : 1) * s->rdft_len * sizeof(*s->kernel_buf));513 memcpy(s->kernel_buf, s->kernel_tmp_buf, (s->multi ? inlink->channels : 1) * s->rdft_len * sizeof(*s->kernel_buf));
452 av_expr_free(gain_expr);514 av_expr_free(gain_expr);
515 if (dump_fp)
516 fclose(dump_fp);
453 return 0;517 return 0;
454}518}
455 519
@@ -499,6 +563,11 @@ static int config_input(AVFilterLink *inlink) · 43 unmodified lines
499 if (!(s->analysis_irdft = av_rdft_init(rdft_bits, IDFT_C2R)))563 if (!(s->analysis_irdft = av_rdft_init(rdft_bits, IDFT_C2R)))
500 return AVERROR(ENOMEM);564 return AVERROR(ENOMEM);
501 565
566 if (s->dumpfile) {
567 s->analysis_rdft = av_rdft_init(rdft_bits, DFT_R2C);
568 s->dump_buf = av_malloc_array(s->analysis_rdft_len, sizeof(*s->dump_buf));
569 }
570
502 s->analysis_buf = av_malloc_array(s->analysis_rdft_len, sizeof(*s->analysis_buf));571 s->analysis_buf = av_malloc_array(s->analysis_rdft_len, sizeof(*s->analysis_buf));
503 s->kernel_tmp_buf = av_malloc_array(s->rdft_len * (s->multi ? inlink->channels : 1), sizeof(*s->kernel_tmp_buf));572 s->kernel_tmp_buf = av_malloc_array(s->rdft_len * (s->multi ? inlink->channels : 1), sizeof(*s->kernel_tmp_buf));
504 s->kernel_buf = av_malloc_array(s->rdft_len * (s->multi ? inlink->channels : 1), sizeof(*s->kernel_buf));573 s->kernel_buf = av_malloc_array(s->rdft_len * (s->multi ? inlink->channels : 1), sizeof(*s->kernel_buf));

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