Signed-off-by: Muhammad Faiz <mfcc64@gmail.com>
Muhammad Faiz authored on 2017/04/08 11:55:06... | ... |
@@ -17192,6 +17192,11 @@ event in time domain is represented more accurately (such as fast bass drum), |
17192 | 17192 |
otherwise event in frequency domain is represented more accurately |
17193 | 17193 |
(such as bass guitar). Acceptable range is @code{[0.002, 1]}. Default value is @code{0.17}. |
17194 | 17194 |
|
17195 |
+@item attack |
|
17196 |
+Set attack time in seconds. The default is @code{0} (disabled). Otherwise, it |
|
17197 |
+limits future samples by applying asymmetric windowing in time domain, useful |
|
17198 |
+when low latency is required. Accepted range is @code{[0, 1]}. |
|
17199 |
+ |
|
17195 | 17200 |
@item basefreq |
17196 | 17201 |
Specify the transform base frequency. Default value is @code{20.01523126408007475}, |
17197 | 17202 |
which is frequency 50 cents below E0. Acceptable range is @code{[10, 100000]}. |
... | ... |
@@ -78,6 +78,7 @@ static const AVOption showcqt_options[] = { |
78 | 78 |
{ "bar_t", "set bar transparency", OFFSET(bar_t), AV_OPT_TYPE_FLOAT, { .dbl = 1.0 }, 0.0, 1.0, FLAGS }, |
79 | 79 |
{ "timeclamp", "set timeclamp", OFFSET(timeclamp), AV_OPT_TYPE_DOUBLE, { .dbl = 0.17 }, 0.002, 1.0, FLAGS }, |
80 | 80 |
{ "tc", "set timeclamp", OFFSET(timeclamp), AV_OPT_TYPE_DOUBLE, { .dbl = 0.17 }, 0.002, 1.0, FLAGS }, |
81 |
+ { "attack", "set attack time", OFFSET(attack), AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, 0.0, 1.0, FLAGS }, |
|
81 | 82 |
{ "basefreq", "set base frequency", OFFSET(basefreq), AV_OPT_TYPE_DOUBLE, { .dbl = BASEFREQ }, 10.0, 100000.0, FLAGS }, |
82 | 83 |
{ "endfreq", "set end frequency", OFFSET(endfreq), AV_OPT_TYPE_DOUBLE, { .dbl = ENDFREQ }, 10.0, 100000.0, FLAGS }, |
83 | 84 |
{ "coeffclamp", "set coeffclamp", OFFSET(coeffclamp), AV_OPT_TYPE_FLOAT, { .dbl = 1.0 }, 0.1, 10.0, FLAGS }, |
... | ... |
@@ -152,6 +153,7 @@ static void common_uninit(ShowCQTContext *s) |
152 | 152 |
av_freep(&s->fft_data); |
153 | 153 |
av_freep(&s->fft_result); |
154 | 154 |
av_freep(&s->cqt_result); |
155 |
+ av_freep(&s->attack_data); |
|
155 | 156 |
av_freep(&s->c_buf); |
156 | 157 |
av_freep(&s->h_buf); |
157 | 158 |
av_freep(&s->rcp_h_buf); |
... | ... |
@@ -1138,6 +1140,14 @@ static int plot_cqt(AVFilterContext *ctx, AVFrame **frameout) |
1138 | 1138 |
last_time = av_gettime(); |
1139 | 1139 |
|
1140 | 1140 |
memcpy(s->fft_result, s->fft_data, s->fft_len * sizeof(*s->fft_data)); |
1141 |
+ if (s->attack_data) { |
|
1142 |
+ int k; |
|
1143 |
+ for (k = 0; k < s->remaining_fill_max; k++) { |
|
1144 |
+ s->fft_result[s->fft_len/2+k].re *= s->attack_data[k]; |
|
1145 |
+ s->fft_result[s->fft_len/2+k].im *= s->attack_data[k]; |
|
1146 |
+ } |
|
1147 |
+ } |
|
1148 |
+ |
|
1141 | 1149 |
av_fft_permute(s->fft_ctx, s->fft_result); |
1142 | 1150 |
av_fft_calc(s->fft_ctx, s->fft_result); |
1143 | 1151 |
s->fft_result[s->fft_len] = s->fft_result[0]; |
... | ... |
@@ -1377,6 +1387,21 @@ static int config_output(AVFilterLink *outlink) |
1377 | 1377 |
if (!s->fft_ctx || !s->fft_data || !s->fft_result || !s->cqt_result) |
1378 | 1378 |
return AVERROR(ENOMEM); |
1379 | 1379 |
|
1380 |
+ s->remaining_fill_max = s->fft_len / 2; |
|
1381 |
+ if (s->attack > 0.0) { |
|
1382 |
+ int k; |
|
1383 |
+ |
|
1384 |
+ s->remaining_fill_max = FFMIN(s->remaining_fill_max, ceil(inlink->sample_rate * s->attack)); |
|
1385 |
+ s->attack_data = av_malloc_array(s->remaining_fill_max, sizeof(*s->attack_data)); |
|
1386 |
+ if (!s->attack_data) |
|
1387 |
+ return AVERROR(ENOMEM); |
|
1388 |
+ |
|
1389 |
+ for (k = 0; k < s->remaining_fill_max; k++) { |
|
1390 |
+ double y = M_PI * k / (inlink->sample_rate * s->attack); |
|
1391 |
+ s->attack_data[k] = 0.355768 + 0.487396 * cos(y) + 0.144232 * cos(2*y) + 0.012604 * cos(3*y); |
|
1392 |
+ } |
|
1393 |
+ } |
|
1394 |
+ |
|
1380 | 1395 |
s->cqt_align = 1; |
1381 | 1396 |
s->cqt_calc = cqt_calc; |
1382 | 1397 |
s->permute_coeffs = NULL; |
... | ... |
@@ -1435,7 +1460,7 @@ static int config_output(AVFilterLink *outlink) |
1435 | 1435 |
s->sono_count = 0; |
1436 | 1436 |
s->next_pts = 0; |
1437 | 1437 |
s->sono_idx = 0; |
1438 |
- s->remaining_fill = s->fft_len / 2; |
|
1438 |
+ s->remaining_fill = s->remaining_fill_max; |
|
1439 | 1439 |
s->remaining_frac = 0; |
1440 | 1440 |
s->step_frac = av_div_q(av_make_q(inlink->sample_rate, s->count) , s->rate); |
1441 | 1441 |
s->step = (int)(s->step_frac.num / s->step_frac.den); |
... | ... |
@@ -1463,15 +1488,15 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) |
1463 | 1463 |
AVFrame *out = NULL; |
1464 | 1464 |
|
1465 | 1465 |
if (!insamples) { |
1466 |
- while (s->remaining_fill < s->fft_len / 2) { |
|
1467 |
- memset(&s->fft_data[s->fft_len - s->remaining_fill], 0, sizeof(*s->fft_data) * s->remaining_fill); |
|
1466 |
+ while (s->remaining_fill < s->remaining_fill_max) { |
|
1467 |
+ memset(&s->fft_data[s->fft_len/2 + s->remaining_fill_max - s->remaining_fill], 0, sizeof(*s->fft_data) * s->remaining_fill); |
|
1468 | 1468 |
ret = plot_cqt(ctx, &out); |
1469 | 1469 |
if (ret < 0) |
1470 | 1470 |
return ret; |
1471 | 1471 |
|
1472 | 1472 |
step = s->step + (s->step_frac.num + s->remaining_frac) / s->step_frac.den; |
1473 | 1473 |
s->remaining_frac = (s->step_frac.num + s->remaining_frac) % s->step_frac.den; |
1474 |
- for (x = 0; x < (s->fft_len-step); x++) |
|
1474 |
+ for (x = 0; x < (s->fft_len/2 + s->remaining_fill_max - step); x++) |
|
1475 | 1475 |
s->fft_data[x] = s->fft_data[x+step]; |
1476 | 1476 |
s->remaining_fill += step; |
1477 | 1477 |
|
... | ... |
@@ -1486,7 +1511,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) |
1486 | 1486 |
|
1487 | 1487 |
while (remaining) { |
1488 | 1488 |
i = insamples->nb_samples - remaining; |
1489 |
- j = s->fft_len - s->remaining_fill; |
|
1489 |
+ j = s->fft_len/2 + s->remaining_fill_max - s->remaining_fill; |
|
1490 | 1490 |
if (remaining >= s->remaining_fill) { |
1491 | 1491 |
for (m = 0; m < s->remaining_fill; m++) { |
1492 | 1492 |
s->fft_data[j+m].re = audio_data[2*(i+m)]; |
... | ... |
@@ -1500,7 +1525,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) |
1500 | 1500 |
remaining -= s->remaining_fill; |
1501 | 1501 |
if (out) { |
1502 | 1502 |
int64_t pts = av_rescale_q(insamples->pts, inlink->time_base, av_make_q(1, inlink->sample_rate)); |
1503 |
- pts += insamples->nb_samples - remaining - s->fft_len/2; |
|
1503 |
+ pts += insamples->nb_samples - remaining - s->remaining_fill_max; |
|
1504 | 1504 |
pts = av_rescale_q(pts, av_make_q(1, inlink->sample_rate), outlink->time_base); |
1505 | 1505 |
if (FFABS(pts - out->pts) > PTS_TOLERANCE) { |
1506 | 1506 |
av_log(ctx, AV_LOG_DEBUG, "changing pts from %"PRId64" (%.3f) to %"PRId64" (%.3f).\n", |
... | ... |
@@ -1518,7 +1543,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) |
1518 | 1518 |
} |
1519 | 1519 |
step = s->step + (s->step_frac.num + s->remaining_frac) / s->step_frac.den; |
1520 | 1520 |
s->remaining_frac = (s->step_frac.num + s->remaining_frac) % s->step_frac.den; |
1521 |
- for (m = 0; m < s->fft_len-step; m++) |
|
1521 |
+ for (m = 0; m < s->fft_len/2 + s->remaining_fill_max - step; m++) |
|
1522 | 1522 |
s->fft_data[m] = s->fft_data[m+step]; |
1523 | 1523 |
s->remaining_fill = step; |
1524 | 1524 |
} else { |
... | ... |
@@ -55,6 +55,7 @@ typedef struct { |
55 | 55 |
AVRational step_frac; |
56 | 56 |
int remaining_frac; |
57 | 57 |
int remaining_fill; |
58 |
+ int remaining_fill_max; |
|
58 | 59 |
int64_t next_pts; |
59 | 60 |
double *freq; |
60 | 61 |
FFTContext *fft_ctx; |
... | ... |
@@ -62,6 +63,7 @@ typedef struct { |
62 | 62 |
FFTComplex *fft_data; |
63 | 63 |
FFTComplex *fft_result; |
64 | 64 |
FFTComplex *cqt_result; |
65 |
+ float *attack_data; |
|
65 | 66 |
int fft_bits; |
66 | 67 |
int fft_len; |
67 | 68 |
int cqt_len; |
... | ... |
@@ -104,6 +106,7 @@ typedef struct { |
104 | 104 |
float bar_g; |
105 | 105 |
float bar_t; |
106 | 106 |
double timeclamp; |
107 |
+ double attack; |
|
107 | 108 |
double basefreq; |
108 | 109 |
double endfreq; |
109 | 110 |
float coeffclamp; /* deprecated - ignored */ |
... | ... |
@@ -31,7 +31,7 @@ |
31 | 31 |
|
32 | 32 |
#define LIBAVFILTER_VERSION_MAJOR 6 |
33 | 33 |
#define LIBAVFILTER_VERSION_MINOR 84 |
34 |
-#define LIBAVFILTER_VERSION_MICRO 100 |
|
34 |
+#define LIBAVFILTER_VERSION_MICRO 101 |
|
35 | 35 |
|
36 | 36 |
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |
37 | 37 |
LIBAVFILTER_VERSION_MINOR, \ |