FFmpeg
anlms_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 ONE
20 #undef ftype
21 #undef SAMPLE_FORMAT
22 #if DEPTH == 32
23 #define SAMPLE_FORMAT float
24 #define ftype float
25 #define ONE 1.f
26 #else
27 #define SAMPLE_FORMAT double
28 #define ftype double
29 #define ONE 1.0
30 #endif
31 
32 #define fn3(a,b) a##_##b
33 #define fn2(a,b) fn3(a,b)
34 #define fn(a) fn2(a, SAMPLE_FORMAT)
35 
36 #if DEPTH == 64
37 static double scalarproduct_double(const double *v1, const double *v2, int len)
38 {
39  double p = 0.0;
40 
41  for (int i = 0; i < len; i++)
42  p += v1[i] * v2[i];
43 
44  return p;
45 }
46 #endif
47 
49  ftype *coeffs, ftype *tmp, int *offset)
50 {
51  const int order = s->order;
52  ftype output;
53 
54  delay[*offset] = sample;
55 
56  memcpy(tmp, coeffs + order - *offset, order * sizeof(ftype));
57 
58 #if DEPTH == 32
59  output = s->fdsp->scalarproduct_float(delay, tmp, s->kernel_size);
60 #else
61  output = scalarproduct_double(delay, tmp, s->kernel_size);
62 #endif
63 
64  if (--(*offset) < 0)
65  *offset = order - 1;
66 
67  return output;
68 }
69 
71  ftype *delay, ftype *coeffs, ftype *tmp, int *offsetp)
72 {
73  const int order = s->order;
74  const ftype leakage = s->leakage;
75  const ftype mu = s->mu;
76  const ftype a = ONE - leakage;
77  ftype sum, output, e, norm, b;
78  int offset = *offsetp;
79 
80  delay[offset + order] = input;
81 
82  output = fn(fir_sample)(s, input, delay, coeffs, tmp, offsetp);
83  e = desired - output;
84 
85 #if DEPTH == 32
86  sum = s->fdsp->scalarproduct_float(delay, delay, s->kernel_size);
87 #else
88  sum = scalarproduct_double(delay, delay, s->kernel_size);
89 #endif
90  norm = s->eps + sum;
91  b = mu * e / norm;
92  if (s->anlmf)
93  b *= e * e;
94 
95  memcpy(tmp, delay + offset, order * sizeof(ftype));
96 
97 #if DEPTH == 32
98  s->fdsp->vector_fmul_scalar(coeffs, coeffs, a, s->kernel_size);
99  s->fdsp->vector_fmac_scalar(coeffs, tmp, b, s->kernel_size);
100 #else
101  s->fdsp->vector_dmul_scalar(coeffs, coeffs, a, s->kernel_size);
102  s->fdsp->vector_dmac_scalar(coeffs, tmp, b, s->kernel_size);
103 #endif
104 
105  memcpy(coeffs + order, coeffs, order * sizeof(ftype));
106 
107  switch (s->output_mode) {
108  case IN_MODE: output = input; break;
109  case DESIRED_MODE: output = desired; break;
110  case OUT_MODE: output = desired - output; break;
111  case NOISE_MODE: output = input - output; break;
112  case ERROR_MODE: break;
113  }
114  return output;
115 }
116 
117 static int fn(filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
118 {
119  AudioNLMSContext *s = ctx->priv;
120  AVFrame *out = arg;
121  const int start = (out->ch_layout.nb_channels * jobnr) / nb_jobs;
122  const int end = (out->ch_layout.nb_channels * (jobnr+1)) / nb_jobs;
123 
124  for (int c = start; c < end; c++) {
125  const ftype *input = (const ftype *)s->frame[0]->extended_data[c];
126  const ftype *desired = (const ftype *)s->frame[1]->extended_data[c];
127  ftype *delay = (ftype *)s->delay->extended_data[c];
128  ftype *coeffs = (ftype *)s->coeffs->extended_data[c];
129  ftype *tmp = (ftype *)s->tmp->extended_data[c];
130  int *offset = (int *)s->offset->extended_data[c];
131  ftype *output = (ftype *)out->extended_data[c];
132 
133  for (int n = 0; n < out->nb_samples; n++) {
134  output[n] = fn(process_sample)(s, input[n], desired[n], delay, coeffs, tmp, offset);
135  if (ctx->is_disabled)
136  output[n] = input[n];
137  }
138  }
139 
140  return 0;
141 }
ftype
#define ftype
Definition: anlms_template.c:28
out
FILE * out
Definition: movenc.c:54
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:225
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:340
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
b
#define b
Definition: input.c:41
ERROR_MODE
@ ERROR_MODE
Definition: af_aap.c:37
s
#define s(width, name)
Definition: cbs_vp9.c:198
ctx
AVFormatContext * ctx
Definition: movenc.c:48
ONE
#define ONE
Definition: anlms_template.c:29
DESIRED_MODE
@ DESIRED_MODE
Definition: af_aap.c:34
arg
const char * arg
Definition: jacosubdec.c:67
filter_channels
static int fn() filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: anlms_template.c:117
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
sample
#define sample
Definition: flacdsp_template.c:44
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
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:245
len
int len
Definition: vorbis_enc_data.h:426
NOISE_MODE
@ NOISE_MODE
Definition: af_aap.c:36
process_sample
static ftype fn() process_sample(AudioNLMSContext *s, ftype input, ftype desired, ftype *delay, ftype *coeffs, ftype *tmp, int *offsetp)
Definition: anlms_template.c:70
AudioNLMSContext
Definition: af_anlms.c:41
IN_MODE
@ IN_MODE
Definition: af_aap.c:33
OUT_MODE
@ OUT_MODE
Definition: af_aap.c:35
fn
#define fn(a)
Definition: anlms_template.c:34
AVFilterContext
An instance of a filter.
Definition: avfilter.h:409
fir_sample
static ftype fn() fir_sample(AudioNLMSContext *s, ftype sample, ftype *delay, ftype *coeffs, ftype *tmp, int *offset)
Definition: anlms_template.c:48