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