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 
37  ftype *coeffs, ftype *tmp, int *offset)
38 {
39  const int order = s->order;
40  ftype output;
41 
42  delay[*offset] = sample;
43 
44  memcpy(tmp, coeffs + order - *offset, order * sizeof(ftype));
45 
46 #if DEPTH == 32
47  output = s->fdsp->scalarproduct_float(delay, tmp, s->kernel_size);
48 #else
49  output = s->fdsp->scalarproduct_double(delay, tmp, s->kernel_size);
50 #endif
51 
52  if (--(*offset) < 0)
53  *offset = order - 1;
54 
55  return output;
56 }
57 
59  ftype *delay, ftype *coeffs, ftype *tmp, int *offsetp)
60 {
61  const int order = s->order;
62  const ftype leakage = s->leakage;
63  const ftype mu = s->mu;
64  const ftype a = ONE - leakage;
65  ftype sum, output, e, norm, b;
66  int offset = *offsetp;
67 
68  delay[offset + order] = input;
69 
70  output = fn(fir_sample)(s, input, delay, coeffs, tmp, offsetp);
71  e = desired - output;
72 
73 #if DEPTH == 32
74  sum = s->fdsp->scalarproduct_float(delay, delay, s->kernel_size);
75 #else
76  sum = s->fdsp->scalarproduct_double(delay, delay, s->kernel_size);
77 #endif
78  norm = s->eps + sum;
79  b = mu * e / norm;
80  if (s->anlmf)
81  b *= e * e;
82 
83  memcpy(tmp, delay + offset, order * sizeof(ftype));
84 
85 #if DEPTH == 32
86  s->fdsp->vector_fmul_scalar(coeffs, coeffs, a, s->kernel_size);
87  s->fdsp->vector_fmac_scalar(coeffs, tmp, b, s->kernel_size);
88 #else
89  s->fdsp->vector_dmul_scalar(coeffs, coeffs, a, s->kernel_size);
90  s->fdsp->vector_dmac_scalar(coeffs, tmp, b, s->kernel_size);
91 #endif
92 
93  memcpy(coeffs + order, coeffs, order * sizeof(ftype));
94 
95  switch (s->output_mode) {
96  case IN_MODE: output = input; break;
97  case DESIRED_MODE: output = desired; break;
98  case OUT_MODE: output = desired - output; break;
99  case NOISE_MODE: output = input - output; break;
100  case ERROR_MODE: break;
101  }
102  return output;
103 }
104 
105 static int fn(filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
106 {
107  AudioNLMSContext *s = ctx->priv;
108  AVFrame *out = arg;
109  const int start = (out->ch_layout.nb_channels * jobnr) / nb_jobs;
110  const int end = (out->ch_layout.nb_channels * (jobnr+1)) / nb_jobs;
111 
112  for (int c = start; c < end; c++) {
113  const ftype *input = (const ftype *)s->frame[0]->extended_data[c];
114  const ftype *desired = (const ftype *)s->frame[1]->extended_data[c];
115  ftype *delay = (ftype *)s->delay->extended_data[c];
116  ftype *coeffs = (ftype *)s->coeffs->extended_data[c];
117  ftype *tmp = (ftype *)s->tmp->extended_data[c];
118  int *offset = (int *)s->offset->extended_data[c];
119  ftype *output = (ftype *)out->extended_data[c];
120 
121  for (int n = 0; n < out->nb_samples; n++) {
122  output[n] = fn(process_sample)(s, input[n], desired[n], delay, coeffs, tmp, offset);
123  if (ctx->is_disabled)
124  output[n] = input[n];
125  }
126  }
127 
128  return 0;
129 }
ftype
#define ftype
Definition: anlms_template.c:28
out
FILE * out
Definition: movenc.c:55
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:389
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:49
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:105
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
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:58
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:457
fir_sample
static ftype fn() fir_sample(AudioNLMSContext *s, ftype sample, ftype *delay, ftype *coeffs, ftype *tmp, int *offset)
Definition: anlms_template.c:36