Showing the changes to libavfilter (1 of 2 files). Show all
Unified · Split
| @@ -40,6 +40,7 @@ typedef struct AudioDynamicEqualizerContext { · 39 unmodified lines | |||
| 40 | double release_coef; | 40 | double release_coef; |
| 41 | int mode; | 41 | int mode; |
| 42 | int direction; | 42 | int direction; |
| 43 | int detection; | ||
| 43 | int type; | 44 | int type; |
| 44 | 45 | ||
| 45 | AVFrame *state; | 46 | AVFrame *state; |
| @@ -92,7 +93,6 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo · 46 unmodified lines | |||
| 92 | const double range = s->range; | 93 | const double range = s->range; |
| 93 | const double dfrequency = fmin(s->dfrequency, sample_rate * 0.5); | 94 | const double dfrequency = fmin(s->dfrequency, sample_rate * 0.5); |
| 94 | const double tfrequency = fmin(s->tfrequency, sample_rate * 0.5); | 95 | const double tfrequency = fmin(s->tfrequency, sample_rate * 0.5); |
| 95 | const double threshold = s->threshold; | ||
| 96 | const double release = s->release_coef; | 96 | const double release = s->release_coef; |
| 97 | const double irelease = 1. - release; | 97 | const double irelease = 1. - release; |
| 98 | const double attack = s->attack_coef; | 98 | const double attack = s->attack_coef; |
| @@ -103,6 +103,7 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo · 4 unmodified lines | |||
| 103 | const double dg = tan(M_PI * dfrequency / sample_rate); | 103 | const double dg = tan(M_PI * dfrequency / sample_rate); |
| 104 | const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; | 104 | const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; |
| 105 | const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; | 105 | const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; |
| 106 | const int detection = s->detection; | ||
| 106 | const int direction = s->direction; | 107 | const int direction = s->direction; |
| 107 | const int mode = s->mode; | 108 | const int mode = s->mode; |
| 108 | const int type = s->type; | 109 | const int type = s->type; |
| @@ -124,6 +125,10 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo · 15 unmodified lines | |||
| 124 | const double *src = (const double *)in->extended_data[ch]; | 125 | const double *src = (const double *)in->extended_data[ch]; |
| 125 | double *dst = (double *)out->extended_data[ch]; | 126 | double *dst = (double *)out->extended_data[ch]; |
| 126 | double *state = (double *)s->state->extended_data[ch]; | 127 | double *state = (double *)s->state->extended_data[ch]; |
| 128 | const double threshold = detection == 0 ? state[5] : s->threshold; | ||
| 129 | |||
| 130 | if (detection < 0) | ||
| 131 | state[5] = threshold; | ||
| 127 | 132 | ||
| 128 | for (int n = 0; n < out->nb_samples; n++) { | 133 | for (int n = 0; n < out->nb_samples; n++) { |
| 129 | double detect, gain, v, listen; | 134 | double detect, gain, v, listen; |
| @@ -133,6 +138,9 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo · 3 unmodified lines | |||
| 133 | detect = listen = get_svf(src[n], dm, da, state); | 138 | detect = listen = get_svf(src[n], dm, da, state); |
| 134 | detect = fabs(detect); | 139 | detect = fabs(detect); |
| 135 | 140 | ||
| 141 | if (detection > 0) | ||
| 142 | state[5] = fmax(state[5], detect); | ||
| 143 | |||
| 136 | if (direction == 0 && mode == 0 && detect < threshold) | 144 | if (direction == 0 && mode == 0 && detect < threshold) |
| 137 | detect = 1. / av_clipd(1. + makeup + (threshold - detect) * ratio, 1., range); | 145 | detect = 1. / av_clipd(1. + makeup + (threshold - detect) * ratio, 1., range); |
| 138 | else if (direction == 0 && mode == 1 && detect < threshold) | 146 | else if (direction == 0 && mode == 1 && detect < threshold) |
| @@ -144,10 +152,18 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo · 5 unmodified lines | |||
| 144 | else | 152 | else |
| 145 | detect = 1.; | 153 | detect = 1.; |
| 146 | 154 | ||
| 147 | if (detect < state[4]) { | 155 | if (direction == 0) { |
| 148 | detect = iattack * detect + attack * state[4]; | 156 | if (detect > state[4]) { |
| 157 | detect = iattack * detect + attack * state[4]; | ||
| 158 | } else { | ||
| 159 | detect = irelease * detect + release * state[4]; | ||
| 160 | } | ||
| 149 | } else { | 161 | } else { |
| 150 | detect = irelease * detect + release * state[4]; | 162 | if (detect < state[4]) { |
| 163 | detect = iattack * detect + attack * state[4]; | ||
| 164 | } else { | ||
| 165 | detect = irelease * detect + release * state[4]; | ||
| 166 | } | ||
| 151 | } | 167 | } |
| 152 | 168 | ||
| 153 | if (state[4] != detect || n == 0) { | 169 | if (state[4] != detect || n == 0) { |
| @@ -270,6 +286,10 @@ static const AVOption adynamicequalizer_options[] = { · 116 unmodified lines | |||
| 270 | { "direction", "set direction", OFFSET(direction), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "direction" }, | 286 | { "direction", "set direction", OFFSET(direction), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "direction" }, |
| 271 | { "downward", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "direction" }, | 287 | { "downward", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "direction" }, |
| 272 | { "upward", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "direction" }, | 288 | { "upward", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "direction" }, |
| 289 | { "auto", "set auto threshold", OFFSET(detection), AV_OPT_TYPE_INT, {.i64=-1}, -1, 1, FLAGS, "auto" }, | ||
| 290 | { "disabled", 0, 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, FLAGS, "auto" }, | ||
| 291 | { "off", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "auto" }, | ||
| 292 | { "on", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "auto" }, | ||
| 273 | { NULL } | 293 | { NULL } |
| 274 | }; | 294 | }; |
| 275 | 295 | ||