summaryrefslogtreecommitdiff
path: root/libs/ffvpx/libavcodec/flacdsp_lpc_template.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ffvpx/libavcodec/flacdsp_lpc_template.c')
-rw-r--r--libs/ffvpx/libavcodec/flacdsp_lpc_template.c159
1 files changed, 159 insertions, 0 deletions
diff --git a/libs/ffvpx/libavcodec/flacdsp_lpc_template.c b/libs/ffvpx/libavcodec/flacdsp_lpc_template.c
new file mode 100644
index 000000000..5d532e067
--- /dev/null
+++ b/libs/ffvpx/libavcodec/flacdsp_lpc_template.c
@@ -0,0 +1,159 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include "libavutil/avutil.h"
+#include "mathops.h"
+
+#undef FUNC
+#undef sum_type
+#undef MUL
+#undef CLIP
+#undef FSUF
+
+#define FUNC(n) AV_JOIN(n ## _, SAMPLE_SIZE)
+
+#if SAMPLE_SIZE == 32
+# define sum_type int64_t
+# define MUL(a, b) MUL64(a, b)
+# define CLIP(x) av_clipl_int32(x)
+#else
+# define sum_type int32_t
+# define MUL(a, b) ((a) * (b))
+# define CLIP(x) (x)
+#endif
+
+#define LPC1(x) { \
+ int c = coefs[(x)-1]; \
+ p0 += MUL(c, s); \
+ s = smp[i-(x)+1]; \
+ p1 += MUL(c, s); \
+}
+
+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)
+{
+ int i;
+ for (i = order; i < len; i += 2) {
+ int s = smp[i-order];
+ sum_type p0 = 0, p1 = 0;
+ if (big) {
+ switch (order) {
+ case 32: LPC1(32)
+ case 31: LPC1(31)
+ case 30: LPC1(30)
+ case 29: LPC1(29)
+ case 28: LPC1(28)
+ case 27: LPC1(27)
+ case 26: LPC1(26)
+ case 25: LPC1(25)
+ case 24: LPC1(24)
+ case 23: LPC1(23)
+ case 22: LPC1(22)
+ case 21: LPC1(21)
+ case 20: LPC1(20)
+ case 19: LPC1(19)
+ case 18: LPC1(18)
+ case 17: LPC1(17)
+ case 16: LPC1(16)
+ case 15: LPC1(15)
+ case 14: LPC1(14)
+ case 13: LPC1(13)
+ case 12: LPC1(12)
+ case 11: LPC1(11)
+ case 10: LPC1(10)
+ case 9: LPC1( 9)
+ LPC1( 8)
+ LPC1( 7)
+ LPC1( 6)
+ LPC1( 5)
+ LPC1( 4)
+ LPC1( 3)
+ LPC1( 2)
+ LPC1( 1)
+ }
+ } else {
+ switch (order) {
+ case 8: LPC1( 8)
+ case 7: LPC1( 7)
+ case 6: LPC1( 6)
+ case 5: LPC1( 5)
+ case 4: LPC1( 4)
+ case 3: LPC1( 3)
+ case 2: LPC1( 2)
+ case 1: LPC1( 1)
+ }
+ }
+ res[i ] = smp[i ] - CLIP(p0 >> shift);
+ res[i+1] = smp[i+1] - CLIP(p1 >> shift);
+ }
+}
+
+static void FUNC(flac_lpc_encode_c)(int32_t *res, const int32_t *smp, int len,
+ int order, const int32_t *coefs, int shift)
+{
+ int i;
+ for (i = 0; i < order; i++)
+ res[i] = smp[i];
+#if CONFIG_SMALL
+ for (i = order; i < len; i += 2) {
+ int j;
+ int s = smp[i];
+ sum_type p0 = 0, p1 = 0;
+ for (j = 0; j < order; j++) {
+ int c = coefs[j];
+ p1 += MUL(c, s);
+ s = smp[i-j-1];
+ p0 += MUL(c, s);
+ }
+ res[i ] = smp[i ] - CLIP(p0 >> shift);
+ res[i+1] = smp[i+1] - CLIP(p1 >> shift);
+ }
+#else
+ switch (order) {
+ case 1: FUNC(lpc_encode_unrolled)(res, smp, len, 1, coefs, shift, 0); break;
+ case 2: FUNC(lpc_encode_unrolled)(res, smp, len, 2, coefs, shift, 0); break;
+ case 3: FUNC(lpc_encode_unrolled)(res, smp, len, 3, coefs, shift, 0); break;
+ case 4: FUNC(lpc_encode_unrolled)(res, smp, len, 4, coefs, shift, 0); break;
+ case 5: FUNC(lpc_encode_unrolled)(res, smp, len, 5, coefs, shift, 0); break;
+ case 6: FUNC(lpc_encode_unrolled)(res, smp, len, 6, coefs, shift, 0); break;
+ case 7: FUNC(lpc_encode_unrolled)(res, smp, len, 7, coefs, shift, 0); break;
+ case 8: FUNC(lpc_encode_unrolled)(res, smp, len, 8, coefs, shift, 0); break;
+ default: FUNC(lpc_encode_unrolled)(res, smp, len, order, coefs, shift, 1); break;
+ }
+#endif
+}
+
+/* Comment for clarity/de-obfuscation.
+ *
+ * for (int i = order; i < len; i++) {
+ * int32_t p = 0;
+ * for (int j = 0; j < order; j++) {
+ * int c = coefs[j];
+ * int s = smp[(i-1)-j];
+ * p += c*s;
+ * }
+ * res[i] = smp[i] - (p >> shift);
+ * }
+ *
+ * The CONFIG_SMALL code above simplifies to this, in the case of SAMPLE_SIZE
+ * not being equal to 32 (at the present time that means for 16-bit audio). The
+ * code above does 2 samples per iteration. Commit bfdd5bc (made all the way
+ * back in 2007) says that way is faster.
+ */