FFmpeg
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 
84 static 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 
206 static void fn(queue_sample)(ChannelContext *cc,
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 
243 static ftype fn(get_peak)(ChannelContext *cc, ftype *score)
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 
251 static 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 = (in->ch_layout.nb_channels * jobnr) / nb_jobs;
273  const int end = (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 }
CUT_BELOW
@ CUT_BELOW
Definition: af_adynamicequalizer.c:40
out
FILE * out
Definition: movenc.c:55
LIN2LOG
#define LIN2LOG(x)
Definition: adynamicequalizer_template.c:77
mode
Definition: swscale.c:52
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:389
DET_ADAPTIVE
@ DET_ADAPTIVE
Definition: af_adynamicequalizer.c:34
b
#define b
Definition: input.c:41
FABS
#define FABS
Definition: adynamicequalizer_template.c:66
fn
#define fn(a)
Definition: adynamicequalizer_template.c:82
DET_ON
@ DET_ON
Definition: af_adynamicequalizer.c:33
CLIP
#define CLIP
Definition: adynamicequalizer_template.c:65
ChannelContext::detection
int detection
Definition: af_adynamicequalizer.c:74
ThreadData::out
AVFrame * out
Definition: af_adeclick.c:526
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:327
ThreadData::in
AVFrame * in
Definition: af_adecorrelate.c:155
get_coef
static double get_coef(double x, double sr)
Definition: af_adynamicequalizer.c:132
FMAX
#define FMAX
Definition: adynamicequalizer_template.c:64
FMIN
#define FMIN
Definition: adynamicequalizer_template.c:63
ChannelContext::init
int init
Definition: af_adynamicequalizer.c:75
AVFrame::ch_layout
AVChannelLayout ch_layout
Channel layout of the audio data.
Definition: frame.h:790
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:202
s
#define s(width, name)
Definition: cbs_vp9.c:198
EPSILON
#define EPSILON
Definition: adynamicequalizer_template.c:73
g
const char * g
Definition: vf_curves.c:128
filter_channels
static int fn() filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: adynamicequalizer_template.c:251
ctx
AVFormatContext * ctx
Definition: movenc.c:49
BOOST_ABOVE
@ BOOST_ABOVE
Definition: af_adynamicequalizer.c:43
arg
const char * arg
Definition: jacosubdec.c:67
FLOG2
#define FLOG2
Definition: adynamicequalizer_template.c:69
DET_OFF
@ DET_OFF
Definition: af_adynamicequalizer.c:32
LOG2LIN
#define LOG2LIN(x)
Definition: adynamicequalizer_template.c:78
LISTEN
@ LISTEN
Definition: af_adynamicequalizer.c:39
TWO
#define TWO
Definition: adynamicequalizer_template.c:61
DET_UNSET
@ DET_UNSET
Definition: af_adynamicequalizer.c:30
f
f
Definition: af_crystalizer.c:122
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
AVFrame::sample_rate
int sample_rate
Sample rate of the audio data.
Definition: frame.h:588
TAN
#define TAN
Definition: adynamicequalizer_template.c:59
BOOST_BELOW
@ BOOST_BELOW
Definition: af_adynamicequalizer.c:42
AudioDynamicEqualizerContext
Definition: af_adynamicequalizer.c:78
range
enum AVColorRange range
Definition: mediacodec_wrapper.c:2594
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
ONE
#define ONE
Definition: adynamicequalizer_template.c:60
M_PI
#define M_PI
Definition: mathematics.h:67
AVFrame::nb_samples
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:469
AVFrame::extended_data
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:450
ThreadData
Used for passing data between threads.
Definition: dsddec.c:71
pos
unsigned int pos
Definition: spdifenc.c:414
SQRT
#define SQRT
Definition: adynamicequalizer_template.c:58
get_svf
static ftype fn() get_svf(ftype in, const ftype *m, const ftype *a, ftype *b)
Definition: adynamicequalizer_template.c:84
PEAKS
#define PEAKS(empty_value, op, sample, psample)
Definition: adynamicequalizer_template.c:165
power
static float power(float r, float g, float b, float max)
Definition: preserve_color.h:45
DET_DISABLED
@ DET_DISABLED
Definition: af_adynamicequalizer.c:31
ChannelContext
Definition: hcadec.c:35
AVFilterContext
An instance of a filter.
Definition: avfilter.h:457
queue_sample
static void fn() queue_sample(ChannelContext *cc, const ftype x, const int nb_samples)
Definition: adynamicequalizer_template.c:206
CUT_ABOVE
@ CUT_ABOVE
Definition: af_adynamicequalizer.c:41
ftype
#define ftype
Definition: adynamicequalizer_template.c:74
ZERO
#define ZERO
Definition: adynamicequalizer_template.c:62
FEXP2
#define FEXP2
Definition: adynamicequalizer_template.c:71
src
#define src
Definition: vp8dsp.c:248
get_peak
static ftype fn() get_peak(ChannelContext *cc, ftype *score)
Definition: adynamicequalizer_template.c:243
filter_prepare
static int fn() filter_prepare(AVFilterContext *ctx)
Definition: adynamicequalizer_template.c:97