add fixed-point functions
diff --git a/src/libFLAC/float.c b/src/libFLAC/float.c
new file mode 100644
index 0000000..a0b4617
--- /dev/null
+++ b/src/libFLAC/float.c
@@ -0,0 +1,304 @@
+/* libFLAC - Free Lossless Audio Codec library
+ * Copyright (C) 2004 Josh Coalson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Xiph.org Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "FLAC/assert.h"
+
+#include "private/float.h"
+
+#ifdef FLAC__INTEGER_ONLY_LIBRARY
+
+/* adjust for compilers that can't understand using LLU suffix for uint64_t literals */
+#ifdef _MSC_VER
+#define FLAC__U64L(x) x
+#else
+#define FLAC__U64L(x) x##LLU
+#endif
+
+const FLAC__fixedpoint FLAC__FP_ZERO = 0;
+const FLAC__fixedpoint FLAC__FP_ONE_HALF = 0x00008000;
+const FLAC__fixedpoint FLAC__FP_ONE = 0x00010000;
+const FLAC__fixedpoint FLAC__FP_LN2 = 45426;
+const FLAC__fixedpoint FLAC__FP_E = 178145;
+
+/* Lookup tables for Knuth's logarithm algorithm */
+#define LOG2_LOOKUP_PRECISION 16
+static const FLAC__uint32 log2_lookup[][LOG2_LOOKUP_PRECISION] = {
+ {
+ /*
+ * 0 fraction bits
+ */
+ /* undefined */ 0x00000000,
+ /* lg(2/1) = */ 0x00000001,
+ /* lg(4/3) = */ 0x00000000,
+ /* lg(8/7) = */ 0x00000000,
+ /* lg(16/15) = */ 0x00000000,
+ /* lg(32/31) = */ 0x00000000,
+ /* lg(64/63) = */ 0x00000000,
+ /* lg(128/127) = */ 0x00000000,
+ /* lg(256/255) = */ 0x00000000,
+ /* lg(512/511) = */ 0x00000000,
+ /* lg(1024/1023) = */ 0x00000000,
+ /* lg(2048/2047) = */ 0x00000000,
+ /* lg(4096/4095) = */ 0x00000000,
+ /* lg(8192/8191) = */ 0x00000000,
+ /* lg(16384/16383) = */ 0x00000000,
+ /* lg(32768/32767) = */ 0x00000000
+ },
+ {
+ /*
+ * 4 fraction bits
+ */
+ /* undefined */ 0x00000000,
+ /* lg(2/1) = */ 0x00000010,
+ /* lg(4/3) = */ 0x00000007,
+ /* lg(8/7) = */ 0x00000003,
+ /* lg(16/15) = */ 0x00000001,
+ /* lg(32/31) = */ 0x00000001,
+ /* lg(64/63) = */ 0x00000000,
+ /* lg(128/127) = */ 0x00000000,
+ /* lg(256/255) = */ 0x00000000,
+ /* lg(512/511) = */ 0x00000000,
+ /* lg(1024/1023) = */ 0x00000000,
+ /* lg(2048/2047) = */ 0x00000000,
+ /* lg(4096/4095) = */ 0x00000000,
+ /* lg(8192/8191) = */ 0x00000000,
+ /* lg(16384/16383) = */ 0x00000000,
+ /* lg(32768/32767) = */ 0x00000000
+ },
+ {
+ /*
+ * 8 fraction bits
+ */
+ /* undefined */ 0x00000000,
+ /* lg(2/1) = */ 0x00000100,
+ /* lg(4/3) = */ 0x0000006a,
+ /* lg(8/7) = */ 0x00000031,
+ /* lg(16/15) = */ 0x00000018,
+ /* lg(32/31) = */ 0x0000000c,
+ /* lg(64/63) = */ 0x00000006,
+ /* lg(128/127) = */ 0x00000003,
+ /* lg(256/255) = */ 0x00000001,
+ /* lg(512/511) = */ 0x00000001,
+ /* lg(1024/1023) = */ 0x00000000,
+ /* lg(2048/2047) = */ 0x00000000,
+ /* lg(4096/4095) = */ 0x00000000,
+ /* lg(8192/8191) = */ 0x00000000,
+ /* lg(16384/16383) = */ 0x00000000,
+ /* lg(32768/32767) = */ 0x00000000
+ },
+ {
+ /*
+ * 12 fraction bits
+ */
+ /* undefined */ 0x00000000,
+ /* lg(2/1) = */ 0x00001000,
+ /* lg(4/3) = */ 0x000006a4,
+ /* lg(8/7) = */ 0x00000315,
+ /* lg(16/15) = */ 0x0000017d,
+ /* lg(32/31) = */ 0x000000bc,
+ /* lg(64/63) = */ 0x0000005d,
+ /* lg(128/127) = */ 0x0000002e,
+ /* lg(256/255) = */ 0x00000017,
+ /* lg(512/511) = */ 0x0000000c,
+ /* lg(1024/1023) = */ 0x00000006,
+ /* lg(2048/2047) = */ 0x00000003,
+ /* lg(4096/4095) = */ 0x00000001,
+ /* lg(8192/8191) = */ 0x00000001,
+ /* lg(16384/16383) = */ 0x00000000,
+ /* lg(32768/32767) = */ 0x00000000
+ },
+ {
+ /*
+ * 16 fraction bits
+ */
+ /* undefined */ 0x00000000,
+ /* lg(2/1) = */ 0x00010000,
+ /* lg(4/3) = */ 0x00006a40,
+ /* lg(8/7) = */ 0x00003151,
+ /* lg(16/15) = */ 0x000017d6,
+ /* lg(32/31) = */ 0x00000bba,
+ /* lg(64/63) = */ 0x000005d1,
+ /* lg(128/127) = */ 0x000002e6,
+ /* lg(256/255) = */ 0x00000172,
+ /* lg(512/511) = */ 0x000000b9,
+ /* lg(1024/1023) = */ 0x0000005c,
+ /* lg(2048/2047) = */ 0x0000002e,
+ /* lg(4096/4095) = */ 0x00000017,
+ /* lg(8192/8191) = */ 0x0000000c,
+ /* lg(16384/16383) = */ 0x00000006,
+ /* lg(32768/32767) = */ 0x00000003
+ },
+ {
+ /*
+ * 20 fraction bits
+ */
+ /* undefined */ 0x00000000,
+ /* lg(2/1) = */ 0x00100000,
+ /* lg(4/3) = */ 0x0006a3fe,
+ /* lg(8/7) = */ 0x00031513,
+ /* lg(16/15) = */ 0x00017d60,
+ /* lg(32/31) = */ 0x0000bb9d,
+ /* lg(64/63) = */ 0x00005d10,
+ /* lg(128/127) = */ 0x00002e59,
+ /* lg(256/255) = */ 0x00001721,
+ /* lg(512/511) = */ 0x00000b8e,
+ /* lg(1024/1023) = */ 0x000005c6,
+ /* lg(2048/2047) = */ 0x000002e3,
+ /* lg(4096/4095) = */ 0x00000171,
+ /* lg(8192/8191) = */ 0x000000b9,
+ /* lg(16384/16383) = */ 0x0000005c,
+ /* lg(32768/32767) = */ 0x0000002e
+ },
+ {
+ /*
+ * 24 fraction bits
+ */
+ /* undefined */ 0x00000000,
+ /* lg(2/1) = */ 0x01000000,
+ /* lg(4/3) = */ 0x006a3fe6,
+ /* lg(8/7) = */ 0x00315130,
+ /* lg(16/15) = */ 0x0017d605,
+ /* lg(32/31) = */ 0x000bb9ca,
+ /* lg(64/63) = */ 0x0005d0fc,
+ /* lg(128/127) = */ 0x0002e58f,
+ /* lg(256/255) = */ 0x0001720e,
+ /* lg(512/511) = */ 0x0000b8d8,
+ /* lg(1024/1023) = */ 0x00005c61,
+ /* lg(2048/2047) = */ 0x00002e2d,
+ /* lg(4096/4095) = */ 0x00001716,
+ /* lg(8192/8191) = */ 0x00000b8b,
+ /* lg(16384/16383) = */ 0x000005c5,
+ /* lg(32768/32767) = */ 0x000002e3
+ },
+ {
+ /*
+ * 28 fraction bits
+ */
+ /* undefined */ 0x00000000,
+ /* lg(2/1) = */ 0x10000000,
+ /* lg(4/3) = */ 0x06a3fe5c,
+ /* lg(8/7) = */ 0x03151301,
+ /* lg(16/15) = */ 0x017d6049,
+ /* lg(32/31) = */ 0x00bb9ca6,
+ /* lg(64/63) = */ 0x005d0fba,
+ /* lg(128/127) = */ 0x002e58f7,
+ /* lg(256/255) = */ 0x001720da,
+ /* lg(512/511) = */ 0x000b8d87,
+ /* lg(1024/1023) = */ 0x0005c60b,
+ /* lg(2048/2047) = */ 0x0002e2d7,
+ /* lg(4096/4095) = */ 0x00017160,
+ /* lg(8192/8191) = */ 0x0000b8ad,
+ /* lg(16384/16383) = */ 0x00005c56,
+ /* lg(32768/32767) = */ 0x00002e2b
+ }
+};
+
+#if 0
+static const FLAC__uint64 log2_lookup_wide[] = {
+ {
+ /*
+ * 32 fraction bits
+ */
+ /* undefined */ 0x00000000,
+ /* lg(2/1) = */ FLAC__U64L(0x100000000),
+ /* lg(4/3) = */ FLAC__U64L(0x6a3fe5c6),
+ /* lg(8/7) = */ FLAC__U64L(0x31513015),
+ /* lg(16/15) = */ FLAC__U64L(0x17d60497),
+ /* lg(32/31) = */ FLAC__U64L(0x0bb9ca65),
+ /* lg(64/63) = */ FLAC__U64L(0x05d0fba2),
+ /* lg(128/127) = */ FLAC__U64L(0x02e58f74),
+ /* lg(256/255) = */ FLAC__U64L(0x01720d9c),
+ /* lg(512/511) = */ FLAC__U64L(0x00b8d875),
+ /* lg(1024/1023) = */ FLAC__U64L(0x005c60aa),
+ /* lg(2048/2047) = */ FLAC__U64L(0x002e2d72),
+ /* lg(4096/4095) = */ FLAC__U64L(0x00171600),
+ /* lg(8192/8191) = */ FLAC__U64L(0x000b8ad2),
+ /* lg(16384/16383) = */ FLAC__U64L(0x0005c55d),
+ /* lg(32768/32767) = */ FLAC__U64L(0x0002e2ac)
+ },
+ {
+ /*
+ * 48 fraction bits
+ */
+ /* undefined */ 0x00000000,
+ /* lg(2/1) = */ FLAC__U64L(0x1000000000000),
+ /* lg(4/3) = */ FLAC__U64L(0x6a3fe5c60429),
+ /* lg(8/7) = */ FLAC__U64L(0x315130157f7a),
+ /* lg(16/15) = */ FLAC__U64L(0x17d60496cfbb),
+ /* lg(32/31) = */ FLAC__U64L(0xbb9ca64ecac),
+ /* lg(64/63) = */ FLAC__U64L(0x5d0fba187cd),
+ /* lg(128/127) = */ FLAC__U64L(0x2e58f7441ee),
+ /* lg(256/255) = */ FLAC__U64L(0x1720d9c06a8),
+ /* lg(512/511) = */ FLAC__U64L(0xb8d8752173),
+ /* lg(1024/1023) = */ FLAC__U64L(0x5c60aa252e),
+ /* lg(2048/2047) = */ FLAC__U64L(0x2e2d71b0d8),
+ /* lg(4096/4095) = */ FLAC__U64L(0x1716001719),
+ /* lg(8192/8191) = */ FLAC__U64L(0xb8ad1de1b),
+ /* lg(16384/16383) = */ FLAC__U64L(0x5c55d640d),
+ /* lg(32768/32767) = */ FLAC__U64L(0x2e2abcf52)
+ }
+};
+#endif
+
+FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, unsigned fracbits, unsigned precision)
+{
+ const FLAC__uint32 ONE = (1u << fracbits);
+ const FLAC__uint32 *table = log2_lookup[fracbits >> 2];
+
+ FLAC__ASSERT(fracbits < 32);
+ FLAC__ASSERT((fracbits & 0x3) == 0);
+
+ if(x < ONE)
+ return 0;
+
+ if(precision > LOG2_LOOKUP_PRECISION)
+ precision = LOG2_LOOKUP_PRECISION;
+
+ /* Knuth's algorithm for computing logarithms, optimized for base-2 with lookup tables */
+ {
+ FLAC__uint32 y = 0;
+ FLAC__uint32 z = x >> 1, k = 1;
+ while (x > ONE && k < precision) {
+ if (x - z >= ONE) {
+ x -= z;
+ z = x >> k;
+ y += table[k];
+ }
+ else {
+ z >>= 1;
+ k++;
+ }
+ }
+ return y;
+ }
+}
+
+#endif /* defined FLAC__INTEGER_ONLY_LIBRARY */
diff --git a/src/libFLAC/include/private/float.h b/src/libFLAC/include/private/float.h
index 9cc8aa3..2a1215f 100644
--- a/src/libFLAC/include/private/float.h
+++ b/src/libFLAC/include/private/float.h
@@ -36,6 +36,8 @@
#include <config.h>
#endif
+#include "FLAC/ordinals.h"
+
/*
* These typedefs make it easier to ensure that integer versions of
* the library really only contain integer operations. All the code
@@ -49,6 +51,43 @@
typedef double FLAC__double;
typedef float FLAC__float;
typedef float FLAC__real;
+#else
+/*
+ * The convention for FLAC__fixedpoint is to use the upper 16 bits
+ * for the integer part and lower 16 bits for the fractional part.
+ */
+typedef FLAC__int32 FLAC__fixedpoint;
+extern const FLAC__fixedpoint FLAC__FP_ZERO;
+extern const FLAC__fixedpoint FLAC__FP_ONE_HALF;
+extern const FLAC__fixedpoint FLAC__FP_ONE;
+extern const FLAC__fixedpoint FLAC__FP_LN2;
+extern const FLAC__fixedpoint FLAC__FP_E;
+
+#define FLAC__fixedpoint_trunc(x) ((x)>>16)
+
+#define FLAC__fixedpoint_mul(x, y) ( (FLAC__fixedpoint) ( ((FLAC__int64)(x)*(FLAC__int64)(y)) >> 16 ) )
+
+#define FLAC__fixedpoint_div(x, y) ( (FLAC__fixedpoint) ( ( ((FLAC__int64)(x)<<32) / (FLAC__int64)(y) ) >> 16 ) )
+
+/*
+ * FLAC__fixedpoint_log2()
+ * --------------------------------------------------------------------
+ * Returns the base-2 logarithm of the fixed-point number 'x' using an
+ * algorithm by Knuth for x >= 1.0
+ *
+ * 'fracbits' is the number of fractional bits of 'x'. 'fracbits' must
+ * be < 32 and evenly divisible by 4 (0 is OK but not very precise).
+ *
+ * 'precision' roughly limits the number of iterations that are done;
+ * use (unsigned)(-1) for maximum precision.
+ *
+ * If 'x' is less than one -- that is, x < (1<<fracbits) -- then this
+ * function will punt and return 0.
+ *
+ * The return value will also have 'fracbits' fractional bits.
+ */
+FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, unsigned fracbits, unsigned precision);
+
#endif
#endif