1/* libFLAC - Free Lossless Audio Codec library 2 * Copyright (C) 2004-2009 Josh Coalson 3 * Copyright (C) 2011-2014 Xiph.Org Foundation 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * - Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * - Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * - Neither the name of the Xiph.org Foundation nor the names of its 17 * contributors may be used to endorse or promote products derived from 18 * this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#ifdef HAVE_CONFIG_H 34# include <config.h> 35#endif 36 37#include "FLAC/assert.h" 38#include "share/compat.h" 39#include "private/float.h" 40 41#ifdef FLAC__INTEGER_ONLY_LIBRARY 42 43const FLAC__fixedpoint FLAC__FP_ZERO = 0; 44const FLAC__fixedpoint FLAC__FP_ONE_HALF = 0x00008000; 45const FLAC__fixedpoint FLAC__FP_ONE = 0x00010000; 46const FLAC__fixedpoint FLAC__FP_LN2 = 45426; 47const FLAC__fixedpoint FLAC__FP_E = 178145; 48 49/* Lookup tables for Knuth's logarithm algorithm */ 50#define LOG2_LOOKUP_PRECISION 16 51static const FLAC__uint32 log2_lookup[][LOG2_LOOKUP_PRECISION] = { 52 { 53 /* 54 * 0 fraction bits 55 */ 56 /* undefined */ 0x00000000, 57 /* lg(2/1) = */ 0x00000001, 58 /* lg(4/3) = */ 0x00000000, 59 /* lg(8/7) = */ 0x00000000, 60 /* lg(16/15) = */ 0x00000000, 61 /* lg(32/31) = */ 0x00000000, 62 /* lg(64/63) = */ 0x00000000, 63 /* lg(128/127) = */ 0x00000000, 64 /* lg(256/255) = */ 0x00000000, 65 /* lg(512/511) = */ 0x00000000, 66 /* lg(1024/1023) = */ 0x00000000, 67 /* lg(2048/2047) = */ 0x00000000, 68 /* lg(4096/4095) = */ 0x00000000, 69 /* lg(8192/8191) = */ 0x00000000, 70 /* lg(16384/16383) = */ 0x00000000, 71 /* lg(32768/32767) = */ 0x00000000 72 }, 73 { 74 /* 75 * 4 fraction bits 76 */ 77 /* undefined */ 0x00000000, 78 /* lg(2/1) = */ 0x00000010, 79 /* lg(4/3) = */ 0x00000007, 80 /* lg(8/7) = */ 0x00000003, 81 /* lg(16/15) = */ 0x00000001, 82 /* lg(32/31) = */ 0x00000001, 83 /* lg(64/63) = */ 0x00000000, 84 /* lg(128/127) = */ 0x00000000, 85 /* lg(256/255) = */ 0x00000000, 86 /* lg(512/511) = */ 0x00000000, 87 /* lg(1024/1023) = */ 0x00000000, 88 /* lg(2048/2047) = */ 0x00000000, 89 /* lg(4096/4095) = */ 0x00000000, 90 /* lg(8192/8191) = */ 0x00000000, 91 /* lg(16384/16383) = */ 0x00000000, 92 /* lg(32768/32767) = */ 0x00000000 93 }, 94 { 95 /* 96 * 8 fraction bits 97 */ 98 /* undefined */ 0x00000000, 99 /* lg(2/1) = */ 0x00000100, 100 /* lg(4/3) = */ 0x0000006a, 101 /* lg(8/7) = */ 0x00000031, 102 /* lg(16/15) = */ 0x00000018, 103 /* lg(32/31) = */ 0x0000000c, 104 /* lg(64/63) = */ 0x00000006, 105 /* lg(128/127) = */ 0x00000003, 106 /* lg(256/255) = */ 0x00000001, 107 /* lg(512/511) = */ 0x00000001, 108 /* lg(1024/1023) = */ 0x00000000, 109 /* lg(2048/2047) = */ 0x00000000, 110 /* lg(4096/4095) = */ 0x00000000, 111 /* lg(8192/8191) = */ 0x00000000, 112 /* lg(16384/16383) = */ 0x00000000, 113 /* lg(32768/32767) = */ 0x00000000 114 }, 115 { 116 /* 117 * 12 fraction bits 118 */ 119 /* undefined */ 0x00000000, 120 /* lg(2/1) = */ 0x00001000, 121 /* lg(4/3) = */ 0x000006a4, 122 /* lg(8/7) = */ 0x00000315, 123 /* lg(16/15) = */ 0x0000017d, 124 /* lg(32/31) = */ 0x000000bc, 125 /* lg(64/63) = */ 0x0000005d, 126 /* lg(128/127) = */ 0x0000002e, 127 /* lg(256/255) = */ 0x00000017, 128 /* lg(512/511) = */ 0x0000000c, 129 /* lg(1024/1023) = */ 0x00000006, 130 /* lg(2048/2047) = */ 0x00000003, 131 /* lg(4096/4095) = */ 0x00000001, 132 /* lg(8192/8191) = */ 0x00000001, 133 /* lg(16384/16383) = */ 0x00000000, 134 /* lg(32768/32767) = */ 0x00000000 135 }, 136 { 137 /* 138 * 16 fraction bits 139 */ 140 /* undefined */ 0x00000000, 141 /* lg(2/1) = */ 0x00010000, 142 /* lg(4/3) = */ 0x00006a40, 143 /* lg(8/7) = */ 0x00003151, 144 /* lg(16/15) = */ 0x000017d6, 145 /* lg(32/31) = */ 0x00000bba, 146 /* lg(64/63) = */ 0x000005d1, 147 /* lg(128/127) = */ 0x000002e6, 148 /* lg(256/255) = */ 0x00000172, 149 /* lg(512/511) = */ 0x000000b9, 150 /* lg(1024/1023) = */ 0x0000005c, 151 /* lg(2048/2047) = */ 0x0000002e, 152 /* lg(4096/4095) = */ 0x00000017, 153 /* lg(8192/8191) = */ 0x0000000c, 154 /* lg(16384/16383) = */ 0x00000006, 155 /* lg(32768/32767) = */ 0x00000003 156 }, 157 { 158 /* 159 * 20 fraction bits 160 */ 161 /* undefined */ 0x00000000, 162 /* lg(2/1) = */ 0x00100000, 163 /* lg(4/3) = */ 0x0006a3fe, 164 /* lg(8/7) = */ 0x00031513, 165 /* lg(16/15) = */ 0x00017d60, 166 /* lg(32/31) = */ 0x0000bb9d, 167 /* lg(64/63) = */ 0x00005d10, 168 /* lg(128/127) = */ 0x00002e59, 169 /* lg(256/255) = */ 0x00001721, 170 /* lg(512/511) = */ 0x00000b8e, 171 /* lg(1024/1023) = */ 0x000005c6, 172 /* lg(2048/2047) = */ 0x000002e3, 173 /* lg(4096/4095) = */ 0x00000171, 174 /* lg(8192/8191) = */ 0x000000b9, 175 /* lg(16384/16383) = */ 0x0000005c, 176 /* lg(32768/32767) = */ 0x0000002e 177 }, 178 { 179 /* 180 * 24 fraction bits 181 */ 182 /* undefined */ 0x00000000, 183 /* lg(2/1) = */ 0x01000000, 184 /* lg(4/3) = */ 0x006a3fe6, 185 /* lg(8/7) = */ 0x00315130, 186 /* lg(16/15) = */ 0x0017d605, 187 /* lg(32/31) = */ 0x000bb9ca, 188 /* lg(64/63) = */ 0x0005d0fc, 189 /* lg(128/127) = */ 0x0002e58f, 190 /* lg(256/255) = */ 0x0001720e, 191 /* lg(512/511) = */ 0x0000b8d8, 192 /* lg(1024/1023) = */ 0x00005c61, 193 /* lg(2048/2047) = */ 0x00002e2d, 194 /* lg(4096/4095) = */ 0x00001716, 195 /* lg(8192/8191) = */ 0x00000b8b, 196 /* lg(16384/16383) = */ 0x000005c5, 197 /* lg(32768/32767) = */ 0x000002e3 198 }, 199 { 200 /* 201 * 28 fraction bits 202 */ 203 /* undefined */ 0x00000000, 204 /* lg(2/1) = */ 0x10000000, 205 /* lg(4/3) = */ 0x06a3fe5c, 206 /* lg(8/7) = */ 0x03151301, 207 /* lg(16/15) = */ 0x017d6049, 208 /* lg(32/31) = */ 0x00bb9ca6, 209 /* lg(64/63) = */ 0x005d0fba, 210 /* lg(128/127) = */ 0x002e58f7, 211 /* lg(256/255) = */ 0x001720da, 212 /* lg(512/511) = */ 0x000b8d87, 213 /* lg(1024/1023) = */ 0x0005c60b, 214 /* lg(2048/2047) = */ 0x0002e2d7, 215 /* lg(4096/4095) = */ 0x00017160, 216 /* lg(8192/8191) = */ 0x0000b8ad, 217 /* lg(16384/16383) = */ 0x00005c56, 218 /* lg(32768/32767) = */ 0x00002e2b 219 } 220}; 221 222#if 0 223static const FLAC__uint64 log2_lookup_wide[] = { 224 { 225 /* 226 * 32 fraction bits 227 */ 228 /* undefined */ 0x00000000, 229 /* lg(2/1) = */ FLAC__U64L(0x100000000), 230 /* lg(4/3) = */ FLAC__U64L(0x6a3fe5c6), 231 /* lg(8/7) = */ FLAC__U64L(0x31513015), 232 /* lg(16/15) = */ FLAC__U64L(0x17d60497), 233 /* lg(32/31) = */ FLAC__U64L(0x0bb9ca65), 234 /* lg(64/63) = */ FLAC__U64L(0x05d0fba2), 235 /* lg(128/127) = */ FLAC__U64L(0x02e58f74), 236 /* lg(256/255) = */ FLAC__U64L(0x01720d9c), 237 /* lg(512/511) = */ FLAC__U64L(0x00b8d875), 238 /* lg(1024/1023) = */ FLAC__U64L(0x005c60aa), 239 /* lg(2048/2047) = */ FLAC__U64L(0x002e2d72), 240 /* lg(4096/4095) = */ FLAC__U64L(0x00171600), 241 /* lg(8192/8191) = */ FLAC__U64L(0x000b8ad2), 242 /* lg(16384/16383) = */ FLAC__U64L(0x0005c55d), 243 /* lg(32768/32767) = */ FLAC__U64L(0x0002e2ac) 244 }, 245 { 246 /* 247 * 48 fraction bits 248 */ 249 /* undefined */ 0x00000000, 250 /* lg(2/1) = */ FLAC__U64L(0x1000000000000), 251 /* lg(4/3) = */ FLAC__U64L(0x6a3fe5c60429), 252 /* lg(8/7) = */ FLAC__U64L(0x315130157f7a), 253 /* lg(16/15) = */ FLAC__U64L(0x17d60496cfbb), 254 /* lg(32/31) = */ FLAC__U64L(0xbb9ca64ecac), 255 /* lg(64/63) = */ FLAC__U64L(0x5d0fba187cd), 256 /* lg(128/127) = */ FLAC__U64L(0x2e58f7441ee), 257 /* lg(256/255) = */ FLAC__U64L(0x1720d9c06a8), 258 /* lg(512/511) = */ FLAC__U64L(0xb8d8752173), 259 /* lg(1024/1023) = */ FLAC__U64L(0x5c60aa252e), 260 /* lg(2048/2047) = */ FLAC__U64L(0x2e2d71b0d8), 261 /* lg(4096/4095) = */ FLAC__U64L(0x1716001719), 262 /* lg(8192/8191) = */ FLAC__U64L(0xb8ad1de1b), 263 /* lg(16384/16383) = */ FLAC__U64L(0x5c55d640d), 264 /* lg(32768/32767) = */ FLAC__U64L(0x2e2abcf52) 265 } 266}; 267#endif 268 269FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, unsigned fracbits, unsigned precision) 270{ 271 const FLAC__uint32 ONE = (1u << fracbits); 272 const FLAC__uint32 *table = log2_lookup[fracbits >> 2]; 273 274 FLAC__ASSERT(fracbits < 32); 275 FLAC__ASSERT((fracbits & 0x3) == 0); 276 277 if(x < ONE) 278 return 0; 279 280 if(precision > LOG2_LOOKUP_PRECISION) 281 precision = LOG2_LOOKUP_PRECISION; 282 283 /* Knuth's algorithm for computing logarithms, optimized for base-2 with lookup tables */ 284 { 285 FLAC__uint32 y = 0; 286 FLAC__uint32 z = x >> 1, k = 1; 287 while (x > ONE && k < precision) { 288 if (x - z >= ONE) { 289 x -= z; 290 z = x >> k; 291 y += table[k]; 292 } 293 else { 294 z >>= 1; 295 k++; 296 } 297 } 298 return y; 299 } 300} 301 302#endif /* defined FLAC__INTEGER_ONLY_LIBRARY */ 303