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