summaryrefslogtreecommitdiff
path: root/audio_codec/libfaad/helixaac/trigtabs_fltgen.c (plain)
blob: b5ffa8e900a4a059d927db048f1dbb58880b8e0c
1/* ***** BEGIN LICENSE BLOCK *****
2 * Source last modified: $Id: trigtabs_fltgen.c,v 1.2 2006/12/05 03:36:53 ehyche Exp $
3 *
4 * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved.
5 *
6 * The contents of this file, and the files included with this file,
7 * are subject to the current version of the RealNetworks Public
8 * Source License (the "RPSL") available at
9 * http://www.helixcommunity.org/content/rpsl unless you have licensed
10 * the file under the current version of the RealNetworks Community
11 * Source License (the "RCSL") available at
12 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
13 * will apply. You may also obtain the license terms directly from
14 * RealNetworks. You may not use this file except in compliance with
15 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
16 * to this file, the RCSL. Please see the applicable RPSL or RCSL for
17 * the rights, obligations and limitations governing use of the
18 * contents of the file.
19 *
20 * This file is part of the Helix DNA Technology. RealNetworks is the
21 * developer of the Original Code and owns the copyrights in the
22 * portions it created.
23 *
24 * This file, and the files included with this file, is distributed
25 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
26 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
27 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
28 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
29 * ENJOYMENT OR NON-INFRINGEMENT.
30 *
31 * Technology Compatibility Kit Test Suite(s) Location:
32 * http://www.helixcommunity.org/content/tck
33 *
34 * Contributor(s):
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38/**************************************************************************************
39 * Fixed-point HE-AAC decoder
40 * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com)
41 * June 2005
42 *
43 * trigtabs_fltgen.c - low-ROM alternative to trigtabs.c
44 * generates large trig tables at runtime using floating-point
45 * math library
46 * MUST VERIFY that runtime-generated tables are bit-exact matches
47 * with ROM tables in trigtabs.c
48 **************************************************************************************/
49#ifdef HELIX_CONFIG_AAC_GENERATE_TRIGTABS_FLOAT
50
51#include <math.h>
52#include "coder.h"
53
54/* read-only tables */
55const int cos4sin4tabOffset[NUM_IMDCT_SIZES] = {0, 128};
56const int sinWindowOffset[NUM_IMDCT_SIZES] = {0, 128};
57const int kbdWindowOffset[NUM_IMDCT_SIZES] = {0, 128};
58const int bitrevtabOffset[NUM_IMDCT_SIZES] = {0, 17};
59const unsigned char bitrevtab[17 + 129] = {
60 /* nfft = 64 */
61 0x01, 0x08, 0x02, 0x04, 0x03, 0x0c, 0x05, 0x0a, 0x07, 0x0e, 0x0b, 0x0d, 0x00, 0x06, 0x09, 0x0f,
62 0x00,
63
64 /* nfft = 512 */
65 0x01, 0x40, 0x02, 0x20, 0x03, 0x60, 0x04, 0x10, 0x05, 0x50, 0x06, 0x30, 0x07, 0x70, 0x09, 0x48,
66 0x0a, 0x28, 0x0b, 0x68, 0x0c, 0x18, 0x0d, 0x58, 0x0e, 0x38, 0x0f, 0x78, 0x11, 0x44, 0x12, 0x24,
67 0x13, 0x64, 0x15, 0x54, 0x16, 0x34, 0x17, 0x74, 0x19, 0x4c, 0x1a, 0x2c, 0x1b, 0x6c, 0x1d, 0x5c,
68 0x1e, 0x3c, 0x1f, 0x7c, 0x21, 0x42, 0x23, 0x62, 0x25, 0x52, 0x26, 0x32, 0x27, 0x72, 0x29, 0x4a,
69 0x2b, 0x6a, 0x2d, 0x5a, 0x2e, 0x3a, 0x2f, 0x7a, 0x31, 0x46, 0x33, 0x66, 0x35, 0x56, 0x37, 0x76,
70 0x39, 0x4e, 0x3b, 0x6e, 0x3d, 0x5e, 0x3f, 0x7e, 0x43, 0x61, 0x45, 0x51, 0x47, 0x71, 0x4b, 0x69,
71 0x4d, 0x59, 0x4f, 0x79, 0x53, 0x65, 0x57, 0x75, 0x5b, 0x6d, 0x5f, 0x7d, 0x67, 0x73, 0x6f, 0x7b,
72 0x00, 0x08, 0x14, 0x1c, 0x22, 0x2a, 0x36, 0x3e, 0x41, 0x49, 0x55, 0x5d, 0x63, 0x6b, 0x77, 0x7f,
73 0x00,
74
75};
76
77/* tables generated at runtime */
78int cos4sin4tab[128 + 1024];
79int cos1sin1tab[514];
80int sinWindow[128 + 1024];
81int kbdWindow[128 + 1024];
82int twidTabEven[4 * 6 + 16 * 6 + 64 * 6];
83int twidTabOdd[8 * 6 + 32 * 6 + 128 * 6];
84
85#define M_PI 3.14159265358979323846
86#define M2_30 1073741824.0
87#define M2_31 2147483648.0
88
89#define MAX_DBL 2147483647.0
90#define MIN_DBL -2147483648.0
91
92static int NormAndRound(double x, double q, double n)
93{
94 if (x >= 0.0) {
95 x = (x * q * n + 0.5);
96 } else {
97 x = (x * q * n - 0.5);
98 }
99
100 /* clip */
101 if (x > MAX_DBL) {
102 x = MAX_DBL;
103 }
104 if (x < MIN_DBL) {
105 x = MIN_DBL;
106 }
107
108 return (int)x;
109}
110
111static void Init_cos4sin4tab(int *tPtr, int nmdct)
112{
113 int i;
114 double angle1, angle2, invM, x1, x2, x3, x4;
115
116 invM = -1.0 / (double)nmdct;
117 for (i = 0; i < nmdct / 4; i++) {
118 angle1 = (i + 0.25) * M_PI / nmdct;
119 angle2 = (nmdct / 2 - 1 - i + 0.25) * M_PI / nmdct;
120
121 x1 = invM * (cos(angle1) + sin(angle1));
122 x2 = invM * sin(angle1);
123 x3 = invM * (cos(angle2) + sin(angle2));
124 x4 = invM * sin(angle2);
125
126 tPtr[0] = NormAndRound(x1, M2_30, nmdct);
127 tPtr[1] = NormAndRound(x2, M2_30, nmdct);
128 tPtr[2] = NormAndRound(x3, M2_30, nmdct);
129 tPtr[3] = NormAndRound(x4, M2_30, nmdct);
130 tPtr += 4;
131 }
132}
133
134static void Init_cos1sin1tab(int *tPtr)
135{
136 int i;
137 double angle, x1, x2;
138
139 for (i = 0; i <= (512 / 2); i++) {
140 angle = i * M_PI / 1024;
141 x1 = (cos(angle) + sin(angle));
142 x2 = sin(angle);
143
144 tPtr[0] = NormAndRound(x1, M2_30, 1);
145 tPtr[1] = NormAndRound(x2, M2_30, 1);
146 tPtr += 2;
147 }
148}
149
150static void Init_sinWindow(int *tPtr, int nmdct)
151{
152 int i;
153 double angle1, angle2, x1, x2;
154
155 for (i = 0; i < nmdct / 2; i++) {
156 angle1 = (i + 0.5) * M_PI / (2.0 * nmdct);
157 angle2 = (nmdct - 1 - i + 0.5) * M_PI / (2.0 * nmdct);
158 x1 = sin(angle1);
159 x2 = sin(angle2);
160
161 tPtr[0] = NormAndRound(x1, M2_31, 1);
162 tPtr[1] = NormAndRound(x2, M2_31, 1);
163 tPtr += 2;
164 }
165}
166
167
168#define KBD_THRESH 1e-12
169
170static double CalcI0(double x)
171{
172 int k;
173 double i0, iTmp, iLast, x2, xPow, kFact;
174
175 x2 = x / 2.0;
176 i0 = 0.0;
177 k = 0;
178 kFact = 1;
179 xPow = 1;
180 do {
181 iLast = i0;
182 iTmp = xPow / kFact;
183 i0 += (iTmp * iTmp);
184 k++;
185 kFact *= k;
186 xPow *= x2;
187 } while (fabs(i0 - iLast) > KBD_THRESH);
188
189 return i0;
190}
191
192static double CalcW(double nRef, double n, double a)
193{
194 double i0Base, i0Curr, nTemp;
195
196 i0Base = CalcI0(M_PI * a);
197
198 nTemp = (n - nRef / 4) / (nRef / 4);
199 i0Curr = CalcI0(M_PI * a * sqrt(1.0 - nTemp * nTemp));
200
201 return i0Curr / i0Base;
202}
203
204static void Init_kbdWindow(int *tPtr, int nmdct)
205{
206 int n, nRef;
207 double a, wBase, wCurr, x1;
208
209 nRef = nmdct * 2;
210
211 /* kbd window */
212 if (nmdct == 128) {
213 a = 6.0;
214 } else {
215 a = 4.0;
216 }
217
218 wBase = 0;
219 for (n = 0; n <= nRef / 2; n++) {
220 wBase += CalcW(nRef, n, a);
221 }
222
223 /* left */
224 wCurr = 0;
225 for (n = 0; n < nmdct / 2; n++) {
226 wCurr += CalcW(nRef, n, a);
227 x1 = sqrt(wCurr / wBase);
228 tPtr[0] = NormAndRound(x1, M2_31, 1);
229 tPtr += 2;
230 }
231 tPtr--;
232
233 /* right */
234 for (n = nmdct / 2; n < nmdct; n++) {
235 wCurr += CalcW(nRef, n, a);
236 x1 = sqrt(wCurr / wBase);
237 tPtr[0] = NormAndRound(x1, M2_31, 1);
238 tPtr -= 2;
239 }
240
241 /* symmetry:
242 * kbd_right(n) = kbd_ldef(N_REF - 1 - n), n = [N_REF/2, N_REF - 1]
243 *
244 * wCurr = 0;
245 * for (n = N_REF-1; n >= N_REF/2; n--) {
246 * wCurr += CalcW(N_REF-n-1, a);
247 * kbdWindowRef[n] = sqrt(wCurr / wBase);
248 * }
249 *
250 */
251 return;
252}
253
254static void Init_twidTabs(int *tPtrEven, int *tPtrOdd, int nfft)
255{
256 int j, k;
257 double wr1, wi1, wr2, wi2, wr3, wi3;
258
259 for (k = 4; k <= nfft / 4; k <<= 1) {
260 for (j = 0; j < k; j++) {
261 wr1 = cos(1.0 * M_PI * j / (2 * k));
262 wi1 = sin(1.0 * M_PI * j / (2 * k));
263 wr1 = (wr1 + wi1);
264 wi1 = -wi1;
265
266 wr2 = cos(2.0 * M_PI * j / (2 * k));
267 wi2 = sin(2.0 * M_PI * j / (2 * k));
268 wr2 = (wr2 + wi2);
269 wi2 = -wi2;
270
271 wr3 = cos(3.0 * M_PI * j / (2 * k));
272 wi3 = sin(3.0 * M_PI * j / (2 * k));
273 wr3 = (wr3 + wi3);
274 wi3 = -wi3;
275
276 if (k & 0xaaaaaaaa) {
277 tPtrOdd[0] = NormAndRound(wr2, M2_30, 1);
278 tPtrOdd[1] = NormAndRound(wi2, M2_30, 1);
279 tPtrOdd[2] = NormAndRound(wr1, M2_30, 1);
280 tPtrOdd[3] = NormAndRound(wi1, M2_30, 1);
281 tPtrOdd[4] = NormAndRound(wr3, M2_30, 1);
282 tPtrOdd[5] = NormAndRound(wi3, M2_30, 1);
283 tPtrOdd += 6;
284 } else {
285 tPtrEven[0] = NormAndRound(wr2, M2_30, 1);
286 tPtrEven[1] = NormAndRound(wi2, M2_30, 1);
287 tPtrEven[2] = NormAndRound(wr1, M2_30, 1);
288 tPtrEven[3] = NormAndRound(wi1, M2_30, 1);
289 tPtrEven[4] = NormAndRound(wr3, M2_30, 1);
290 tPtrEven[5] = NormAndRound(wi3, M2_30, 1);
291 tPtrEven += 6;
292 }
293 }
294 }
295}
296
297/**************************************************************************************
298 * Function: AACInitTrigtabsFloat
299 *
300 * Description: generate AAC decoder tables using floating-point math library
301 *
302 * Inputs: none
303 *
304 * Outputs: initialized tables
305 *
306 * Return: 0 on success
307 *
308 * Notes: this function should ONLY be called when double-precision
309 * floating-point math is supported
310 * the generated tables must be bit-exact matches with read-only
311 * tables stored in trigtabs.c
312 * this initializes global tables in RAM, and is NOT thread-safe,
313 * so the caller must ensure that this function is not called
314 * from multiple threads
315 * this should be called exactly once, before the entrypoint function
316 * for the application or DLL is called
317 **************************************************************************************/
318int AACInitTrigtabsFloat(void)
319{
320 /* cos4sin4tab */
321 Init_cos4sin4tab(cos4sin4tab + cos4sin4tabOffset[0], 128);
322 Init_cos4sin4tab(cos4sin4tab + cos4sin4tabOffset[1], 1024);
323
324 /* cos1sin1tab */
325 Init_cos1sin1tab(cos1sin1tab);
326
327 /* sinWindow */
328 Init_sinWindow(sinWindow + sinWindowOffset[0], 128);
329 Init_sinWindow(sinWindow + sinWindowOffset[1], 1024);
330
331 /* kbdWindow */
332 Init_kbdWindow(kbdWindow + kbdWindowOffset[0], 128);
333 Init_kbdWindow(kbdWindow + kbdWindowOffset[1], 1024);
334
335 /* twidTabEven, twidTabOdd */
336 Init_twidTabs(twidTabEven, twidTabOdd, 512);
337
338 return 0;
339}
340
341/**************************************************************************************
342 * Function: AACFreeTrigtabsFloat
343 *
344 * Description: free any memory allocated by AACInitTrigtabsFloat()
345 *
346 * Inputs: none
347 *
348 * Outputs: none
349 *
350 * Return: none
351 **************************************************************************************/
352void AACFreeTrigtabsFloat(void)
353{
354 return;
355}
356
357#endif /* HELIX_CONFIG_AAC_GENERATE_TRIGTABS_FLOAT */
358