1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
20
26
29
45
48
50 {
53
57
58 return 0;
59 }
60
61 static double get_svf(
double in,
double *m,
double *
a,
double *
b)
62 {
64 const double v3 =
v0 -
b[1];
65 const double v1 =
a[0] *
b[0] +
a[1] * v3;
66 const double v2 =
b[1] +
a[1] *
b[0] +
a[2] * v3;
67
68 b[0] = 2. * v1 -
b[0];
69 b[1] = 2. * v2 -
b[1];
70
71 return m[0] *
v0 + m[1] * v1 + m[2] * v2;
72 }
73
75 {
77 }
78
79 static inline double to_dB(
double x)
80 {
81 return 20. * log10(x);
82 }
83
84 static inline double sqr(
double x)
85 {
86 return x * x;
87 }
88
89 static double get_gain(
double in,
double srate,
double makeup,
90 double aattack, double iratio, double knee, double range,
91 double thresdb,
double slewfactor,
double *
state,
92 double attack_coeff, double release_coeff, double nc)
93 {
94 double width = (6. * knee) + 0.01;
95 double cdb = 0.;
96 double Lgain = 1.;
97 double Lxg, Lxl, Lyg, Lyl, Ly1;
98 double checkwidth = 0.;
99 double slewwidth = 1.8;
100 int attslew = 0;
101
102 Lyg = 0.;
104
105 Lyg = Lxg + (iratio - 1.) *
sqr(Lxg - thresdb +
width * .5) / (2. *
width);
106
107 checkwidth = 2. *
fabs(Lxg - thresdb);
108 if (2. * (Lxg - thresdb) < -
width) {
109 Lyg = Lxg;
110 }
else if (checkwidth <=
width) {
111 Lyg = thresdb + (Lxg - thresdb) * iratio;
112 if (checkwidth <= slewwidth) {
114 attslew = 1;
115 }
116 }
else if (2. * (Lxg-thresdb) >
width) {
117 Lyg = thresdb + (Lxg - thresdb) * iratio;
118 }
119
120 attack_coeff = attslew ? aattack : attack_coeff;
121
122 Lxl = Lxg - Lyg;
123
124 Ly1 =
fmaxf(Lxl, release_coeff *
state[1] +(1. - release_coeff) * Lxl);
125 Lyl = attack_coeff *
state[0] + (1. - attack_coeff) * Ly1;
126
127 cdb = -Lyl;
129
133
134 return Lgain;
135 }
136
140
142 {
148 const double makeup =
s->makeup;
149 const double iratio = 1. /
s->ratio;
150 const double range =
s->range;
153 const double threshold = log(
s->threshold + DBL_EPSILON);
154 const double release =
s->release_coef;
155 const double attack =
s->attack_coef;
156 const double dqfactor =
s->dqfactor;
157 const double tqfactor =
s->tqfactor;
160 const int start = (in->
channels * jobnr) / nb_jobs;
161 const int end = (in->
channels * (jobnr+1)) / nb_jobs;
162 const int mode =
s->mode;
163 const double knee =
s->knee;
164 const double slew =
s->slew;
165 const double aattack =
exp(-1000. / ((
s->attack + 2.0 * (slew - 1.)) *
sample_rate));
166 const double nc =
mode == 0 ? 1. : -1.;
167 double da[3], dm[3];
168
169 {
170 double k = 1. / dqfactor;
171
172 da[0] = 1. / (1. + dg * (dg + k));
173 da[1] = dg * da[0];
174 da[2] = dg * da[1];
175
176 dm[0] = 0.;
177 dm[1] = 1.;
178 dm[2] = 0.;
179 }
180
181 for (int ch = start; ch < end; ch++) {
183 double *dst = (
double *)
out->extended_data[ch];
184 double *
state = (
double *)
s->state->extended_data[ch];
185
186 for (
int n = 0; n <
out->nb_samples; n++) {
187 double detect, gain, v, listen;
188 double fa[3], fm[3];
189
191 detect =
fabs(detect);
192
194 aattack, iratio, knee, range, threshold, slew,
195 &
state[4], attack, release, nc);
196
197 {
198 double k = 1. / (tqfactor * gain);
199
200 fa[0] = 1. / (1. + fg * (fg + k));
201 fa[1] = fg * fa[0];
202 fa[2] = fg * fa[1];
203
204 fm[0] = 1.;
205 fm[1] = k * (gain * gain - 1.);
206 fm[2] = 0.;
207 }
208
210 v =
mode == -1 ? listen : v;
211 dst[n] =
ctx->is_disabled ?
src[n] : v;
212 }
213 }
214
215 return 0;
216 }
217
219 {
220 return exp(-1000. / (x * sr));
221 }
222
224 {
230
233 } else {
238 }
240 }
241
244
249
253 }
254
256 {
258
260 }
261
262 #define OFFSET(x) offsetof(AudioDynamicEqualizerContext, x)
263 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
264
283 };
284
286
288 {
293 },
294 };
295
297 {
300 },
301 };
302
304 .
name =
"adynamicequalizer",
307 .priv_class = &adynamicequalizer_class,
315 };