/src/aac/libAACenc/src/aacenc_tns.cpp
Line  | Count  | Source  | 
1  |  | /* -----------------------------------------------------------------------------  | 
2  |  | Software License for The Fraunhofer FDK AAC Codec Library for Android  | 
3  |  |  | 
4  |  | © Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten  | 
5  |  | Forschung e.V. All rights reserved.  | 
6  |  |  | 
7  |  |  1.    INTRODUCTION  | 
8  |  | The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software | 
9  |  | that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding | 
10  |  | scheme for digital audio. This FDK AAC Codec software is intended to be used on  | 
11  |  | a wide variety of Android devices.  | 
12  |  |  | 
13  |  | AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient  | 
14  |  | general perceptual audio codecs. AAC-ELD is considered the best-performing  | 
15  |  | full-bandwidth communications codec by independent studies and is widely  | 
16  |  | deployed. AAC has been standardized by ISO and IEC as part of the MPEG  | 
17  |  | specifications.  | 
18  |  |  | 
19  |  | Patent licenses for necessary patent claims for the FDK AAC Codec (including  | 
20  |  | those of Fraunhofer) may be obtained through Via Licensing  | 
21  |  | (www.vialicensing.com) or through the respective patent owners individually for  | 
22  |  | the purpose of encoding or decoding bit streams in products that are compliant  | 
23  |  | with the ISO/IEC MPEG audio standards. Please note that most manufacturers of  | 
24  |  | Android devices already license these patent claims through Via Licensing or  | 
25  |  | directly from the patent owners, and therefore FDK AAC Codec software may  | 
26  |  | already be covered under those patent licenses when it is used for those  | 
27  |  | licensed purposes only.  | 
28  |  |  | 
29  |  | Commercially-licensed AAC software libraries, including floating-point versions  | 
30  |  | with enhanced sound quality, are also available from Fraunhofer. Users are  | 
31  |  | encouraged to check the Fraunhofer website for additional applications  | 
32  |  | information and documentation.  | 
33  |  |  | 
34  |  | 2.    COPYRIGHT LICENSE  | 
35  |  |  | 
36  |  | Redistribution and use in source and binary forms, with or without modification,  | 
37  |  | are permitted without payment of copyright license fees provided that you  | 
38  |  | satisfy the following conditions:  | 
39  |  |  | 
40  |  | You must retain the complete text of this software license in redistributions of  | 
41  |  | the FDK AAC Codec or your modifications thereto in source code form.  | 
42  |  |  | 
43  |  | You must retain the complete text of this software license in the documentation  | 
44  |  | and/or other materials provided with redistributions of the FDK AAC Codec or  | 
45  |  | your modifications thereto in binary form. You must make available free of  | 
46  |  | charge copies of the complete source code of the FDK AAC Codec and your  | 
47  |  | modifications thereto to recipients of copies in binary form.  | 
48  |  |  | 
49  |  | The name of Fraunhofer may not be used to endorse or promote products derived  | 
50  |  | from this library without prior written permission.  | 
51  |  |  | 
52  |  | You may not charge copyright license fees for anyone to use, copy or distribute  | 
53  |  | the FDK AAC Codec software or your modifications thereto.  | 
54  |  |  | 
55  |  | Your modified versions of the FDK AAC Codec must carry prominent notices stating  | 
56  |  | that you changed the software and the date of any change. For modified versions  | 
57  |  | of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"  | 
58  |  | must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK  | 
59  |  | AAC Codec Library for Android."  | 
60  |  |  | 
61  |  | 3.    NO PATENT LICENSE  | 
62  |  |  | 
63  |  | NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without  | 
64  |  | limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.  | 
65  |  | Fraunhofer provides no warranty of patent non-infringement with respect to this  | 
66  |  | software.  | 
67  |  |  | 
68  |  | You may use this FDK AAC Codec software or modifications thereto only for  | 
69  |  | purposes that are authorized by appropriate patent licenses.  | 
70  |  |  | 
71  |  | 4.    DISCLAIMER  | 
72  |  |  | 
73  |  | This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright  | 
74  |  | holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,  | 
75  |  | including but not limited to the implied warranties of merchantability and  | 
76  |  | fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR  | 
77  |  | CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,  | 
78  |  | or consequential damages, including but not limited to procurement of substitute  | 
79  |  | goods or services; loss of use, data, or profits, or business interruption,  | 
80  |  | however caused and on any theory of liability, whether in contract, strict  | 
81  |  | liability, or tort (including negligence), arising in any way out of the use of  | 
82  |  | this software, even if advised of the possibility of such damage.  | 
83  |  |  | 
84  |  | 5.    CONTACT INFORMATION  | 
85  |  |  | 
86  |  | Fraunhofer Institute for Integrated Circuits IIS  | 
87  |  | Attention: Audio and Multimedia Departments - FDK AAC LL  | 
88  |  | Am Wolfsmantel 33  | 
89  |  | 91058 Erlangen, Germany  | 
90  |  |  | 
91  |  | www.iis.fraunhofer.de/amm  | 
92  |  | amm-info@iis.fraunhofer.de  | 
93  |  | ----------------------------------------------------------------------------- */  | 
94  |  |  | 
95  |  | /**************************** AAC encoder library ******************************  | 
96  |  |  | 
97  |  |    Author(s):   Alex Groeschel, Tobias Chalupka  | 
98  |  |  | 
99  |  |    Description: Temporal noise shaping  | 
100  |  |  | 
101  |  | *******************************************************************************/  | 
102  |  |  | 
103  |  | #include "aacenc_tns.h"  | 
104  |  | #include "psy_const.h"  | 
105  |  | #include "psy_configuration.h"  | 
106  |  | #include "tns_func.h"  | 
107  |  | #include "aacEnc_rom.h"  | 
108  |  | #include "aacenc_tns.h"  | 
109  |  | #include "FDK_lpc.h"  | 
110  |  |  | 
111  | 0  | #define FILTER_DIRECTION 0 /* 0 = up, 1 = down */  | 
112  |  |  | 
113  |  | static const FIXP_DBL acfWindowLong[12 + 3 + 1] = { | 
114  |  |     0x7fffffff, 0x7fb80000, 0x7ee00000, 0x7d780000, 0x7b800000, 0x78f80000,  | 
115  |  |     0x75e00000, 0x72380000, 0x6e000000, 0x69380000, 0x63e00000, 0x5df80000,  | 
116  |  |     0x57800000, 0x50780000, 0x48e00000, 0x40b80000};  | 
117  |  |  | 
118  |  | static const FIXP_DBL acfWindowShort[4 + 3 + 1] = { | 
119  |  |     0x7fffffff, 0x7e000000, 0x78000000, 0x6e000000,  | 
120  |  |     0x60000000, 0x4e000000, 0x38000000, 0x1e000000};  | 
121  |  |  | 
122  |  | typedef struct { | 
123  |  |   INT bitRateFrom[2];                  /* noneSbr=0, useSbr=1 */  | 
124  |  |   INT bitRateTo[2];                    /* noneSbr=0, useSbr=1 */  | 
125  |  |   TNS_PARAMETER_TABULATED paramTab[2]; /* mono=0, stereo=1 */  | 
126  |  |  | 
127  |  | } TNS_INFO_TAB;  | 
128  |  |  | 
129  | 0  | #define TNS_TIMERES_SCALE (1)  | 
130  |  | #define FL2_TIMERES_FIX(a) (FL2FXCONST_DBL(a / (float)(1 << TNS_TIMERES_SCALE)))  | 
131  |  |  | 
132  |  | static const TNS_INFO_TAB tnsInfoTab[] = { | 
133  |  |     {{16000, 13500}, | 
134  |  |      {32000, 28000}, | 
135  |  |      {{{1, 1}, | 
136  |  |        {1437, 1500}, | 
137  |  |        {1400, 600}, | 
138  |  |        {12, 12}, | 
139  |  |        {FILTER_DIRECTION, FILTER_DIRECTION}, | 
140  |  |        {3, 1}, | 
141  |  |        {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.2f)}, | 
142  |  |        1},  | 
143  |  |       {{1, 1}, | 
144  |  |        {1437, 1500}, | 
145  |  |        {1400, 600}, | 
146  |  |        {12, 12}, | 
147  |  |        {FILTER_DIRECTION, FILTER_DIRECTION}, | 
148  |  |        {3, 1}, | 
149  |  |        {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.2f)}, | 
150  |  |        1}}},  | 
151  |  |     {{32001, 28001}, | 
152  |  |      {60000, 52000}, | 
153  |  |      {{{1, 1}, | 
154  |  |        {1437, 1500}, | 
155  |  |        {1400, 600}, | 
156  |  |        {12, 10}, | 
157  |  |        {FILTER_DIRECTION, FILTER_DIRECTION}, | 
158  |  |        {3, 1}, | 
159  |  |        {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)}, | 
160  |  |        1},  | 
161  |  |       {{1, 1}, | 
162  |  |        {1437, 1500}, | 
163  |  |        {1400, 600}, | 
164  |  |        {12, 10}, | 
165  |  |        {FILTER_DIRECTION, FILTER_DIRECTION}, | 
166  |  |        {3, 1}, | 
167  |  |        {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)}, | 
168  |  |        1}}},  | 
169  |  |     {{60001, 52001}, | 
170  |  |      {384000, 384000}, | 
171  |  |      {{{1, 1}, | 
172  |  |        {1437, 1500}, | 
173  |  |        {1400, 600}, | 
174  |  |        {12, 8}, | 
175  |  |        {FILTER_DIRECTION, FILTER_DIRECTION}, | 
176  |  |        {3, 1}, | 
177  |  |        {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)}, | 
178  |  |        1},  | 
179  |  |       {{1, 1}, | 
180  |  |        {1437, 1500}, | 
181  |  |        {1400, 600}, | 
182  |  |        {12, 8}, | 
183  |  |        {FILTER_DIRECTION, FILTER_DIRECTION}, | 
184  |  |        {3, 1}, | 
185  |  |        {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)}, | 
186  |  |        1}}}};  | 
187  |  |  | 
188  |  | typedef struct { | 
189  |  |   INT samplingRate;  | 
190  |  |   SCHAR maxBands[2]; /* long=0; short=1 */  | 
191  |  |  | 
192  |  | } TNS_MAX_TAB_ENTRY;  | 
193  |  |  | 
194  |  | static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab1024[] = { | 
195  |  |     {96000, {31, 9}},  {88200, {31, 9}},  {64000, {34, 10}}, {48000, {40, 14}}, | 
196  |  |     {44100, {42, 14}}, {32000, {51, 14}}, {24000, {46, 14}}, {22050, {46, 14}}, | 
197  |  |     {16000, {42, 14}}, {12000, {42, 14}}, {11025, {42, 14}}, {8000, {39, 14}}}; | 
198  |  |  | 
199  |  | static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab120[] = { | 
200  |  |     {48000, {12, -1}}, /* 48000 */ | 
201  |  |     {44100, {12, -1}}, /* 44100 */ | 
202  |  |     {32000, {15, -1}}, /* 32000 */ | 
203  |  |     {24000, {15, -1}}, /* 24000 */ | 
204  |  |     {22050, {15, -1}}  /* 22050 */ | 
205  |  | };  | 
206  |  |  | 
207  |  | static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab128[] = { | 
208  |  |     {48000, {12, -1}}, /* 48000 */ | 
209  |  |     {44100, {12, -1}}, /* 44100 */ | 
210  |  |     {32000, {15, -1}}, /* 32000 */ | 
211  |  |     {24000, {15, -1}}, /* 24000 */ | 
212  |  |     {22050, {15, -1}}  /* 22050 */ | 
213  |  | };  | 
214  |  |  | 
215  |  | static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab240[] = { | 
216  |  |     {96000, {22, -1}}, /* 96000 */ | 
217  |  |     {48000, {22, -1}}, /* 48000 */ | 
218  |  |     {44100, {22, -1}}, /* 44100 */ | 
219  |  |     {32000, {21, -1}}, /* 32000 */ | 
220  |  |     {24000, {21, -1}}, /* 24000 */ | 
221  |  |     {22050, {21, -1}}  /* 22050 */ | 
222  |  | };  | 
223  |  |  | 
224  |  | static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab256[] = { | 
225  |  |     {96000, {25, -1}}, /* 96000 */ | 
226  |  |     {48000, {25, -1}}, /* 48000 */ | 
227  |  |     {44100, {25, -1}}, /* 44100 */ | 
228  |  |     {32000, {24, -1}}, /* 32000 */ | 
229  |  |     {24000, {24, -1}}, /* 24000 */ | 
230  |  |     {22050, {24, -1}}  /* 22050 */ | 
231  |  | };  | 
232  |  | static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab480[] = {{48000, {31, -1}}, | 
233  |  |                                                       {44100, {32, -1}}, | 
234  |  |                                                       {32000, {37, -1}}, | 
235  |  |                                                       {24000, {30, -1}}, | 
236  |  |                                                       {22050, {30, -1}}}; | 
237  |  |  | 
238  |  | static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab512[] = {{48000, {31, -1}}, | 
239  |  |                                                       {44100, {32, -1}}, | 
240  |  |                                                       {32000, {37, -1}}, | 
241  |  |                                                       {24000, {31, -1}}, | 
242  |  |                                                       {22050, {31, -1}}}; | 
243  |  |  | 
244  |  | static void FDKaacEnc_Parcor2Index(const FIXP_LPC *parcor, INT *RESTRICT index,  | 
245  |  |                                    const INT order, const INT bitsPerCoeff);  | 
246  |  |  | 
247  |  | static void FDKaacEnc_Index2Parcor(const INT *index, FIXP_LPC *RESTRICT parcor,  | 
248  |  |                                    const INT order, const INT bitsPerCoeff);  | 
249  |  |  | 
250  |  | static void FDKaacEnc_CalcGaussWindow(FIXP_DBL *win, const int winSize,  | 
251  |  |                                       const INT samplingRate,  | 
252  |  |                                       const INT transformResolution,  | 
253  |  |                                       const FIXP_DBL timeResolution,  | 
254  |  |                                       const INT timeResolution_e);  | 
255  |  |  | 
256  |  | static const TNS_PARAMETER_TABULATED *FDKaacEnc_GetTnsParam(const INT bitRate,  | 
257  |  |                                                             const INT channels,  | 
258  | 0  |                                                             const INT sbrLd) { | 
259  | 0  |   int i;  | 
260  | 0  |   const TNS_PARAMETER_TABULATED *tnsConfigTab = NULL;  | 
261  |  | 
  | 
262  | 0  |   for (i = 0; i < (int)(sizeof(tnsInfoTab) / sizeof(TNS_INFO_TAB)); i++) { | 
263  | 0  |     if ((bitRate >= tnsInfoTab[i].bitRateFrom[sbrLd ? 1 : 0]) &&  | 
264  | 0  |         bitRate <= tnsInfoTab[i].bitRateTo[sbrLd ? 1 : 0]) { | 
265  | 0  |       tnsConfigTab = &tnsInfoTab[i].paramTab[(channels == 1) ? 0 : 1];  | 
266  | 0  |     }  | 
267  | 0  |   }  | 
268  |  | 
  | 
269  | 0  |   return tnsConfigTab;  | 
270  | 0  | }  | 
271  |  |  | 
272  |  | static INT getTnsMaxBands(const INT sampleRate, const INT granuleLength,  | 
273  | 0  |                           const INT isShortBlock) { | 
274  | 0  |   int i;  | 
275  | 0  |   INT numBands = -1;  | 
276  | 0  |   const TNS_MAX_TAB_ENTRY *pMaxBandsTab = NULL;  | 
277  | 0  |   int maxBandsTabSize = 0;  | 
278  |  | 
  | 
279  | 0  |   switch (granuleLength) { | 
280  | 0  |     case 960:  | 
281  | 0  |     case 1024:  | 
282  | 0  |       pMaxBandsTab = tnsMaxBandsTab1024;  | 
283  | 0  |       maxBandsTabSize = sizeof(tnsMaxBandsTab1024) / sizeof(TNS_MAX_TAB_ENTRY);  | 
284  | 0  |       break;  | 
285  | 0  |     case 120:  | 
286  | 0  |       pMaxBandsTab = tnsMaxBandsTab120;  | 
287  | 0  |       maxBandsTabSize = sizeof(tnsMaxBandsTab120) / sizeof(TNS_MAX_TAB_ENTRY);  | 
288  | 0  |       break;  | 
289  | 0  |     case 128:  | 
290  | 0  |       pMaxBandsTab = tnsMaxBandsTab128;  | 
291  | 0  |       maxBandsTabSize = sizeof(tnsMaxBandsTab128) / sizeof(TNS_MAX_TAB_ENTRY);  | 
292  | 0  |       break;  | 
293  | 0  |     case 240:  | 
294  | 0  |       pMaxBandsTab = tnsMaxBandsTab240;  | 
295  | 0  |       maxBandsTabSize = sizeof(tnsMaxBandsTab240) / sizeof(TNS_MAX_TAB_ENTRY);  | 
296  | 0  |       break;  | 
297  | 0  |     case 256:  | 
298  | 0  |       pMaxBandsTab = tnsMaxBandsTab256;  | 
299  | 0  |       maxBandsTabSize = sizeof(tnsMaxBandsTab256) / sizeof(TNS_MAX_TAB_ENTRY);  | 
300  | 0  |       break;  | 
301  | 0  |     case 480:  | 
302  | 0  |       pMaxBandsTab = tnsMaxBandsTab480;  | 
303  | 0  |       maxBandsTabSize = sizeof(tnsMaxBandsTab480) / sizeof(TNS_MAX_TAB_ENTRY);  | 
304  | 0  |       break;  | 
305  | 0  |     case 512:  | 
306  | 0  |       pMaxBandsTab = tnsMaxBandsTab512;  | 
307  | 0  |       maxBandsTabSize = sizeof(tnsMaxBandsTab512) / sizeof(TNS_MAX_TAB_ENTRY);  | 
308  | 0  |       break;  | 
309  | 0  |     default:  | 
310  | 0  |       numBands = -1;  | 
311  | 0  |   }  | 
312  |  |  | 
313  | 0  |   if (pMaxBandsTab != NULL) { | 
314  | 0  |     for (i = 0; i < maxBandsTabSize; i++) { | 
315  | 0  |       numBands = pMaxBandsTab[i].maxBands[(!isShortBlock) ? 0 : 1];  | 
316  | 0  |       if (sampleRate >= pMaxBandsTab[i].samplingRate) { | 
317  | 0  |         break;  | 
318  | 0  |       }  | 
319  | 0  |     }  | 
320  | 0  |   }  | 
321  |  | 
  | 
322  | 0  |   return numBands;  | 
323  | 0  | }  | 
324  |  |  | 
325  |  | /***************************************************************************/  | 
326  |  | /*!  | 
327  |  |   \brief     FDKaacEnc_FreqToBandWidthRounding  | 
328  |  |  | 
329  |  |   Returns index of nearest band border  | 
330  |  |  | 
331  |  |   \param frequency  | 
332  |  |   \param sampling frequency  | 
333  |  |   \param total number of bands  | 
334  |  |   \param pointer to table of band borders  | 
335  |  |  | 
336  |  |   \return band border  | 
337  |  | ****************************************************************************/  | 
338  |  |  | 
339  |  | INT FDKaacEnc_FreqToBandWidthRounding(const INT freq, const INT fs,  | 
340  |  |                                       const INT numOfBands,  | 
341  | 0  |                                       const INT *bandStartOffset) { | 
342  | 0  |   INT lineNumber, band;  | 
343  |  |  | 
344  |  |   /*  assert(freq >= 0);  */  | 
345  | 0  |   lineNumber = (freq * bandStartOffset[numOfBands] * 4 / fs + 1) / 2;  | 
346  |  |  | 
347  |  |   /* freq > fs/2 */  | 
348  | 0  |   if (lineNumber >= bandStartOffset[numOfBands]) return numOfBands;  | 
349  |  |  | 
350  |  |   /* find band the line number lies in */  | 
351  | 0  |   for (band = 0; band < numOfBands; band++) { | 
352  | 0  |     if (bandStartOffset[band + 1] > lineNumber) break;  | 
353  | 0  |   }  | 
354  |  |  | 
355  |  |   /* round to nearest band border */  | 
356  | 0  |   if (lineNumber - bandStartOffset[band] >  | 
357  | 0  |       bandStartOffset[band + 1] - lineNumber) { | 
358  | 0  |     band++;  | 
359  | 0  |   }  | 
360  |  | 
  | 
361  | 0  |   return (band);  | 
362  | 0  | }  | 
363  |  |  | 
364  |  | /*****************************************************************************  | 
365  |  |  | 
366  |  |     functionname: FDKaacEnc_InitTnsConfiguration  | 
367  |  |     description:  fill TNS_CONFIG structure with sensible content  | 
368  |  |     returns:  | 
369  |  |     input:        bitrate, samplerate, number of channels,  | 
370  |  |                   blocktype (long or short),  | 
371  |  |                   TNS Config struct (modified),  | 
372  |  |                   psy config struct,  | 
373  |  |                   tns active flag  | 
374  |  |     output:  | 
375  |  |  | 
376  |  | *****************************************************************************/  | 
377  |  | AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(  | 
378  |  |     INT bitRate, INT sampleRate, INT channels, INT blockType, INT granuleLength,  | 
379  |  |     INT isLowDelay, INT ldSbrPresent, TNS_CONFIG *tC, PSY_CONFIGURATION *pC,  | 
380  | 0  |     INT active, INT useTnsPeak) { | 
381  | 0  |   int i;  | 
382  |  |   // float acfTimeRes   = (blockType == SHORT_WINDOW) ? 0.125f : 0.046875f;  | 
383  |  | 
  | 
384  | 0  |   if (channels <= 0) return (AAC_ENCODER_ERROR)1;  | 
385  |  |  | 
386  | 0  |   tC->isLowDelay = isLowDelay;  | 
387  |  |  | 
388  |  |   /* initialize TNS filter flag, order, and coefficient resolution (in bits per  | 
389  |  |    * coeff) */  | 
390  | 0  |   tC->tnsActive = (active) ? TRUE : FALSE;  | 
391  | 0  |   tC->maxOrder = (blockType == SHORT_WINDOW) ? 5 : 12; /* maximum: 7, 20 */  | 
392  | 0  |   if (bitRate < 16000) tC->maxOrder -= 2;  | 
393  | 0  |   tC->coefRes = (blockType == SHORT_WINDOW) ? 3 : 4;  | 
394  |  |  | 
395  |  |   /* LPC stop line: highest MDCT line to be coded, but do not go beyond  | 
396  |  |    * TNS_MAX_BANDS! */  | 
397  | 0  |   tC->lpcStopBand = getTnsMaxBands(sampleRate, granuleLength,  | 
398  | 0  |                                    (blockType == SHORT_WINDOW) ? 1 : 0);  | 
399  |  | 
  | 
400  | 0  |   if (tC->lpcStopBand < 0) { | 
401  | 0  |     return (AAC_ENCODER_ERROR)1;  | 
402  | 0  |   }  | 
403  |  |  | 
404  | 0  |   tC->lpcStopBand = fMin(tC->lpcStopBand, pC->sfbActive);  | 
405  | 0  |   tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand];  | 
406  |  | 
  | 
407  | 0  |   switch (granuleLength) { | 
408  | 0  |     case 960:  | 
409  | 0  |     case 1024:  | 
410  |  |       /* TNS start line: skip lower MDCT lines to prevent artifacts due to  | 
411  |  |        * filter mismatch */  | 
412  | 0  |       if (blockType == SHORT_WINDOW) { | 
413  | 0  |         tC->lpcStartBand[LOFILT] = 0;  | 
414  | 0  |       } else { | 
415  | 0  |         tC->lpcStartBand[LOFILT] =  | 
416  | 0  |             (sampleRate < 9391) ? 2 : ((sampleRate < 18783) ? 4 : 8);  | 
417  | 0  |       }  | 
418  | 0  |       tC->lpcStartLine[LOFILT] = pC->sfbOffset[tC->lpcStartBand[LOFILT]];  | 
419  |  | 
  | 
420  | 0  |       i = tC->lpcStopBand;  | 
421  | 0  |       while (pC->sfbOffset[i] >  | 
422  | 0  |              (tC->lpcStartLine[LOFILT] +  | 
423  | 0  |               (tC->lpcStopLine - tC->lpcStartLine[LOFILT]) / 4))  | 
424  | 0  |         i--;  | 
425  | 0  |       tC->lpcStartBand[HIFILT] = i;  | 
426  | 0  |       tC->lpcStartLine[HIFILT] = pC->sfbOffset[i];  | 
427  |  | 
  | 
428  | 0  |       tC->confTab.threshOn[HIFILT] = 1437;  | 
429  | 0  |       tC->confTab.threshOn[LOFILT] = 1500;  | 
430  |  | 
  | 
431  | 0  |       tC->confTab.tnsLimitOrder[HIFILT] = tC->maxOrder;  | 
432  | 0  |       tC->confTab.tnsLimitOrder[LOFILT] = fMax(0, tC->maxOrder - 7);  | 
433  |  | 
  | 
434  | 0  |       tC->confTab.tnsFilterDirection[HIFILT] = FILTER_DIRECTION;  | 
435  | 0  |       tC->confTab.tnsFilterDirection[LOFILT] = FILTER_DIRECTION;  | 
436  |  | 
  | 
437  | 0  |       tC->confTab.acfSplit[HIFILT] =  | 
438  | 0  |           -1; /* signal Merged4to2QuartersAutoCorrelation in  | 
439  |  |                  FDKaacEnc_MergedAutoCorrelation*/  | 
440  | 0  |       tC->confTab.acfSplit[LOFILT] =  | 
441  | 0  |           -1; /* signal Merged4to2QuartersAutoCorrelation in  | 
442  |  |                  FDKaacEnc_MergedAutoCorrelation */  | 
443  |  | 
  | 
444  | 0  |       tC->confTab.filterEnabled[HIFILT] = 1;  | 
445  | 0  |       tC->confTab.filterEnabled[LOFILT] = 1;  | 
446  | 0  |       tC->confTab.seperateFiltersAllowed = 1;  | 
447  |  |  | 
448  |  |       /* compute autocorrelation window based on maximum filter order for given  | 
449  |  |        * block type */  | 
450  |  |       /* for (i = 0; i <= tC->maxOrder + 3; i++) { | 
451  |  |            float acfWinTemp = acfTimeRes * i;  | 
452  |  |            acfWindow[i] = FL2FXCONST_DBL(1.0f - acfWinTemp * acfWinTemp);  | 
453  |  |          }  | 
454  |  |       */  | 
455  | 0  |       if (blockType == SHORT_WINDOW) { | 
456  | 0  |         FDKmemcpy(tC->acfWindow[HIFILT], acfWindowShort,  | 
457  | 0  |                   fMin((LONG)sizeof(acfWindowShort),  | 
458  | 0  |                        (LONG)sizeof(tC->acfWindow[HIFILT])));  | 
459  | 0  |         FDKmemcpy(tC->acfWindow[LOFILT], acfWindowShort,  | 
460  | 0  |                   fMin((LONG)sizeof(acfWindowShort),  | 
461  | 0  |                        (LONG)sizeof(tC->acfWindow[HIFILT])));  | 
462  | 0  |       } else { | 
463  | 0  |         FDKmemcpy(tC->acfWindow[HIFILT], acfWindowLong,  | 
464  | 0  |                   fMin((LONG)sizeof(acfWindowLong),  | 
465  | 0  |                        (LONG)sizeof(tC->acfWindow[HIFILT])));  | 
466  | 0  |         FDKmemcpy(tC->acfWindow[LOFILT], acfWindowLong,  | 
467  | 0  |                   fMin((LONG)sizeof(acfWindowLong),  | 
468  | 0  |                        (LONG)sizeof(tC->acfWindow[HIFILT])));  | 
469  | 0  |       }  | 
470  | 0  |       break;  | 
471  | 0  |     case 480:  | 
472  | 0  |     case 512: { | 
473  | 0  |       const TNS_PARAMETER_TABULATED *pCfg =  | 
474  | 0  |           FDKaacEnc_GetTnsParam(bitRate, channels, ldSbrPresent);  | 
475  | 0  |       if (pCfg != NULL) { | 
476  | 0  |         FDKmemcpy(&(tC->confTab), pCfg, sizeof(tC->confTab));  | 
477  |  | 
  | 
478  | 0  |         tC->lpcStartBand[HIFILT] = FDKaacEnc_FreqToBandWidthRounding(  | 
479  | 0  |             pCfg->filterStartFreq[HIFILT], sampleRate, pC->sfbCnt,  | 
480  | 0  |             pC->sfbOffset);  | 
481  | 0  |         tC->lpcStartLine[HIFILT] = pC->sfbOffset[tC->lpcStartBand[HIFILT]];  | 
482  | 0  |         tC->lpcStartBand[LOFILT] = FDKaacEnc_FreqToBandWidthRounding(  | 
483  | 0  |             pCfg->filterStartFreq[LOFILT], sampleRate, pC->sfbCnt,  | 
484  | 0  |             pC->sfbOffset);  | 
485  | 0  |         tC->lpcStartLine[LOFILT] = pC->sfbOffset[tC->lpcStartBand[LOFILT]];  | 
486  |  | 
  | 
487  | 0  |         FDKaacEnc_CalcGaussWindow(  | 
488  | 0  |             tC->acfWindow[HIFILT], tC->maxOrder + 1, sampleRate, granuleLength,  | 
489  | 0  |             pCfg->tnsTimeResolution[HIFILT], TNS_TIMERES_SCALE);  | 
490  | 0  |         FDKaacEnc_CalcGaussWindow(  | 
491  | 0  |             tC->acfWindow[LOFILT], tC->maxOrder + 1, sampleRate, granuleLength,  | 
492  | 0  |             pCfg->tnsTimeResolution[LOFILT], TNS_TIMERES_SCALE);  | 
493  | 0  |       } else { | 
494  | 0  |         tC->tnsActive =  | 
495  | 0  |             FALSE; /* no configuration available, disable tns tool */  | 
496  | 0  |       }  | 
497  | 0  |     } break;  | 
498  | 0  |     default:  | 
499  | 0  |       tC->tnsActive = FALSE; /* no configuration available, disable tns tool */  | 
500  | 0  |   }  | 
501  |  |  | 
502  | 0  |   return AAC_ENC_OK;  | 
503  | 0  | }  | 
504  |  |  | 
505  |  | /***************************************************************************/  | 
506  |  | /*!  | 
507  |  |   \brief     FDKaacEnc_ScaleUpSpectrum  | 
508  |  |  | 
509  |  |   Scales up spectrum lines in a given frequency section  | 
510  |  |  | 
511  |  |   \param scaled spectrum  | 
512  |  |   \param original spectrum  | 
513  |  |   \param frequency line to start scaling  | 
514  |  |   \param frequency line to enc scaling  | 
515  |  |  | 
516  |  |   \return scale factor  | 
517  |  |  | 
518  |  | ****************************************************************************/  | 
519  |  | static inline INT FDKaacEnc_ScaleUpSpectrum(FIXP_DBL *dest, const FIXP_DBL *src,  | 
520  |  |                                             const INT startLine,  | 
521  | 0  |                                             const INT stopLine) { | 
522  | 0  |   INT i, scale;  | 
523  |  | 
  | 
524  | 0  |   FIXP_DBL maxVal = FL2FXCONST_DBL(0.f);  | 
525  |  |  | 
526  |  |   /* Get highest value in given spectrum */  | 
527  | 0  |   for (i = startLine; i < stopLine; i++) { | 
528  | 0  |     maxVal = fixMax(maxVal, fixp_abs(src[i]));  | 
529  | 0  |   }  | 
530  | 0  |   scale = CountLeadingBits(maxVal);  | 
531  |  |  | 
532  |  |   /* Scale spectrum according to highest value */  | 
533  | 0  |   for (i = startLine; i < stopLine; i++) { | 
534  | 0  |     dest[i] = src[i] << scale;  | 
535  | 0  |   }  | 
536  |  | 
  | 
537  | 0  |   return scale;  | 
538  | 0  | }  | 
539  |  |  | 
540  |  | /***************************************************************************/  | 
541  |  | /*!  | 
542  |  |   \brief     FDKaacEnc_CalcAutoCorrValue  | 
543  |  |  | 
544  |  |   Calculate autocorellation value for one lag  | 
545  |  |  | 
546  |  |   \param pointer to spectrum  | 
547  |  |   \param start line  | 
548  |  |   \param stop line  | 
549  |  |   \param lag to be calculated  | 
550  |  |   \param scaling of the lag  | 
551  |  |  | 
552  |  | ****************************************************************************/  | 
553  |  | static inline FIXP_DBL FDKaacEnc_CalcAutoCorrValue(const FIXP_DBL *spectrum,  | 
554  |  |                                                    const INT startLine,  | 
555  |  |                                                    const INT stopLine,  | 
556  |  |                                                    const INT lag,  | 
557  | 0  |                                                    const INT scale) { | 
558  | 0  |   int i;  | 
559  | 0  |   FIXP_DBL result = FL2FXCONST_DBL(0.f);  | 
560  |  |  | 
561  |  |   /* This versions allows to save memory accesses, when computing pow2 */  | 
562  |  |   /* It is of interest for ARM, XTENSA without parallel memory access  */  | 
563  | 0  |   if (lag == 0) { | 
564  | 0  |     for (i = startLine; i < stopLine; i++) { | 
565  | 0  |       result += (fPow2(spectrum[i]) >> scale);  | 
566  | 0  |     }  | 
567  | 0  |   } else { | 
568  | 0  |     for (i = startLine; i < (stopLine - lag); i++) { | 
569  | 0  |       result += (fMult(spectrum[i], spectrum[i + lag]) >> scale);  | 
570  | 0  |     }  | 
571  | 0  |   }  | 
572  |  | 
  | 
573  | 0  |   return result;  | 
574  | 0  | }  | 
575  |  |  | 
576  |  | /***************************************************************************/  | 
577  |  | /*!  | 
578  |  |   \brief     FDKaacEnc_AutoCorrNormFac  | 
579  |  |  | 
580  |  |   Autocorrelation function for 1st and 2nd half of the spectrum  | 
581  |  |  | 
582  |  |   \param pointer to spectrum  | 
583  |  |   \param pointer to autocorrelation window  | 
584  |  |   \param filter start line  | 
585  |  |  | 
586  |  | ****************************************************************************/  | 
587  |  | static inline FIXP_DBL FDKaacEnc_AutoCorrNormFac(const FIXP_DBL value,  | 
588  | 0  |                                                  const INT scale, INT *sc) { | 
589  | 0  | #define HLM_MIN_NRG 0.0000000037252902984619140625f /* 2^-28 */  | 
590  | 0  | #define MAX_INV_NRGFAC (1.f / HLM_MIN_NRG)  | 
591  |  | 
  | 
592  | 0  |   FIXP_DBL retValue;  | 
593  | 0  |   FIXP_DBL A, B;  | 
594  |  | 
  | 
595  | 0  |   if (scale >= 0) { | 
596  | 0  |     A = value;  | 
597  | 0  |     B = FL2FXCONST_DBL(HLM_MIN_NRG) >> fixMin(DFRACT_BITS - 1, scale);  | 
598  | 0  |   } else { | 
599  | 0  |     A = value >> fixMin(DFRACT_BITS - 1, (-scale));  | 
600  | 0  |     B = FL2FXCONST_DBL(HLM_MIN_NRG);  | 
601  | 0  |   }  | 
602  |  | 
  | 
603  | 0  |   if (A > B) { | 
604  | 0  |     int shift = 0;  | 
605  | 0  |     FIXP_DBL tmp = invSqrtNorm2(value, &shift);  | 
606  |  | 
  | 
607  | 0  |     retValue = fMult(tmp, tmp);  | 
608  | 0  |     *sc += (2 * shift);  | 
609  | 0  |   } else { | 
610  |  |     /* MAX_INV_NRGFAC*FDKpow(2,-28) = 1/2^-28 * 2^-28 = 1.0 */  | 
611  | 0  |     retValue =  | 
612  | 0  |         /*FL2FXCONST_DBL(MAX_INV_NRGFAC*FDKpow(2,-28))*/ (FIXP_DBL)MAXVAL_DBL;  | 
613  | 0  |     *sc += scale + 28;  | 
614  | 0  |   }  | 
615  |  | 
  | 
616  | 0  |   return retValue;  | 
617  | 0  | }  | 
618  |  |  | 
619  |  | static void FDKaacEnc_MergedAutoCorrelation(  | 
620  |  |     const FIXP_DBL *spectrum, const INT isLowDelay,  | 
621  |  |     const FIXP_DBL acfWindow[MAX_NUM_OF_FILTERS][TNS_MAX_ORDER + 3 + 1],  | 
622  |  |     const INT lpcStartLine[MAX_NUM_OF_FILTERS], const INT lpcStopLine,  | 
623  |  |     const INT maxOrder, const INT acfSplit[MAX_NUM_OF_FILTERS], FIXP_DBL *_rxx1,  | 
624  | 0  |     FIXP_DBL *_rxx2) { | 
625  | 0  |   int i, idx0, idx1, idx2, idx3, idx4, lag;  | 
626  | 0  |   FIXP_DBL rxx1_0, rxx2_0, rxx3_0, rxx4_0;  | 
627  |  |  | 
628  |  |   /* buffer for temporal spectrum */  | 
629  | 0  |   C_ALLOC_SCRATCH_START(pSpectrum, FIXP_DBL, (1024))  | 
630  |  |  | 
631  |  |   /* MDCT line indices separating the 1st, 2nd, 3rd, and 4th analysis quarters  | 
632  |  |    */  | 
633  | 0  |   if ((acfSplit[LOFILT] == -1) || (acfSplit[HIFILT] == -1)) { | 
634  |  |     /* autocorrelation function for 1st, 2nd, 3rd, and 4th quarter of the  | 
635  |  |      * spectrum */  | 
636  | 0  |     idx0 = lpcStartLine[LOFILT];  | 
637  | 0  |     i = lpcStopLine - lpcStartLine[LOFILT];  | 
638  | 0  |     idx1 = idx0 + i / 4;  | 
639  | 0  |     idx2 = idx0 + i / 2;  | 
640  | 0  |     idx3 = idx0 + i * 3 / 4;  | 
641  | 0  |     idx4 = lpcStopLine;  | 
642  | 0  |   } else { | 
643  | 0  |     FDK_ASSERT(acfSplit[LOFILT] == 1);  | 
644  | 0  |     FDK_ASSERT(acfSplit[HIFILT] == 3);  | 
645  | 0  |     i = (lpcStopLine - lpcStartLine[HIFILT]) / 3;  | 
646  | 0  |     idx0 = lpcStartLine[LOFILT];  | 
647  | 0  |     idx1 = lpcStartLine[HIFILT];  | 
648  | 0  |     idx2 = idx1 + i;  | 
649  | 0  |     idx3 = idx2 + i;  | 
650  | 0  |     idx4 = lpcStopLine;  | 
651  | 0  |   }  | 
652  |  |  | 
653  |  |   /* copy spectrum to temporal buffer and scale up as much as possible */  | 
654  | 0  |   INT sc1 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx0, idx1);  | 
655  | 0  |   INT sc2 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx1, idx2);  | 
656  | 0  |   INT sc3 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx2, idx3);  | 
657  | 0  |   INT sc4 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx3, idx4);  | 
658  |  |  | 
659  |  |   /* get scaling values for summation */  | 
660  | 0  |   INT nsc1, nsc2, nsc3, nsc4;  | 
661  | 0  |   for (nsc1 = 1; (1 << nsc1) < (idx1 - idx0); nsc1++)  | 
662  | 0  |     ;  | 
663  | 0  |   for (nsc2 = 1; (1 << nsc2) < (idx2 - idx1); nsc2++)  | 
664  | 0  |     ;  | 
665  | 0  |   for (nsc3 = 1; (1 << nsc3) < (idx3 - idx2); nsc3++)  | 
666  | 0  |     ;  | 
667  | 0  |   for (nsc4 = 1; (1 << nsc4) < (idx4 - idx3); nsc4++)  | 
668  | 0  |     ;  | 
669  |  |  | 
670  |  |   /* compute autocorrelation value at lag zero, i. e. energy, for each quarter  | 
671  |  |    */  | 
672  | 0  |   rxx1_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, 0, nsc1);  | 
673  | 0  |   rxx2_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx1, idx2, 0, nsc2);  | 
674  | 0  |   rxx3_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx2, idx3, 0, nsc3);  | 
675  | 0  |   rxx4_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx3, idx4, 0, nsc4);  | 
676  |  |  | 
677  |  |   /* compute energy normalization factors, i. e. 1/energy (saves some divisions)  | 
678  |  |    */  | 
679  | 0  |   if (rxx1_0 != FL2FXCONST_DBL(0.f)) { | 
680  | 0  |     INT sc_fac1 = -1;  | 
681  | 0  |     FIXP_DBL fac1 =  | 
682  | 0  |         FDKaacEnc_AutoCorrNormFac(rxx1_0, ((-2 * sc1) + nsc1), &sc_fac1);  | 
683  | 0  |     _rxx1[0] = scaleValue(fMult(rxx1_0, fac1), sc_fac1);  | 
684  |  | 
  | 
685  | 0  |     if (isLowDelay) { | 
686  | 0  |       for (lag = 1; lag <= maxOrder; lag++) { | 
687  |  |         /* compute energy-normalized and windowed autocorrelation values at this  | 
688  |  |          * lag */  | 
689  | 0  |         FIXP_DBL x1 =  | 
690  | 0  |             FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, lag, nsc1);  | 
691  | 0  |         _rxx1[lag] =  | 
692  | 0  |             fMult(scaleValue(fMult(x1, fac1), sc_fac1), acfWindow[LOFILT][lag]);  | 
693  | 0  |       }  | 
694  | 0  |     } else { | 
695  | 0  |       for (lag = 1; lag <= maxOrder; lag++) { | 
696  | 0  |         if ((3 * lag) <= maxOrder + 3) { | 
697  | 0  |           FIXP_DBL x1 =  | 
698  | 0  |               FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, lag, nsc1);  | 
699  | 0  |           _rxx1[lag] = fMult(scaleValue(fMult(x1, fac1), sc_fac1),  | 
700  | 0  |                              acfWindow[LOFILT][3 * lag]);  | 
701  | 0  |         }  | 
702  | 0  |       }  | 
703  | 0  |     }  | 
704  | 0  |   }  | 
705  |  |  | 
706  |  |   /* auto corr over upper 3/4 of spectrum */  | 
707  | 0  |   if (!((rxx2_0 == FL2FXCONST_DBL(0.f)) && (rxx3_0 == FL2FXCONST_DBL(0.f)) &&  | 
708  | 0  |         (rxx4_0 == FL2FXCONST_DBL(0.f)))) { | 
709  | 0  |     FIXP_DBL fac2, fac3, fac4;  | 
710  | 0  |     fac2 = fac3 = fac4 = FL2FXCONST_DBL(0.f);  | 
711  | 0  |     INT sc_fac2, sc_fac3, sc_fac4;  | 
712  | 0  |     sc_fac2 = sc_fac3 = sc_fac4 = 0;  | 
713  |  | 
  | 
714  | 0  |     if (rxx2_0 != FL2FXCONST_DBL(0.f)) { | 
715  | 0  |       fac2 = FDKaacEnc_AutoCorrNormFac(rxx2_0, ((-2 * sc2) + nsc2), &sc_fac2);  | 
716  | 0  |       sc_fac2 -= 2;  | 
717  | 0  |     }  | 
718  | 0  |     if (rxx3_0 != FL2FXCONST_DBL(0.f)) { | 
719  | 0  |       fac3 = FDKaacEnc_AutoCorrNormFac(rxx3_0, ((-2 * sc3) + nsc3), &sc_fac3);  | 
720  | 0  |       sc_fac3 -= 2;  | 
721  | 0  |     }  | 
722  | 0  |     if (rxx4_0 != FL2FXCONST_DBL(0.f)) { | 
723  | 0  |       fac4 = FDKaacEnc_AutoCorrNormFac(rxx4_0, ((-2 * sc4) + nsc4), &sc_fac4);  | 
724  | 0  |       sc_fac4 -= 2;  | 
725  | 0  |     }  | 
726  |  | 
  | 
727  | 0  |     _rxx2[0] = scaleValue(fMult(rxx2_0, fac2), sc_fac2) +  | 
728  | 0  |                scaleValue(fMult(rxx3_0, fac3), sc_fac3) +  | 
729  | 0  |                scaleValue(fMult(rxx4_0, fac4), sc_fac4);  | 
730  |  | 
  | 
731  | 0  |     for (lag = 1; lag <= maxOrder; lag++) { | 
732  |  |       /* merge quarters 2, 3, 4 into one autocorrelation; quarter 1 stays  | 
733  |  |        * separate */  | 
734  | 0  |       FIXP_DBL x2 = scaleValue(fMult(FDKaacEnc_CalcAutoCorrValue(  | 
735  | 0  |                                          pSpectrum, idx1, idx2, lag, nsc2),  | 
736  | 0  |                                      fac2),  | 
737  | 0  |                                sc_fac2) +  | 
738  | 0  |                     scaleValue(fMult(FDKaacEnc_CalcAutoCorrValue(  | 
739  | 0  |                                          pSpectrum, idx2, idx3, lag, nsc3),  | 
740  | 0  |                                      fac3),  | 
741  | 0  |                                sc_fac3) +  | 
742  | 0  |                     scaleValue(fMult(FDKaacEnc_CalcAutoCorrValue(  | 
743  | 0  |                                          pSpectrum, idx3, idx4, lag, nsc4),  | 
744  | 0  |                                      fac4),  | 
745  | 0  |                                sc_fac4);  | 
746  |  | 
  | 
747  | 0  |       _rxx2[lag] = fMult(x2, acfWindow[HIFILT][lag]);  | 
748  | 0  |     }  | 
749  | 0  |   }  | 
750  |  | 
  | 
751  | 0  |   C_ALLOC_SCRATCH_END(pSpectrum, FIXP_DBL, (1024))  | 
752  | 0  | }  | 
753  |  |  | 
754  |  | /*****************************************************************************  | 
755  |  |     functionname: FDKaacEnc_TnsDetect  | 
756  |  |     description:  do decision, if TNS shall be used or not  | 
757  |  |     returns:  | 
758  |  |     input:        tns data structure (modified),  | 
759  |  |                   tns config structure,  | 
760  |  |                   scalefactor size and table,  | 
761  |  |                   spectrum,  | 
762  |  |                   subblock num, blocktype,  | 
763  |  |                   sfb-wise energy.  | 
764  |  |  | 
765  |  | *****************************************************************************/  | 
766  |  | INT FDKaacEnc_TnsDetect(TNS_DATA *tnsData, const TNS_CONFIG *tC,  | 
767  |  |                         TNS_INFO *tnsInfo, INT sfbCnt, const FIXP_DBL *spectrum,  | 
768  | 0  |                         INT subBlockNumber, INT blockType) { | 
769  |  |   /* autocorrelation function for 1st, 2nd, 3rd, and 4th quarter of the  | 
770  |  |    * spectrum. */  | 
771  | 0  |   FIXP_DBL rxx1[TNS_MAX_ORDER + 1]; /* higher part */  | 
772  | 0  |   FIXP_DBL rxx2[TNS_MAX_ORDER + 1]; /* lower part */  | 
773  | 0  |   FIXP_LPC parcor_tmp[TNS_MAX_ORDER];  | 
774  |  | 
  | 
775  | 0  |   int i;  | 
776  |  | 
  | 
777  | 0  |   FDKmemclear(rxx1, sizeof(rxx1));  | 
778  | 0  |   FDKmemclear(rxx2, sizeof(rxx2));  | 
779  |  | 
  | 
780  | 0  |   TNS_SUBBLOCK_INFO *tsbi =  | 
781  | 0  |       (blockType == SHORT_WINDOW)  | 
782  | 0  |           ? &tnsData->dataRaw.Short.subBlockInfo[subBlockNumber]  | 
783  | 0  |           : &tnsData->dataRaw.Long.subBlockInfo;  | 
784  |  | 
  | 
785  | 0  |   tnsData->filtersMerged = FALSE;  | 
786  |  | 
  | 
787  | 0  |   tsbi->tnsActive[HIFILT] = FALSE;  | 
788  | 0  |   tsbi->predictionGain[HIFILT] = 1000;  | 
789  | 0  |   tsbi->tnsActive[LOFILT] = FALSE;  | 
790  | 0  |   tsbi->predictionGain[LOFILT] = 1000;  | 
791  |  | 
  | 
792  | 0  |   tnsInfo->numOfFilters[subBlockNumber] = 0;  | 
793  | 0  |   tnsInfo->coefRes[subBlockNumber] = tC->coefRes;  | 
794  | 0  |   for (i = 0; i < tC->maxOrder; i++) { | 
795  | 0  |     tnsInfo->coef[subBlockNumber][HIFILT][i] =  | 
796  | 0  |         tnsInfo->coef[subBlockNumber][LOFILT][i] = 0;  | 
797  | 0  |   }  | 
798  |  | 
  | 
799  | 0  |   tnsInfo->length[subBlockNumber][HIFILT] =  | 
800  | 0  |       tnsInfo->length[subBlockNumber][LOFILT] = 0;  | 
801  | 0  |   tnsInfo->order[subBlockNumber][HIFILT] =  | 
802  | 0  |       tnsInfo->order[subBlockNumber][LOFILT] = 0;  | 
803  |  | 
  | 
804  | 0  |   if ((tC->tnsActive) && (tC->maxOrder > 0)) { | 
805  | 0  |     int sumSqrCoef;  | 
806  |  | 
  | 
807  | 0  |     FDKaacEnc_MergedAutoCorrelation(  | 
808  | 0  |         spectrum, tC->isLowDelay, tC->acfWindow, tC->lpcStartLine,  | 
809  | 0  |         tC->lpcStopLine, tC->maxOrder, tC->confTab.acfSplit, rxx1, rxx2);  | 
810  |  |  | 
811  |  |     /* compute higher TNS filter coefficients in lattice form (ParCor) with  | 
812  |  |      * LeRoux-Gueguen/Schur algorithm */  | 
813  | 0  |     { | 
814  | 0  |       FIXP_DBL predictionGain_m;  | 
815  | 0  |       INT predictionGain_e;  | 
816  |  | 
  | 
817  | 0  |       CLpc_AutoToParcor(rxx2, 0, parcor_tmp, tC->confTab.tnsLimitOrder[HIFILT],  | 
818  | 0  |                         &predictionGain_m, &predictionGain_e);  | 
819  | 0  |       tsbi->predictionGain[HIFILT] =  | 
820  | 0  |           (INT)fMultNorm(predictionGain_m, predictionGain_e, 1000, 31, 31);  | 
821  | 0  |     }  | 
822  |  |  | 
823  |  |     /* non-linear quantization of TNS lattice coefficients with given resolution  | 
824  |  |      */  | 
825  | 0  |     FDKaacEnc_Parcor2Index(parcor_tmp, tnsInfo->coef[subBlockNumber][HIFILT],  | 
826  | 0  |                            tC->confTab.tnsLimitOrder[HIFILT], tC->coefRes);  | 
827  |  |  | 
828  |  |     /* reduce filter order by truncating trailing zeros, compute sum(abs(coefs))  | 
829  |  |      */  | 
830  | 0  |     for (i = tC->confTab.tnsLimitOrder[HIFILT] - 1; i >= 0; i--) { | 
831  | 0  |       if (tnsInfo->coef[subBlockNumber][HIFILT][i] != 0) { | 
832  | 0  |         break;  | 
833  | 0  |       }  | 
834  | 0  |     }  | 
835  |  | 
  | 
836  | 0  |     tnsInfo->order[subBlockNumber][HIFILT] = i + 1;  | 
837  |  | 
  | 
838  | 0  |     sumSqrCoef = 0;  | 
839  | 0  |     for (; i >= 0; i--) { | 
840  | 0  |       sumSqrCoef += tnsInfo->coef[subBlockNumber][HIFILT][i] *  | 
841  | 0  |                     tnsInfo->coef[subBlockNumber][HIFILT][i];  | 
842  | 0  |     }  | 
843  |  | 
  | 
844  | 0  |     tnsInfo->direction[subBlockNumber][HIFILT] =  | 
845  | 0  |         tC->confTab.tnsFilterDirection[HIFILT];  | 
846  | 0  |     tnsInfo->length[subBlockNumber][HIFILT] = sfbCnt - tC->lpcStartBand[HIFILT];  | 
847  |  |  | 
848  |  |     /* disable TNS if predictionGain is less than 3dB or sumSqrCoef is too small  | 
849  |  |      */  | 
850  | 0  |     if ((tsbi->predictionGain[HIFILT] > tC->confTab.threshOn[HIFILT]) ||  | 
851  | 0  |         (sumSqrCoef > (tC->confTab.tnsLimitOrder[HIFILT] / 2 + 2))) { | 
852  | 0  |       tsbi->tnsActive[HIFILT] = TRUE;  | 
853  | 0  |       tnsInfo->numOfFilters[subBlockNumber]++;  | 
854  |  |  | 
855  |  |       /* compute second filter for lower quarter; only allowed for long windows!  | 
856  |  |        */  | 
857  | 0  |       if ((blockType != SHORT_WINDOW) && (tC->confTab.filterEnabled[LOFILT]) &&  | 
858  | 0  |           (tC->confTab.seperateFiltersAllowed)) { | 
859  |  |         /* compute second filter for lower frequencies */  | 
860  |  |  | 
861  |  |         /* compute TNS filter in lattice (ParCor) form with LeRoux-Gueguen  | 
862  |  |          * algorithm */  | 
863  | 0  |         INT predGain;  | 
864  | 0  |         { | 
865  | 0  |           FIXP_DBL predictionGain_m;  | 
866  | 0  |           INT predictionGain_e;  | 
867  |  | 
  | 
868  | 0  |           CLpc_AutoToParcor(rxx1, 0, parcor_tmp,  | 
869  | 0  |                             tC->confTab.tnsLimitOrder[LOFILT],  | 
870  | 0  |                             &predictionGain_m, &predictionGain_e);  | 
871  | 0  |           predGain =  | 
872  | 0  |               (INT)fMultNorm(predictionGain_m, predictionGain_e, 1000, 31, 31);  | 
873  | 0  |         }  | 
874  |  |  | 
875  |  |         /* non-linear quantization of TNS lattice coefficients with given  | 
876  |  |          * resolution */  | 
877  | 0  |         FDKaacEnc_Parcor2Index(parcor_tmp,  | 
878  | 0  |                                tnsInfo->coef[subBlockNumber][LOFILT],  | 
879  | 0  |                                tC->confTab.tnsLimitOrder[LOFILT], tC->coefRes);  | 
880  |  |  | 
881  |  |         /* reduce filter order by truncating trailing zeros, compute  | 
882  |  |          * sum(abs(coefs)) */  | 
883  | 0  |         for (i = tC->confTab.tnsLimitOrder[LOFILT] - 1; i >= 0; i--) { | 
884  | 0  |           if (tnsInfo->coef[subBlockNumber][LOFILT][i] != 0) { | 
885  | 0  |             break;  | 
886  | 0  |           }  | 
887  | 0  |         }  | 
888  | 0  |         tnsInfo->order[subBlockNumber][LOFILT] = i + 1;  | 
889  |  | 
  | 
890  | 0  |         sumSqrCoef = 0;  | 
891  | 0  |         for (; i >= 0; i--) { | 
892  | 0  |           sumSqrCoef += tnsInfo->coef[subBlockNumber][LOFILT][i] *  | 
893  | 0  |                         tnsInfo->coef[subBlockNumber][LOFILT][i];  | 
894  | 0  |         }  | 
895  |  | 
  | 
896  | 0  |         tnsInfo->direction[subBlockNumber][LOFILT] =  | 
897  | 0  |             tC->confTab.tnsFilterDirection[LOFILT];  | 
898  | 0  |         tnsInfo->length[subBlockNumber][LOFILT] =  | 
899  | 0  |             tC->lpcStartBand[HIFILT] - tC->lpcStartBand[LOFILT];  | 
900  |  |  | 
901  |  |         /* filter lower quarter if gain is high enough, but not if it's too high  | 
902  |  |          */  | 
903  | 0  |         if (((predGain > tC->confTab.threshOn[LOFILT]) &&  | 
904  | 0  |              (predGain < (16000 * tC->confTab.tnsLimitOrder[LOFILT]))) ||  | 
905  | 0  |             ((sumSqrCoef > 9) &&  | 
906  | 0  |              (sumSqrCoef < 22 * tC->confTab.tnsLimitOrder[LOFILT]))) { | 
907  |  |           /* compare lower to upper filter; if they are very similar, merge them  | 
908  |  |            */  | 
909  | 0  |           tsbi->tnsActive[LOFILT] = TRUE;  | 
910  | 0  |           sumSqrCoef = 0;  | 
911  | 0  |           for (i = 0; i < tC->confTab.tnsLimitOrder[LOFILT]; i++) { | 
912  | 0  |             sumSqrCoef += fAbs(tnsInfo->coef[subBlockNumber][HIFILT][i] -  | 
913  | 0  |                                tnsInfo->coef[subBlockNumber][LOFILT][i]);  | 
914  | 0  |           }  | 
915  | 0  |           if ((sumSqrCoef < 2) &&  | 
916  | 0  |               (tnsInfo->direction[subBlockNumber][LOFILT] ==  | 
917  | 0  |                tnsInfo->direction[subBlockNumber][HIFILT])) { | 
918  | 0  |             tnsData->filtersMerged = TRUE;  | 
919  | 0  |             tnsInfo->length[subBlockNumber][HIFILT] =  | 
920  | 0  |                 sfbCnt - tC->lpcStartBand[LOFILT];  | 
921  | 0  |             for (; i < tnsInfo->order[subBlockNumber][HIFILT]; i++) { | 
922  | 0  |               if (fAbs(tnsInfo->coef[subBlockNumber][HIFILT][i]) > 1) { | 
923  | 0  |                 break;  | 
924  | 0  |               }  | 
925  | 0  |             }  | 
926  | 0  |             for (i--; i >= 0; i--) { | 
927  | 0  |               if (tnsInfo->coef[subBlockNumber][HIFILT][i] != 0) { | 
928  | 0  |                 break;  | 
929  | 0  |               }  | 
930  | 0  |             }  | 
931  | 0  |             if (i < tnsInfo->order[subBlockNumber][HIFILT]) { | 
932  | 0  |               tnsInfo->order[subBlockNumber][HIFILT] = i + 1;  | 
933  | 0  |             }  | 
934  | 0  |           } else { | 
935  | 0  |             tnsInfo->numOfFilters[subBlockNumber]++;  | 
936  | 0  |           }  | 
937  | 0  |         } /* filter lower part */  | 
938  | 0  |         tsbi->predictionGain[LOFILT] = predGain;  | 
939  |  | 
  | 
940  | 0  |       } /* second filter allowed  */  | 
941  | 0  |     }   /* if predictionGain > 1437 ... */  | 
942  | 0  |   }     /* maxOrder > 0 && tnsActive */  | 
943  |  | 
  | 
944  | 0  |   return 0;  | 
945  | 0  | }  | 
946  |  |  | 
947  |  | /***************************************************************************/  | 
948  |  | /*!  | 
949  |  |   \brief     FDKaacLdEnc_TnsSync  | 
950  |  |  | 
951  |  |   synchronize TNS parameters when TNS gain difference small (relative)  | 
952  |  |  | 
953  |  |   \param pointer to TNS data structure (destination)  | 
954  |  |   \param pointer to TNS data structure (source)  | 
955  |  |   \param pointer to TNS config structure  | 
956  |  |   \param number of sub-block  | 
957  |  |   \param block type  | 
958  |  |  | 
959  |  |   \return void  | 
960  |  | ****************************************************************************/  | 
961  |  | void FDKaacEnc_TnsSync(TNS_DATA *tnsDataDest, const TNS_DATA *tnsDataSrc,  | 
962  |  |                        TNS_INFO *tnsInfoDest, TNS_INFO *tnsInfoSrc,  | 
963  |  |                        const INT blockTypeDest, const INT blockTypeSrc,  | 
964  | 0  |                        const TNS_CONFIG *tC) { | 
965  | 0  |   int i, w, absDiff, nWindows;  | 
966  | 0  |   TNS_SUBBLOCK_INFO *sbInfoDest;  | 
967  | 0  |   const TNS_SUBBLOCK_INFO *sbInfoSrc;  | 
968  |  |  | 
969  |  |   /* if one channel contains short blocks and the other not, do not synchronize  | 
970  |  |    */  | 
971  | 0  |   if ((blockTypeSrc == SHORT_WINDOW && blockTypeDest != SHORT_WINDOW) ||  | 
972  | 0  |       (blockTypeDest == SHORT_WINDOW && blockTypeSrc != SHORT_WINDOW)) { | 
973  | 0  |     return;  | 
974  | 0  |   }  | 
975  |  |  | 
976  | 0  |   if (blockTypeDest != SHORT_WINDOW) { | 
977  | 0  |     sbInfoDest = &tnsDataDest->dataRaw.Long.subBlockInfo;  | 
978  | 0  |     sbInfoSrc = &tnsDataSrc->dataRaw.Long.subBlockInfo;  | 
979  | 0  |     nWindows = 1;  | 
980  | 0  |   } else { | 
981  | 0  |     sbInfoDest = &tnsDataDest->dataRaw.Short.subBlockInfo[0];  | 
982  | 0  |     sbInfoSrc = &tnsDataSrc->dataRaw.Short.subBlockInfo[0];  | 
983  | 0  |     nWindows = 8;  | 
984  | 0  |   }  | 
985  |  | 
  | 
986  | 0  |   for (w = 0; w < nWindows; w++) { | 
987  | 0  |     const TNS_SUBBLOCK_INFO *pSbInfoSrcW = sbInfoSrc + w;  | 
988  | 0  |     TNS_SUBBLOCK_INFO *pSbInfoDestW = sbInfoDest + w;  | 
989  | 0  |     INT doSync = 1, absDiffSum = 0;  | 
990  |  |  | 
991  |  |     /* if TNS is active in at least one channel, check if ParCor coefficients of  | 
992  |  |      * higher filter are similar */  | 
993  | 0  |     if (pSbInfoDestW->tnsActive[HIFILT] || pSbInfoSrcW->tnsActive[HIFILT]) { | 
994  | 0  |       for (i = 0; i < tC->maxOrder; i++) { | 
995  | 0  |         absDiff = fAbs(tnsInfoDest->coef[w][HIFILT][i] -  | 
996  | 0  |                        tnsInfoSrc->coef[w][HIFILT][i]);  | 
997  | 0  |         absDiffSum += absDiff;  | 
998  |  |         /* if coefficients diverge too much between channels, do not synchronize  | 
999  |  |          */  | 
1000  | 0  |         if ((absDiff > 1) || (absDiffSum > 2)) { | 
1001  | 0  |           doSync = 0;  | 
1002  | 0  |           break;  | 
1003  | 0  |         }  | 
1004  | 0  |       }  | 
1005  |  | 
  | 
1006  | 0  |       if (doSync) { | 
1007  |  |         /* if no significant difference was detected, synchronize coefficient  | 
1008  |  |          * sets */  | 
1009  | 0  |         if (pSbInfoSrcW->tnsActive[HIFILT]) { | 
1010  |  |           /* no dest filter, or more dest than source filters: use one dest  | 
1011  |  |            * filter */  | 
1012  | 0  |           if ((!pSbInfoDestW->tnsActive[HIFILT]) ||  | 
1013  | 0  |               ((pSbInfoDestW->tnsActive[HIFILT]) &&  | 
1014  | 0  |                (tnsInfoDest->numOfFilters[w] > tnsInfoSrc->numOfFilters[w]))) { | 
1015  | 0  |             pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 1;  | 
1016  | 0  |           }  | 
1017  | 0  |           tnsDataDest->filtersMerged = tnsDataSrc->filtersMerged;  | 
1018  | 0  |           tnsInfoDest->order[w][HIFILT] = tnsInfoSrc->order[w][HIFILT];  | 
1019  | 0  |           tnsInfoDest->length[w][HIFILT] = tnsInfoSrc->length[w][HIFILT];  | 
1020  | 0  |           tnsInfoDest->direction[w][HIFILT] = tnsInfoSrc->direction[w][HIFILT];  | 
1021  | 0  |           tnsInfoDest->coefCompress[w][HIFILT] =  | 
1022  | 0  |               tnsInfoSrc->coefCompress[w][HIFILT];  | 
1023  |  | 
  | 
1024  | 0  |           for (i = 0; i < tC->maxOrder; i++) { | 
1025  | 0  |             tnsInfoDest->coef[w][HIFILT][i] = tnsInfoSrc->coef[w][HIFILT][i];  | 
1026  | 0  |           }  | 
1027  | 0  |         } else  | 
1028  | 0  |           pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 0;  | 
1029  | 0  |       }  | 
1030  | 0  |     }  | 
1031  | 0  |   }  | 
1032  | 0  | }  | 
1033  |  |  | 
1034  |  | /***************************************************************************/  | 
1035  |  | /*!  | 
1036  |  |   \brief     FDKaacEnc_TnsEncode  | 
1037  |  |  | 
1038  |  |   perform TNS encoding  | 
1039  |  |  | 
1040  |  |   \param pointer to TNS info structure  | 
1041  |  |   \param pointer to TNS data structure  | 
1042  |  |   \param number of sfbs  | 
1043  |  |   \param pointer to TNS config structure  | 
1044  |  |   \param low-pass line  | 
1045  |  |   \param pointer to spectrum  | 
1046  |  |   \param number of sub-block  | 
1047  |  |   \param block type  | 
1048  |  |  | 
1049  |  |   \return ERROR STATUS  | 
1050  |  | ****************************************************************************/  | 
1051  |  | INT FDKaacEnc_TnsEncode(TNS_INFO *tnsInfo, TNS_DATA *tnsData,  | 
1052  |  |                         const INT numOfSfb, const TNS_CONFIG *tC,  | 
1053  |  |                         const INT lowPassLine, FIXP_DBL *spectrum,  | 
1054  | 0  |                         const INT subBlockNumber, const INT blockType) { | 
1055  | 0  |   INT i, startLine, stopLine;  | 
1056  |  | 
  | 
1057  | 0  |   if (((blockType == SHORT_WINDOW) &&  | 
1058  | 0  |        (!tnsData->dataRaw.Short.subBlockInfo[subBlockNumber]  | 
1059  | 0  |              .tnsActive[HIFILT])) ||  | 
1060  | 0  |       ((blockType != SHORT_WINDOW) &&  | 
1061  | 0  |        (!tnsData->dataRaw.Long.subBlockInfo.tnsActive[HIFILT]))) { | 
1062  | 0  |     return 1;  | 
1063  | 0  |   }  | 
1064  |  |  | 
1065  | 0  |   startLine = (tnsData->filtersMerged) ? tC->lpcStartLine[LOFILT]  | 
1066  | 0  |                                        : tC->lpcStartLine[HIFILT];  | 
1067  | 0  |   stopLine = tC->lpcStopLine;  | 
1068  |  | 
  | 
1069  | 0  |   for (i = 0; i < tnsInfo->numOfFilters[subBlockNumber]; i++) { | 
1070  | 0  |     INT lpcGainFactor;  | 
1071  | 0  |     FIXP_LPC LpcCoeff[TNS_MAX_ORDER];  | 
1072  | 0  |     FIXP_DBL workBuffer[TNS_MAX_ORDER];  | 
1073  | 0  |     FIXP_LPC parcor_tmp[TNS_MAX_ORDER];  | 
1074  |  | 
  | 
1075  | 0  |     FDKaacEnc_Index2Parcor(tnsInfo->coef[subBlockNumber][i], parcor_tmp,  | 
1076  | 0  |                            tnsInfo->order[subBlockNumber][i], tC->coefRes);  | 
1077  |  | 
  | 
1078  | 0  |     lpcGainFactor = CLpc_ParcorToLpc(  | 
1079  | 0  |         parcor_tmp, LpcCoeff, tnsInfo->order[subBlockNumber][i], workBuffer);  | 
1080  |  | 
  | 
1081  | 0  |     FDKmemclear(workBuffer, TNS_MAX_ORDER * sizeof(FIXP_DBL));  | 
1082  | 0  |     CLpc_Analysis(&spectrum[startLine], stopLine - startLine, LpcCoeff,  | 
1083  | 0  |                   lpcGainFactor, tnsInfo->order[subBlockNumber][i], workBuffer,  | 
1084  | 0  |                   NULL);  | 
1085  |  |  | 
1086  |  |     /* update for second filter */  | 
1087  | 0  |     startLine = tC->lpcStartLine[LOFILT];  | 
1088  | 0  |     stopLine = tC->lpcStartLine[HIFILT];  | 
1089  | 0  |   }  | 
1090  |  | 
  | 
1091  | 0  |   return (0);  | 
1092  | 0  | }  | 
1093  |  |  | 
1094  |  | static void FDKaacEnc_CalcGaussWindow(FIXP_DBL *win, const int winSize,  | 
1095  |  |                                       const INT samplingRate,  | 
1096  |  |                                       const INT transformResolution,  | 
1097  |  |                                       const FIXP_DBL timeResolution,  | 
1098  | 0  |                                       const INT timeResolution_e) { | 
1099  | 0  | #define PI_E (2)  | 
1100  | 0  | #define PI_M FL2FXCONST_DBL(3.1416f / (float)(1 << PI_E))  | 
1101  |  | 
  | 
1102  | 0  | #define EULER_E (2)  | 
1103  | 0  | #define EULER_M FL2FXCONST_DBL(2.7183 / (float)(1 << EULER_E))  | 
1104  |  | 
  | 
1105  | 0  | #define COEFF_LOOP_SCALE (4)  | 
1106  |  | 
  | 
1107  | 0  |   INT i, e1, e2, gaussExp_e;  | 
1108  | 0  |   FIXP_DBL gaussExp_m;  | 
1109  |  |  | 
1110  |  |   /* calc. window exponent from time resolution:  | 
1111  |  |    *  | 
1112  |  |    *   gaussExp = PI * samplingRate * 0.001f * timeResolution /  | 
1113  |  |    * transformResolution; gaussExp = -0.5f * gaussExp * gaussExp;  | 
1114  |  |    */  | 
1115  | 0  |   gaussExp_m = fMultNorm(  | 
1116  | 0  |       timeResolution,  | 
1117  | 0  |       fMult(PI_M,  | 
1118  | 0  |             fDivNorm((FIXP_DBL)(samplingRate),  | 
1119  | 0  |                      (FIXP_DBL)(LONG)(transformResolution * 1000.f), &e1)),  | 
1120  | 0  |       &e2);  | 
1121  | 0  |   gaussExp_m = -fPow2Div2(gaussExp_m);  | 
1122  | 0  |   gaussExp_e = 2 * (e1 + e2 + timeResolution_e + PI_E);  | 
1123  |  | 
  | 
1124  | 0  |   FDK_ASSERT(winSize < (1 << COEFF_LOOP_SCALE));  | 
1125  |  |  | 
1126  |  |   /* calc. window coefficients  | 
1127  |  |    *   win[i] = (float)exp( gaussExp * (i+0.5) * (i+0.5) );  | 
1128  |  |    */  | 
1129  | 0  |   for (i = 0; i < winSize; i++) { | 
1130  | 0  |     win[i] = fPow(  | 
1131  | 0  |         EULER_M, EULER_E,  | 
1132  | 0  |         fMult(gaussExp_m,  | 
1133  | 0  |               fPow2((i * FL2FXCONST_DBL(1.f / (float)(1 << COEFF_LOOP_SCALE)) +  | 
1134  | 0  |                      FL2FXCONST_DBL(.5f / (float)(1 << COEFF_LOOP_SCALE))))),  | 
1135  | 0  |         gaussExp_e + 2 * COEFF_LOOP_SCALE, &e1);  | 
1136  |  | 
  | 
1137  | 0  |     win[i] = scaleValueSaturate(win[i], e1);  | 
1138  | 0  |   }  | 
1139  | 0  | }  | 
1140  |  |  | 
1141  | 0  | static INT FDKaacEnc_Search3(FIXP_LPC parcor) { | 
1142  | 0  |   INT i, index = 0;  | 
1143  |  | 
  | 
1144  | 0  |   for (i = 0; i < 8; i++) { | 
1145  | 0  |     if (parcor > FDKaacEnc_tnsCoeff3Borders[i]) index = i;  | 
1146  | 0  |   }  | 
1147  | 0  |   return (index - 4);  | 
1148  | 0  | }  | 
1149  |  |  | 
1150  | 0  | static INT FDKaacEnc_Search4(FIXP_LPC parcor) { | 
1151  | 0  |   INT i, index = 0;  | 
1152  |  | 
  | 
1153  | 0  |   for (i = 0; i < 16; i++) { | 
1154  | 0  |     if (parcor > FDKaacEnc_tnsCoeff4Borders[i]) index = i;  | 
1155  | 0  |   }  | 
1156  | 0  |   return (index - 8);  | 
1157  | 0  | }  | 
1158  |  |  | 
1159  |  | /*****************************************************************************  | 
1160  |  |  | 
1161  |  |     functionname: FDKaacEnc_Parcor2Index  | 
1162  |  |  | 
1163  |  | *****************************************************************************/  | 
1164  |  | static void FDKaacEnc_Parcor2Index(const FIXP_LPC *parcor, INT *RESTRICT index,  | 
1165  | 0  |                                    const INT order, const INT bitsPerCoeff) { | 
1166  | 0  |   INT i;  | 
1167  | 0  |   for (i = 0; i < order; i++) { | 
1168  | 0  |     if (bitsPerCoeff == 3)  | 
1169  | 0  |       index[i] = FDKaacEnc_Search3(parcor[i]);  | 
1170  | 0  |     else  | 
1171  | 0  |       index[i] = FDKaacEnc_Search4(parcor[i]);  | 
1172  | 0  |   }  | 
1173  | 0  | }  | 
1174  |  |  | 
1175  |  | /*****************************************************************************  | 
1176  |  |  | 
1177  |  |     functionname: FDKaacEnc_Index2Parcor  | 
1178  |  |     description:  inverse quantization for reflection coefficients  | 
1179  |  |     returns:      -  | 
1180  |  |     input:        quantized values, ptr. to reflection coefficients,  | 
1181  |  |                   no. of coefficients, resolution  | 
1182  |  |     output:       reflection coefficients  | 
1183  |  |  | 
1184  |  | *****************************************************************************/  | 
1185  |  | static void FDKaacEnc_Index2Parcor(const INT *index, FIXP_LPC *RESTRICT parcor,  | 
1186  | 0  |                                    const INT order, const INT bitsPerCoeff) { | 
1187  | 0  |   INT i;  | 
1188  | 0  |   for (i = 0; i < order; i++)  | 
1189  | 0  |     parcor[i] = bitsPerCoeff == 4 ? FDKaacEnc_tnsEncCoeff4[index[i] + 8]  | 
1190  | 0  |                                   : FDKaacEnc_tnsEncCoeff3[index[i] + 4];  | 
1191  | 0  | }  |