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 EPSILON
30 #undef FABS
31 #if DEPTH == 32
32 #define SAMPLE_FORMAT float
33 #define SQRT sqrtf
34 #define TAN tanf
35 #define ONE 1.f
36 #define TWO 2.f
37 #define ZERO 0.f
38 #define FMIN fminf
39 #define FMAX fmaxf
40 #define CLIP av_clipf
41 #define FABS fabsf
42 #define ftype float
43 #define EPSILON (1.f / (1 << 22))
44 #else
45 #define SAMPLE_FORMAT double
46 #define SQRT sqrt
47 #define TAN tan
48 #define ONE 1.0
49 #define TWO 2.0
50 #define ZERO 0.0
51 #define FMIN fmin
52 #define FMAX fmax
53 #define CLIP av_clipd
54 #define FABS fabs
55 #define ftype double
56 #define EPSILON (1.0 / (1LL << 51))
57 #endif
58 
59 #define fn3(a,b) a##_##b
60 #define fn2(a,b) fn3(a,b)
61 #define fn(a) fn2(a, SAMPLE_FORMAT)
62 
63 static ftype fn(get_svf)(ftype in, const ftype *m, const ftype *a, ftype *b)
64 {
65  const ftype v0 = in;
66  const ftype v3 = v0 - b[1];
67  const ftype v1 = a[0] * b[0] + a[1] * v3;
68  const ftype v2 = b[1] + a[1] * b[0] + a[2] * v3;
69 
70  b[0] = TWO * v1 - b[0];
71  b[1] = TWO * v2 - b[1];
72 
73  return m[0] * v0 + m[1] * v1 + m[2] * v2;
74 }
75 
77 {
79  const ftype sample_rate = ctx->inputs[0]->sample_rate;
80  const ftype dfrequency = FMIN(s->dfrequency, sample_rate * 0.5);
81  const ftype dg = TAN(M_PI * dfrequency / sample_rate);
82  const ftype dqfactor = s->dqfactor;
83  const int dftype = s->dftype;
84  ftype *da = fn(s->da);
85  ftype *dm = fn(s->dm);
86  ftype k;
87 
88  s->attack_coef = get_coef(s->attack, sample_rate);
89  s->release_coef = get_coef(s->release, sample_rate);
90 
91  switch (dftype) {
92  case 0:
93  k = ONE / dqfactor;
94 
95  da[0] = ONE / (ONE + dg * (dg + k));
96  da[1] = dg * da[0];
97  da[2] = dg * da[1];
98 
99  dm[0] = ZERO;
100  dm[1] = k;
101  dm[2] = ZERO;
102  break;
103  case 1:
104  k = ONE / dqfactor;
105 
106  da[0] = ONE / (ONE + dg * (dg + k));
107  da[1] = dg * da[0];
108  da[2] = dg * da[1];
109 
110  dm[0] = ZERO;
111  dm[1] = ZERO;
112  dm[2] = ONE;
113  break;
114  case 2:
115  k = ONE / dqfactor;
116 
117  da[0] = ONE / (ONE + dg * (dg + k));
118  da[1] = dg * da[0];
119  da[2] = dg * da[1];
120 
121  dm[0] = ZERO;
122  dm[1] = -k;
123  dm[2] = -ONE;
124  break;
125  case 3:
126  k = ONE / dqfactor;
127 
128  da[0] = ONE / (ONE + dg * (dg + k));
129  da[1] = dg * da[0];
130  da[2] = dg * da[1];
131 
132  dm[0] = ONE;
133  dm[1] = -k;
134  dm[2] = -TWO;
135  break;
136  }
137 
138  return 0;
139 }
140 
141 static int fn(filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
142 {
144  ThreadData *td = arg;
145  AVFrame *in = td->in;
146  AVFrame *out = td->out;
147  const ftype sample_rate = in->sample_rate;
148  const ftype makeup = s->makeup;
149  const ftype ratio = s->ratio;
150  const ftype range = s->range;
151  const ftype tfrequency = FMIN(s->tfrequency, sample_rate * 0.5);
152  const ftype release = s->release_coef;
153  const ftype attack = s->attack_coef;
154  const ftype tqfactor = s->tqfactor;
155  const ftype itqfactor = ONE / tqfactor;
156  const ftype fg = TAN(M_PI * tfrequency / sample_rate);
157  const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs;
158  const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs;
159  const int detection = s->detection;
160  const int direction = s->direction;
161  const int tftype = s->tftype;
162  const int mode = s->mode;
163  const ftype *da = fn(s->da);
164  const ftype *dm = fn(s->dm);
165 
166  for (int ch = start; ch < end; ch++) {
167  const ftype *src = (const ftype *)in->extended_data[ch];
168  ftype *dst = (ftype *)out->extended_data[ch];
169  ftype *state = (ftype *)s->state->extended_data[ch];
170  const ftype threshold = detection == 0 ? state[5] : s->threshold;
171  ftype fa[3], fm[3];
172 
173  if (detection < 0)
174  state[5] = threshold;
175 
176  memcpy(fa, state + 8, sizeof(fa));
177  memcpy(fm, state + 11, sizeof(fm));
178 
179  for (int n = 0; n < out->nb_samples; n++) {
180  ftype detect, gain, v, listen;
181  ftype k, g;
182 
183  detect = listen = fn(get_svf)(src[n], dm, da, state);
184  detect = FABS(detect);
185 
186  if (detection > 0)
187  state[5] = FMAX(state[5], detect);
188 
189  if (mode >= 0) {
190  if (direction == 0 && detect < threshold) {
191  detect = CLIP(ONE + makeup + (threshold - detect) * ratio, ONE, range);
192  if (!mode)
193  detect = ONE / detect;
194  } else if (direction == 1 && detect > threshold) {
195  detect = CLIP(ONE + makeup + (detect - threshold) * ratio, ONE, range);
196  if (!mode)
197  detect = ONE / detect;
198  } else {
199  detect = ONE;
200  }
201 
202  {
203  ftype delta = detect - state[4];
204 
205  if (delta > EPSILON)
206  detect = state[4] + attack * delta;
207  else if (delta < -EPSILON)
208  detect = state[4] + release * delta;
209  }
210  }
211 
212  if (state[4] != detect) {
213  state[4] = gain = detect;
214 
215  switch (tftype) {
216  case 0:
217  k = itqfactor / gain;
218 
219  fa[0] = ONE / (ONE + fg * (fg + k));
220  fa[1] = fg * fa[0];
221  fa[2] = fg * fa[1];
222 
223  fm[0] = ONE;
224  fm[1] = k * (gain * gain - ONE);
225  fm[2] = ZERO;
226  break;
227  case 1:
228  k = itqfactor;
229  g = fg / SQRT(gain);
230 
231  fa[0] = ONE / (ONE + g * (g + k));
232  fa[1] = g * fa[0];
233  fa[2] = g * fa[1];
234 
235  fm[0] = ONE;
236  fm[1] = k * (gain - ONE);
237  fm[2] = gain * gain - ONE;
238  break;
239  case 2:
240  k = itqfactor;
241  g = fg * SQRT(gain);
242 
243  fa[0] = ONE / (ONE + g * (g + k));
244  fa[1] = g * fa[0];
245  fa[2] = g * fa[1];
246 
247  fm[0] = gain * gain;
248  fm[1] = k * (ONE - gain) * gain;
249  fm[2] = ONE - gain * gain;
250  break;
251  }
252  }
253 
254  v = fn(get_svf)(src[n], fm, fa, &state[2]);
255  v = mode == -1 ? listen : v;
256  dst[n] = ctx->is_disabled ? src[n] : v;
257  }
258 
259  memcpy(state + 8, fa, sizeof(fa));
260  memcpy(state + 11, fm, sizeof(fm));
261  }
262 
263  return 0;
264 }
td
#define td
Definition: regdef.h:70
out
FILE * out
Definition: movenc.c:54
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:340
b
#define b
Definition: input.c:41
FABS
#define FABS
Definition: adynamicequalizer_template.c:54
fn
#define fn(a)
Definition: adynamicequalizer_template.c:61
CLIP
#define CLIP
Definition: adynamicequalizer_template.c:53
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:317
get_coef
static double get_coef(double x, double sr)
Definition: af_adynamicequalizer.c:77
sample_rate
sample_rate
Definition: ffmpeg_filter.c:368
FMAX
#define FMAX
Definition: adynamicequalizer_template.c:52
v0
#define v0
Definition: regdef.h:26
FMIN
#define FMIN
Definition: adynamicequalizer_template.c:51
AVFrame::ch_layout
AVChannelLayout ch_layout
Channel layout of the audio data.
Definition: frame.h:802
s
#define s(width, name)
Definition: cbs_vp9.c:198
EPSILON
#define EPSILON
Definition: adynamicequalizer_template.c:56
g
const char * g
Definition: vf_curves.c:127
filter_channels
static int fn() filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: adynamicequalizer_template.c:141
ctx
AVFormatContext * ctx
Definition: movenc.c:48
arg
const char * arg
Definition: jacosubdec.c:67
if
if(ret)
Definition: filter_design.txt:179
TWO
#define TWO
Definition: adynamicequalizer_template.c:49
AVFrame::sample_rate
int sample_rate
Sample rate of the audio data.
Definition: frame.h:567
TAN
#define TAN
Definition: adynamicequalizer_template.c:47
AudioDynamicEqualizerContext
Definition: af_adynamicequalizer.c:26
range
enum AVColorRange range
Definition: mediacodec_wrapper.c:2646
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:48
M_PI
#define M_PI
Definition: mathematics.h:67
AVFrame::extended_data
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:401
delta
float delta
Definition: vorbis_enc_data.h:430
ThreadData
Used for passing data between threads.
Definition: dsddec.c:69
SQRT
#define SQRT
Definition: adynamicequalizer_template.c:46
get_svf
static ftype fn() get_svf(ftype in, const ftype *m, const ftype *a, ftype *b)
Definition: adynamicequalizer_template.c:63
mode
mode
Definition: ebur128.h:83
state
static struct @362 state
AVFilterContext
An instance of a filter.
Definition: avfilter.h:397
ftype
#define ftype
Definition: adynamicequalizer_template.c:55
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
ZERO
#define ZERO
Definition: adynamicequalizer_template.c:50
filter_prepare
static int fn() filter_prepare(AVFilterContext *ctx)
Definition: adynamicequalizer_template.c:76