FFmpeg
flacdsp_lpc_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 #include <stdint.h>
20 #include "libavutil/avutil.h"
21 #include "mathops.h"
22 
23 #undef FUNC
24 #undef sum_type
25 #undef MUL
26 #undef CLIP
27 #undef FSUF
28 
29 #define FUNC(n) AV_JOIN(n ## _, SAMPLE_SIZE)
30 
31 #if SAMPLE_SIZE == 32
32 # define sum_type int64_t
33 # define MUL(a, b) MUL64(a, b)
34 # define CLIP(x) av_clipl_int32(x)
35 #else
36 # define sum_type int32_t
37 # define MUL(a, b) ((a) * (b))
38 # define CLIP(x) (x)
39 #endif
40 
41 #define LPC1(x) { \
42  int c = coefs[(x)-1]; \
43  p0 += MUL(c, s); \
44  s = smp[i-(x)+1]; \
45  p1 += MUL(c, s); \
46 }
47 
49  const int32_t *smp, int len, int order,
50  const int32_t *coefs, int shift, int big)
51 {
52  int i;
53  for (i = order; i < len; i += 2) {
54  int s = smp[i-order];
55  sum_type p0 = 0, p1 = 0;
56  if (big) {
57  switch (order) {
58  case 32: LPC1(32)
59  case 31: LPC1(31)
60  case 30: LPC1(30)
61  case 29: LPC1(29)
62  case 28: LPC1(28)
63  case 27: LPC1(27)
64  case 26: LPC1(26)
65  case 25: LPC1(25)
66  case 24: LPC1(24)
67  case 23: LPC1(23)
68  case 22: LPC1(22)
69  case 21: LPC1(21)
70  case 20: LPC1(20)
71  case 19: LPC1(19)
72  case 18: LPC1(18)
73  case 17: LPC1(17)
74  case 16: LPC1(16)
75  case 15: LPC1(15)
76  case 14: LPC1(14)
77  case 13: LPC1(13)
78  case 12: LPC1(12)
79  case 11: LPC1(11)
80  case 10: LPC1(10)
81  case 9: LPC1( 9)
82  LPC1( 8)
83  LPC1( 7)
84  LPC1( 6)
85  LPC1( 5)
86  LPC1( 4)
87  LPC1( 3)
88  LPC1( 2)
89  LPC1( 1)
90  }
91  } else {
92  switch (order) {
93  case 8: LPC1( 8)
94  case 7: LPC1( 7)
95  case 6: LPC1( 6)
96  case 5: LPC1( 5)
97  case 4: LPC1( 4)
98  case 3: LPC1( 3)
99  case 2: LPC1( 2)
100  case 1: LPC1( 1)
101  }
102  }
103  res[i ] = smp[i ] - CLIP(p0 >> shift);
104  res[i+1] = smp[i+1] - CLIP(p1 >> shift);
105  }
106 }
107 
108 static void FUNC(flac_lpc_encode_c)(int32_t *res, const int32_t *smp, int len,
109  int order, const int32_t *coefs, int shift)
110 {
111  int i;
112  for (i = 0; i < order; i++)
113  res[i] = smp[i];
114 #if CONFIG_SMALL
115  for (i = order; i < len; i += 2) {
116  int j;
117  int s = smp[i];
118  sum_type p0 = 0, p1 = 0;
119  for (j = 0; j < order; j++) {
120  int c = coefs[j];
121  p1 += MUL(c, s);
122  s = smp[i-j-1];
123  p0 += MUL(c, s);
124  }
125  res[i ] = smp[i ] - CLIP(p0 >> shift);
126  res[i+1] = smp[i+1] - CLIP(p1 >> shift);
127  }
128 #else
129  switch (order) {
130  case 1: FUNC(lpc_encode_unrolled)(res, smp, len, 1, coefs, shift, 0); break;
131  case 2: FUNC(lpc_encode_unrolled)(res, smp, len, 2, coefs, shift, 0); break;
132  case 3: FUNC(lpc_encode_unrolled)(res, smp, len, 3, coefs, shift, 0); break;
133  case 4: FUNC(lpc_encode_unrolled)(res, smp, len, 4, coefs, shift, 0); break;
134  case 5: FUNC(lpc_encode_unrolled)(res, smp, len, 5, coefs, shift, 0); break;
135  case 6: FUNC(lpc_encode_unrolled)(res, smp, len, 6, coefs, shift, 0); break;
136  case 7: FUNC(lpc_encode_unrolled)(res, smp, len, 7, coefs, shift, 0); break;
137  case 8: FUNC(lpc_encode_unrolled)(res, smp, len, 8, coefs, shift, 0); break;
138  default: FUNC(lpc_encode_unrolled)(res, smp, len, order, coefs, shift, 1); break;
139  }
140 #endif
141 }
142 
143 /* Comment for clarity/de-obfuscation.
144  *
145  * for (int i = order; i < len; i++) {
146  * int32_t p = 0;
147  * for (int j = 0; j < order; j++) {
148  * int c = coefs[j];
149  * int s = smp[(i-1)-j];
150  * p += c*s;
151  * }
152  * res[i] = smp[i] - (p >> shift);
153  * }
154  *
155  * The CONFIG_SMALL code above simplifies to this, in the case of SAMPLE_SIZE
156  * not being equal to 32 (at the present time that means for 16-bit audio). The
157  * code above does 2 samples per iteration. Commit bfdd5bc (made all the way
158  * back in 2007) says that way is faster.
159  */
#define LPC1(x)
static int shift(int a, int b)
Definition: sonic.c:82
static av_always_inline void FUNC() lpc_encode_unrolled(int32_t *res, const int32_t *smp, int len, int order, const int32_t *coefs, int shift, int big)
Convenience header that includes libavutil&#39;s core.
#define CLIP(x)
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
#define sum_type
static void FUNC() flac_lpc_encode_c(int32_t *res, const int32_t *smp, int len, int order, const int32_t *coefs, int shift)
int32_t
#define s(width, name)
Definition: cbs_vp9.c:257
#define MUL(a, b)
#define FUNC(n)
int len
#define av_always_inline
Definition: attributes.h:45
int i
Definition: input.c:407