FFmpeg
arls_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 ZERO
20 #undef HALF
21 #undef ONE
22 #undef ftype
23 #undef SAMPLE_FORMAT
24 #if DEPTH == 32
25 #define SAMPLE_FORMAT float
26 #define ftype float
27 #define ONE 1.f
28 #define HALF 0.5f
29 #define ZERO 0.f
30 #else
31 #define SAMPLE_FORMAT double
32 #define ftype double
33 #define ONE 1.0
34 #define HALF 0.5
35 #define ZERO 0.0
36 #endif
37 
38 #define fn3(a,b) a##_##b
39 #define fn2(a,b) fn3(a,b)
40 #define fn(a) fn2(a, SAMPLE_FORMAT)
41 
42 #if DEPTH == 64
43 static double scalarproduct_double(const double *v1, const double *v2, int len)
44 {
45  double p = 0.0;
46 
47  for (int i = 0; i < len; i++)
48  p += v1[i] * v2[i];
49 
50  return p;
51 }
52 #endif
53 
55  ftype *coeffs, ftype *tmp, int *offset)
56 {
57  const int order = s->order;
58  ftype output;
59 
60  delay[*offset] = sample;
61 
62  memcpy(tmp, coeffs + order - *offset, order * sizeof(ftype));
63 
64 #if DEPTH == 32
65  output = s->fdsp->scalarproduct_float(delay, tmp, s->kernel_size);
66 #else
67  output = scalarproduct_double(delay, tmp, s->kernel_size);
68 #endif
69 
70  if (--(*offset) < 0)
71  *offset = order - 1;
72 
73  return output;
74 }
75 
76 static ftype fn(process_sample)(AudioRLSContext *s, ftype input, ftype desired, int ch)
77 {
78  ftype *coeffs = (ftype *)s->coeffs->extended_data[ch];
79  ftype *delay = (ftype *)s->delay->extended_data[ch];
80  ftype *gains = (ftype *)s->gains->extended_data[ch];
81  ftype *tmp = (ftype *)s->tmp->extended_data[ch];
82  ftype *u = (ftype *)s->u->extended_data[ch];
83  ftype *p = (ftype *)s->p->extended_data[ch];
84  ftype *dp = (ftype *)s->dp->extended_data[ch];
85  int *offsetp = (int *)s->offset->extended_data[ch];
86  const int kernel_size = s->kernel_size;
87  const int order = s->order;
88  const ftype lambda = s->lambda;
89  int offset = *offsetp;
90  ftype g = lambda;
91  ftype output, e;
92 
93  delay[offset + order] = input;
94 
95  output = fn(fir_sample)(s, input, delay, coeffs, tmp, offsetp);
96  e = desired - output;
97 
98  for (int i = 0, pos = offset; i < order; i++, pos++) {
99  const int ikernel_size = i * kernel_size;
100 
101  u[i] = ZERO;
102  for (int k = 0, pos = offset; k < order; k++, pos++)
103  u[i] += p[ikernel_size + k] * delay[pos];
104 
105  g += u[i] * delay[pos];
106  }
107 
108  g = ONE / g;
109 
110  for (int i = 0; i < order; i++) {
111  const int ikernel_size = i * kernel_size;
112 
113  gains[i] = u[i] * g;
114  coeffs[i] = coeffs[order + i] = coeffs[i] + gains[i] * e;
115  tmp[i] = ZERO;
116  for (int k = 0, pos = offset; k < order; k++, pos++)
117  tmp[i] += p[ikernel_size + k] * delay[pos];
118  }
119 
120  for (int i = 0; i < order; i++) {
121  const int ikernel_size = i * kernel_size;
122 
123  for (int k = 0; k < order; k++)
124  dp[ikernel_size + k] = gains[i] * tmp[k];
125  }
126 
127  for (int i = 0; i < order; i++) {
128  const int ikernel_size = i * kernel_size;
129 
130  for (int k = 0; k < order; k++)
131  p[ikernel_size + k] = (p[ikernel_size + k] - (dp[ikernel_size + k] + dp[kernel_size * k + i]) * HALF) * lambda;
132  }
133 
134  switch (s->output_mode) {
135  case IN_MODE: output = input; break;
136  case DESIRED_MODE: output = desired; break;
137  case OUT_MODE: output = desired - output; break;
138  case NOISE_MODE: output = input - output; break;
139  case ERROR_MODE: break;
140  }
141  return output;
142 }
143 
144 static int fn(filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
145 {
146  AudioRLSContext *s = ctx->priv;
147  AVFrame *out = arg;
148  const int start = (out->ch_layout.nb_channels * jobnr) / nb_jobs;
149  const int end = (out->ch_layout.nb_channels * (jobnr+1)) / nb_jobs;
150 
151  for (int c = start; c < end; c++) {
152  const ftype *input = (const ftype *)s->frame[0]->extended_data[c];
153  const ftype *desired = (const ftype *)s->frame[1]->extended_data[c];
154  ftype *output = (ftype *)out->extended_data[c];
155 
156  for (int n = 0; n < out->nb_samples; n++) {
157  output[n] = fn(process_sample)(s, input[n], desired[n], c);
158  if (ctx->is_disabled)
159  output[n] = input[n];
160  }
161  }
162 
163  return 0;
164 }
out
FILE * out
Definition: movenc.c:55
u
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:251
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:374
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
fir_sample
static ftype fn() fir_sample(AudioRLSContext *s, ftype sample, ftype *delay, ftype *coeffs, ftype *tmp, int *offset)
Definition: arls_template.c:54
HALF
#define HALF
Definition: arls_template.c:34
ftype
#define ftype
Definition: arls_template.c:32
process_sample
static ftype fn() process_sample(AudioRLSContext *s, ftype input, ftype desired, int ch)
Definition: arls_template.c:76
ERROR_MODE
@ ERROR_MODE
Definition: af_aap.c:38
s
#define s(width, name)
Definition: cbs_vp9.c:198
g
const char * g
Definition: vf_curves.c:128
fn
#define fn(a)
Definition: arls_template.c:40
ctx
AVFormatContext * ctx
Definition: movenc.c:49
DESIRED_MODE
@ DESIRED_MODE
Definition: af_aap.c:35
arg
const char * arg
Definition: jacosubdec.c:67
ZERO
#define ZERO
Definition: arls_template.c:35
ONE
#define ONE
Definition: arls_template.c:33
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
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:256
filter_channels
static int fn() filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: arls_template.c:144
len
int len
Definition: vorbis_enc_data.h:426
NOISE_MODE
@ NOISE_MODE
Definition: af_aap.c:37
pos
unsigned int pos
Definition: spdifenc.c:414
IN_MODE
@ IN_MODE
Definition: af_aap.c:34
OUT_MODE
@ OUT_MODE
Definition: af_aap.c:36
AVFilterContext
An instance of a filter.
Definition: avfilter.h:407
AudioRLSContext
Definition: af_arls.c:41