FFmpeg
Loading...
Searching...
No Matches
adynamicequalizer_template.c
Go to the documentation of this file.
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
19#undef ftype
20#undef SQRT
21#undef TAN
22#undef ONE
23#undef TWO
24#undef ZERO
25#undef FMAX
26#undef FMIN
27#undef CLIP
28#undef SAMPLE_FORMAT
29#undef FABS
30#undef FLOG
31#undef FEXP
32#undef FLOG2
33#undef FLOG10
34#undef FEXP2
35#undef FEXP10
36#undef EPSILON
37#if DEPTH == 32
38#define SAMPLE_FORMAT float
39#define SQRT sqrtf
40#define TAN tanf
41#define ONE 1.f
42#define TWO 2.f
43#define ZERO 0.f
44#define FMIN fminf
45#define FMAX fmaxf
46#define CLIP av_clipf
47#define FABS fabsf
48#define FLOG logf
49#define FEXP expf
50#define FLOG2 log2f
51#define FLOG10 log10f
52#define FEXP2 exp2f
53#define FEXP10 ff_exp10f
54#define EPSILON (1.f / (1 << 23))
55#define ftype float
56#else
57#define SAMPLE_FORMAT double
58#define SQRT sqrt
59#define TAN tan
60#define ONE 1.0
61#define TWO 2.0
62#define ZERO 0.0
63#define FMIN fmin
64#define FMAX fmax
65#define CLIP av_clipd
66#define FABS fabs
67#define FLOG log
68#define FEXP exp
69#define FLOG2 log2
70#define FLOG10 log10
71#define FEXP2 exp2
72#define FEXP10 ff_exp10
73#define EPSILON (1.0 / (1LL << 53))
74#define ftype double
75#endif
76
77#define LIN2LOG(x) (20.0 * FLOG10(x))
78#define LOG2LIN(x) (FEXP10(x / 20.0))
79
80#define fn3(a,b) a##_##b
81#define fn2(a,b) fn3(a,b)
82#define fn(a) fn2(a, SAMPLE_FORMAT)
83
84static ftype fn(get_svf)(ftype in, const ftype *m, const ftype *a, ftype *b)
85{
86 const ftype v0 = in;
87 const ftype v3 = v0 - b[1];
88 const ftype v1 = a[0] * b[0] + a[1] * v3;
89 const ftype v2 = b[1] + a[1] * b[0] + a[2] * v3;
90
91 b[0] = TWO * v1 - b[0];
92 b[1] = TWO * v2 - b[1];
93
94 return m[0] * v0 + m[1] * v1 + m[2] * v2;
95}
96
98{
100 const ftype sample_rate = ctx->inputs[0]->sample_rate;
101 const ftype dfrequency = FMIN(s->dfrequency, sample_rate * 0.5);
102 const ftype dg = TAN(M_PI * dfrequency / sample_rate);
103 const ftype dqfactor = s->dqfactor;
104 const int dftype = s->dftype;
105 ftype *da = fn(s->da);
106 ftype *dm = fn(s->dm);
107 ftype k;
108
109 s->threshold_log = LIN2LOG(s->threshold);
110 s->dattack_coef = get_coef(s->dattack, sample_rate);
111 s->drelease_coef = get_coef(s->drelease, sample_rate);
112 s->gattack_coef = s->dattack_coef * 0.25;
113 s->grelease_coef = s->drelease_coef * 0.25;
114
115 switch (dftype) {
116 case 0:
117 k = ONE / dqfactor;
118
119 da[0] = ONE / (ONE + dg * (dg + k));
120 da[1] = dg * da[0];
121 da[2] = dg * da[1];
122
123 dm[0] = ZERO;
124 dm[1] = k;
125 dm[2] = ZERO;
126 break;
127 case 1:
128 k = ONE / dqfactor;
129
130 da[0] = ONE / (ONE + dg * (dg + k));
131 da[1] = dg * da[0];
132 da[2] = dg * da[1];
133
134 dm[0] = ZERO;
135 dm[1] = ZERO;
136 dm[2] = ONE;
137 break;
138 case 2:
139 k = ONE / dqfactor;
140
141 da[0] = ONE / (ONE + dg * (dg + k));
142 da[1] = dg * da[0];
143 da[2] = dg * da[1];
144
145 dm[0] = ZERO;
146 dm[1] = -k;
147 dm[2] = -ONE;
148 break;
149 case 3:
150 k = ONE / dqfactor;
151
152 da[0] = ONE / (ONE + dg * (dg + k));
153 da[1] = dg * da[0];
154 da[2] = dg * da[1];
155
156 dm[0] = ONE;
157 dm[1] = -k;
158 dm[2] = -TWO;
159 break;
160 }
161
162 return 0;
163}
164
165#define PEAKS(empty_value,op,sample, psample)\
166 if (!empty && psample == ss[front]) { \
167 ss[front] = empty_value; \
168 if (back != front) { \
169 front--; \
170 if (front < 0) \
171 front = n - 1; \
172 } \
173 empty = front == back; \
174 } \
175 \
176 if (!empty && sample op ss[front]) { \
177 while (1) { \
178 ss[front] = empty_value; \
179 if (back == front) { \
180 empty = 1; \
181 break; \
182 } \
183 front--; \
184 if (front < 0) \
185 front = n - 1; \
186 } \
187 } \
188 \
189 while (!empty && sample op ss[back]) { \
190 ss[back] = empty_value; \
191 if (back == front) { \
192 empty = 1; \
193 break; \
194 } \
195 back++; \
196 if (back >= n) \
197 back = 0; \
198 } \
199 \
200 if (!empty) { \
201 back--; \
202 if (back < 0) \
203 back = n - 1; \
204 }
205
207 const ftype x,
208 const int nb_samples)
209{
210 ftype *ss = cc->dqueue;
211 ftype *qq = cc->queue;
212 int front = cc->front;
213 int back = cc->back;
214 int empty, n, pos = cc->position;
215 ftype px = qq[pos];
216
217 fn(cc->sum) += x;
218 fn(cc->log_sum) += FLOG2(x);
219 if (cc->size >= nb_samples) {
220 fn(cc->sum) -= px;
221 fn(cc->log_sum) -= FLOG2(px);
222 }
223
224 qq[pos] = x;
225 pos++;
226 if (pos >= nb_samples)
227 pos = 0;
228 cc->position = pos;
229
230 if (cc->size < nb_samples)
231 cc->size++;
232 n = cc->size;
233
234 empty = (front == back) && (ss[front] == ZERO);
235 PEAKS(ZERO, >, x, px)
236
237 ss[back] = x;
238
239 cc->front = front;
240 cc->back = back;
241}
242
244{
245 ftype s, *ss = cc->dqueue;
246 s = FEXP2(fn(cc->log_sum) / cc->size) / (fn(cc->sum) / cc->size);
247 *score = LIN2LOG(s);
248 return ss[cc->front];
249}
250
251static int fn(filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
252{
254 ThreadData *td = arg;
255 AVFrame *in = td->in;
256 AVFrame *out = td->out;
257 const ftype sample_rate = in->sample_rate;
258 const int isample_rate = in->sample_rate;
259 const ftype makeup = s->makeup;
260 const ftype ratio = s->ratio;
261 const ftype range = s->range;
262 const ftype tfrequency = FMIN(s->tfrequency, sample_rate * 0.5);
263 const int mode = s->mode;
264 const ftype power = (mode == CUT_BELOW || mode == CUT_ABOVE) ? -ONE : ONE;
265 const ftype grelease = s->grelease_coef;
266 const ftype gattack = s->gattack_coef;
267 const ftype drelease = s->drelease_coef;
268 const ftype dattack = s->dattack_coef;
269 const ftype tqfactor = s->tqfactor;
270 const ftype itqfactor = ONE / tqfactor;
271 const ftype fg = TAN(M_PI * tfrequency / sample_rate);
272 const int start = ff_slice_pos(in->ch_layout.nb_channels, jobnr, nb_jobs);
273 const int end = ff_slice_pos(in->ch_layout.nb_channels, jobnr + 1, nb_jobs);
274 const int is_disabled = ctx->is_disabled;
275 const int detection = s->detection;
276 const int tftype = s->tftype;
277 const ftype *da = fn(s->da);
278 const ftype *dm = fn(s->dm);
279
280 if (detection == DET_ON) {
281 for (int ch = start; ch < end; ch++) {
282 const ftype *src = (const ftype *)in->extended_data[ch];
283 ChannelContext *cc = &s->cc[ch];
284 ftype *tstate = fn(cc->tstate);
285 ftype new_threshold = ZERO;
286
287 if (cc->detection != detection) {
288 cc->detection = detection;
289 fn(cc->new_threshold_log) = LIN2LOG(EPSILON);
290 }
291
292 for (int n = 0; n < in->nb_samples; n++) {
293 ftype detect = FABS(fn(get_svf)(src[n], dm, da, tstate));
294 new_threshold = FMAX(new_threshold, detect);
295 }
296
297 fn(cc->new_threshold_log) = FMAX(fn(cc->new_threshold_log), LIN2LOG(new_threshold));
298 }
299 } else if (detection == DET_ADAPTIVE) {
300 for (int ch = start; ch < end; ch++) {
301 const ftype *src = (const ftype *)in->extended_data[ch];
302 ChannelContext *cc = &s->cc[ch];
303 ftype *tstate = fn(cc->tstate);
304 ftype score, peak;
305
306 for (int n = 0; n < in->nb_samples; n++) {
307 ftype detect = FMAX(FABS(fn(get_svf)(src[n], dm, da, tstate)), EPSILON);
308 fn(queue_sample)(cc, detect, isample_rate);
309 }
310
311 peak = fn(get_peak)(cc, &score);
312
313 if (score >= -3.5) {
314 fn(cc->threshold_log) = LIN2LOG(peak);
315 } else if (cc->detection == DET_UNSET) {
316 fn(cc->threshold_log) = s->threshold_log;
317 }
318 cc->detection = detection;
319 }
320 } else if (detection == DET_DISABLED) {
321 for (int ch = start; ch < end; ch++) {
322 ChannelContext *cc = &s->cc[ch];
323 fn(cc->threshold_log) = s->threshold_log;
324 cc->detection = detection;
325 }
326 } else if (detection == DET_OFF) {
327 for (int ch = start; ch < end; ch++) {
328 ChannelContext *cc = &s->cc[ch];
329 if (cc->detection == DET_ON)
330 fn(cc->threshold_log) = fn(cc->new_threshold_log);
331 else if (cc->detection == DET_UNSET)
332 fn(cc->threshold_log) = s->threshold_log;
333 cc->detection = detection;
334 }
335 }
336
337 for (int ch = start; ch < end; ch++) {
338 const ftype *src = (const ftype *)in->extended_data[ch];
339 ftype *dst = (ftype *)out->extended_data[ch];
340 ChannelContext *cc = &s->cc[ch];
341 const ftype threshold_log = fn(cc->threshold_log);
342 ftype *fa = fn(cc->fa), *fm = fn(cc->fm);
343 ftype *fstate = fn(cc->fstate);
344 ftype *dstate = fn(cc->dstate);
345 ftype detect = fn(cc->detect);
346 ftype lin_gain = fn(cc->lin_gain);
347 int init = cc->init;
348
349 for (int n = 0; n < out->nb_samples; n++) {
350 ftype new_detect, new_lin_gain = ONE;
351 ftype f, v, listen, k, g, ld;
352
353 listen = fn(get_svf)(src[n], dm, da, dstate);
354 if (mode > LISTEN) {
355 new_detect = FABS(listen);
356 f = (new_detect > detect) * dattack + (new_detect <= detect) * drelease;
357 detect = f * new_detect + (ONE - f) * detect;
358 }
359
360 switch (mode) {
361 case LISTEN:
362 break;
363 case CUT_BELOW:
364 case BOOST_BELOW:
365 ld = LIN2LOG(detect);
366 if (ld < threshold_log) {
367 ftype new_log_gain = CLIP(makeup + (threshold_log - ld) * ratio, ZERO, range) * power;
368 new_lin_gain = LOG2LIN(new_log_gain);
369 }
370 break;
371 case CUT_ABOVE:
372 case BOOST_ABOVE:
373 ld = LIN2LOG(detect);
374 if (ld > threshold_log) {
375 ftype new_log_gain = CLIP(makeup + (ld - threshold_log) * ratio, ZERO, range) * power;
376 new_lin_gain = LOG2LIN(new_log_gain);
377 }
378 break;
379 }
380
381 f = (new_lin_gain > lin_gain) * gattack + (new_lin_gain <= lin_gain) * grelease;
382 new_lin_gain = f * new_lin_gain + (ONE - f) * lin_gain;
383
384 if (lin_gain != new_lin_gain || !init) {
385 init = 1;
386 lin_gain = new_lin_gain;
387
388 switch (tftype) {
389 case 0:
390 k = itqfactor / lin_gain;
391
392 fa[0] = ONE / (ONE + fg * (fg + k));
393 fa[1] = fg * fa[0];
394 fa[2] = fg * fa[1];
395
396 fm[0] = ONE;
397 fm[1] = k * (lin_gain * lin_gain - ONE);
398 fm[2] = ZERO;
399 break;
400 case 1:
401 k = itqfactor;
402 g = fg / SQRT(lin_gain);
403
404 fa[0] = ONE / (ONE + g * (g + k));
405 fa[1] = g * fa[0];
406 fa[2] = g * fa[1];
407
408 fm[0] = ONE;
409 fm[1] = k * (lin_gain - ONE);
410 fm[2] = lin_gain * lin_gain - ONE;
411 break;
412 case 2:
413 k = itqfactor;
414 g = fg * SQRT(lin_gain);
415
416 fa[0] = ONE / (ONE + g * (g + k));
417 fa[1] = g * fa[0];
418 fa[2] = g * fa[1];
419
420 fm[0] = lin_gain * lin_gain;
421 fm[1] = k * (ONE - lin_gain) * lin_gain;
422 fm[2] = ONE - lin_gain * lin_gain;
423 break;
424 }
425 }
426
427 v = fn(get_svf)(src[n], fm, fa, fstate);
428 v = mode == LISTEN ? listen : v;
429 dst[n] = is_disabled ? src[n] : v;
430 }
431
432 fn(cc->detect) = detect;
433 fn(cc->lin_gain) = lin_gain;
434 cc->init = 1;
435 }
436
437 return 0;
438}
#define ftype
#define ZERO
static int fn filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
#define EPSILON
static int fn filter_prepare(AVFilterContext *ctx)
#define PEAKS(empty_value, op, sample, psample)
#define fn(a)
#define LOG2LIN(x)
static ftype fn get_peak(ChannelContext *cc, ftype *score)
#define FEXP2
#define LIN2LOG(x)
#define FLOG2
static void fn queue_sample(ChannelContext *cc, const ftype x, const int nb_samples)
static ftype fn get_svf(ftype in, const ftype *m, const ftype *a, ftype *b)
static double get_coef(double x, double sr)
@ BOOST_BELOW
@ BOOST_ABOVE
@ DET_ADAPTIVE
@ DET_DISABLED
#define f(width, name)
Definition cbs_vp8.c:236
#define ss(width, name, subs,...)
Definition cbs_vp9.c:202
#define s(width, name)
Definition cbs_vp9.c:198
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
int a
#define b
Definition input.c:43
#define ONE
Definition jrevdct.c:137
const char * arg
Definition jacosubdec.c:65
static int ff_slice_pos(int total, int jobnr, int nb_jobs)
Compute the boundary index for a slice when work of size total is split into nb_jobs slices.
Definition filters.h:763
#define M_PI
Definition mathematics.h:67
enum AVColorRange range
static float power(float r, float g, float b, float max)
unsigned int pos
Definition spdifenc.c:431
int nb_channels
Number of channels in this layout.
An instance of a filter.
Definition avfilter.h:273
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
int nb_samples
number of audio samples (per channel) described by this frame
Definition frame.h:552
int sample_rate
Sample rate of the audio data.
Definition frame.h:635
AVChannelLayout ch_layout
Channel layout of the audio data.
Definition frame.h:815
uint8_t ** extended_data
pointers to the data planes/channels.
Definition frame.h:533
Used for passing data between threads.
Definition dsddec.c:71
AVFrame * out
Definition swscale.c:71
#define src
Definition vp8dsp.c:248
static FILE * out
Definition movenc.c:55
static AVFormatContext * ctx
Definition movenc.c:49
const char * g
Definition vf_curves.c:128