• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4 
5 � Copyright  1995 - 2012 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-4 AAC Decoder  **************************
85 
86    Author(s):   Josef Hoepfl
87    Description: independent channel concealment
88 
89 ******************************************************************************/
90 
91 /*!
92   \page concealment AAC core concealment
93 
94   This AAC core implementation includes a concealment function, which can be enabled
95   using the several defines during compilation.
96 
97   There are various tests inside the core, starting with simple CRC tests and ending in
98   a variety of plausibility checks. If such a check indicates an invalid bitstream, then
99   concealment is applied.
100 
101   Concealment is also applied when the calling main program indicates a distorted or missing
102   data frame using the frameOK flag. This is used for error detection on the transport layer.
103   (See below)
104 
105   There are three concealment-modes:
106 
107   1) Muting: The spectral data is simply set to zero in case of an detected error.
108 
109   2) Noise substitution: In case of an detected error, concealment copies the last frame and adds
110      attenuates the spectral data. For this mode you have to set the #CONCEAL_NOISE define.
111      Noise substitution adds no additional delay.
112 
113   3) Interpolation: The interpolation routine swaps the spectral data from the previous and the
114      current frame just before the final frequency to time conversion. In case a single frame is
115      corrupted, concealmant interpolates between the last good and the first good frame to create
116      the spectral data for the missing frame. If multiple frames are corrupted, concealment
117      implements first a fade out based on slightly modified spectral values from the last good
118      frame. As soon as good frames are available, concealmant fades in the new spectral data.
119      For this mode you have to set the #CONCEAL_INTER define. Note that in this case, you also
120      need to set #SBR_BS_DELAY_ENABLE, which basically adds approriate delay in the SBR decoder.
121      Note that the Interpolating-Concealment increases the delay of your decoder by one frame
122      and that it does require additional resources such as memory and computational complexity.
123 
124   <h2>How concealment can be used with errors on the transport layer</h2>
125 
126   Many errors can or have to be detected on the transport layer. For example in IP based systems
127   packet loss can occur. The transport protocol used should indicate such packet loss by inserting
128   an empty frame with frameOK=0.
129 */
130 
131 #include "conceal.h"
132 
133 #include "aac_rom.h"
134 #include "genericStds.h"
135 
136 
137 /* PNS (of block) */
138 #include "aacdec_pns.h"
139 #include "block.h"
140 
141 #include "FDK_tools_rom.h"
142 
143 #define CONCEAL_DFLT_COMF_NOISE_LEVEL     ( 46 )  /* ~= -70 dB */
144 
145 
146 /* default settings */
147 #define CONCEAL_DFLT_FADEOUT_FRAMES       ( 5 )
148 #define CONCEAL_DFLT_FADEIN_FRAMES        ( 5 )
149 #define CONCEAL_DFLT_MUTE_RELEASE_FRAMES  ( 3 )
150 
151 #define CONCEAL_DFLT_FADE_FACTOR          ( 0.707106781186548f )   /* 1/sqrt(2) */
152 
153 /* some often used constants: */
154 #define FIXP_ZERO           FL2FXCONST_DBL(0.0f)
155 #define FIXP_ONE            FL2FXCONST_DBL(1.0f)
156 #define FIXP_FL_CORRECTION  FL2FXCONST_DBL(0.53333333333333333f)
157 
158 /* For parameter conversion */
159 #define CONCEAL_PARAMETER_BITS              ( 8 )
160 #define CONCEAL_MAX_QUANT_FACTOR            ( (1<<CONCEAL_PARAMETER_BITS)-1 )
161 /*#define CONCEAL_MIN_ATTENUATION_FACTOR_025  ( FL2FXCONST_DBL(0.971627951577106174) )*/  /* -0.25 dB */
162 #define CONCEAL_MIN_ATTENUATION_FACTOR_025_LD  FL2FXCONST_DBL(-0.041524101186092029596853445212299)
163 /*#define CONCEAL_MIN_ATTENUATION_FACTOR_050  ( FL2FXCONST_DBL(0.944060876285923380) )*/  /* -0.50 dB */
164 #define CONCEAL_MIN_ATTENUATION_FACTOR_050_LD FL2FXCONST_DBL(-0.083048202372184059253597008145293)
165 
166 typedef enum {
167   CConcealment_NoExpand,
168   CConcealment_Expand,
169   CConcealment_Compress
170 }
171 CConcealmentExpandType;
172 
173 static const FIXP_SGL facMod4Table[4] = {
174   FL2FXCONST_SGL(0.500000000f),   /* FIXP_SGL(0x4000),  2^-(1-0,00) */
175   FL2FXCONST_SGL(0.594603558f),   /* FIXP_SGL(0x4c1b),  2^-(1-0,25) */
176   FL2FXCONST_SGL(0.707106781f),   /* FIXP_SGL(0x5a82),  2^-(1-0,50) */
177   FL2FXCONST_SGL(0.840896415f)    /* FIXP_SGL(0x6ba2)   2^-(1-0,75) */
178 };
179 
180 
181 
182 
183 static void
184   CConcealment_CalcBandEnergy (
185     FIXP_DBL               *spectrum,
186     const SamplingRateInfo *pSamplingRateInfo,
187     const int               blockType,
188     CConcealmentExpandType  ex,
189     int                    *sfbEnergy
190   );
191 
192 static void
193   CConcealment_InterpolateBuffer (
194     FIXP_DBL    *spectrum,
195     SHORT       *pSpecScalePrev,
196     SHORT       *pSpecScaleAct,
197     SHORT       *pSpecScaleOut,
198     int         *enPrv,
199     int         *enAct,
200     int          sfbCnt,
201     const SHORT *pSfbOffset
202   );
203 
204 static int
205   CConcealment_ApplyInter (
206     CConcealmentInfo       *pConcealmentInfo,
207     CAacDecoderChannelInfo *pAacDecoderChannelInfo,
208     const SamplingRateInfo *pSamplingRateInfo,
209     const int  samplesPerFrame,
210     const int  improveTonal,
211     const int  frameOk
212   );
213 
214 
215 
216 static int
217   CConcealment_ApplyNoise (
218     CConcealmentInfo *pConcealmentInfo,
219     CAacDecoderChannelInfo *pAacDecoderChannelInfo,
220     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
221     const SamplingRateInfo *pSamplingRateInfo,
222     const int    samplesPerFrame,
223     const UINT flags
224   );
225 
226 static void
227   CConcealment_UpdateState (
228     CConcealmentInfo *pConcealmentInfo,
229     int frameOk
230   );
231 
232 static void
233   CConcealment_ApplyRandomSign (
234     int        iRandomPhase,
235     FIXP_DBL  *spec,
236     int        samplesPerFrame
237   );
238 
239 
CConcealment_GetWinSeq(int prevWinSeq)240 static int CConcealment_GetWinSeq(int prevWinSeq)
241 {
242   int newWinSeq = OnlyLongSequence;
243 
244   /* Try to have only long blocks */
245   if ( prevWinSeq == LongStartSequence
246     || prevWinSeq == EightShortSequence )
247   {
248     newWinSeq = LongStopSequence;
249   }
250 
251   return (newWinSeq);
252 }
253 
254 
255 /*!
256   \brief Init common concealment information data
257 
258   \pConcealCommonData Pointer to the concealment common data structure.
259 
260   \return  none
261 */
262 void
CConcealment_InitCommonData(CConcealParams * pConcealCommonData)263   CConcealment_InitCommonData (CConcealParams *pConcealCommonData)
264 {
265   if (pConcealCommonData != NULL)
266   {
267     int i;
268 
269     /* Set default error concealment technique */
270     pConcealCommonData->method = ConcealMethodInter;
271 
272     pConcealCommonData->numFadeOutFrames     = CONCEAL_DFLT_FADEOUT_FRAMES;
273     pConcealCommonData->numFadeInFrames      = CONCEAL_DFLT_FADEIN_FRAMES;
274     pConcealCommonData->numMuteReleaseFrames = CONCEAL_DFLT_MUTE_RELEASE_FRAMES;
275 
276     pConcealCommonData->comfortNoiseLevel    = CONCEAL_DFLT_COMF_NOISE_LEVEL;
277 
278     /* Init fade factors (symetric) */
279     pConcealCommonData->fadeOutFactor[0] = FL2FXCONST_SGL( CONCEAL_DFLT_FADE_FACTOR );
280     pConcealCommonData->fadeInFactor[0]  = pConcealCommonData->fadeOutFactor[0];
281 
282     for (i = 1; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
283       pConcealCommonData->fadeOutFactor[i] = FX_DBL2FX_SGL(fMult(pConcealCommonData->fadeOutFactor[i-1],FL2FXCONST_SGL(CONCEAL_DFLT_FADE_FACTOR)));
284       pConcealCommonData->fadeInFactor[i]  = pConcealCommonData->fadeOutFactor[i];
285     }
286   }
287 }
288 
289 
290 
291 /*!
292   \brief Get current concealment method.
293 
294   \pConcealCommonData Pointer to common concealment data (for all channels)
295 
296   \return Concealment method.
297 */
298 CConcealmentMethod
CConcealment_GetMethod(CConcealParams * pConcealCommonData)299   CConcealment_GetMethod( CConcealParams *pConcealCommonData )
300 {
301   CConcealmentMethod method = ConcealMethodNone;
302 
303   if (pConcealCommonData != NULL) {
304     method = pConcealCommonData->method;
305   }
306 
307   return (method);
308 }
309 
310 
311 /*!
312   \brief Init concealment information for each channel
313 
314   The function initializes the concealment information. Two methods can be chosen:
315              0 = interpolation method (adds delay)
316              1 = noise substitution (no delay, low complexity)
317 
318   \return  none
319 */
320 void
CConcealment_InitChannelData(CConcealmentInfo * pConcealChannelInfo,CConcealParams * pConcealCommonData,int samplesPerFrame)321   CConcealment_InitChannelData (
322     CConcealmentInfo *pConcealChannelInfo,
323     CConcealParams   *pConcealCommonData,
324     int samplesPerFrame )
325 {
326   int i;
327 
328   pConcealChannelInfo->pConcealParams = pConcealCommonData;
329 
330   FDKmemclear(pConcealChannelInfo->spectralCoefficient, 1024 * sizeof(FIXP_CNCL));
331 
332   for (i = 0; i < 8; i++) {
333     pConcealChannelInfo->specScale[i] = 0;
334   }
335 
336   pConcealChannelInfo->iRandomPhase   = 0;
337 
338   pConcealChannelInfo->windowSequence = 0;
339   pConcealChannelInfo->windowShape    = 0;
340 
341   pConcealChannelInfo->prevFrameOk[0] = 1;
342   pConcealChannelInfo->prevFrameOk[1] = 1;
343 
344   pConcealChannelInfo->cntFadeFrames  = 0;
345   pConcealChannelInfo->cntValidFrames = 0;
346 
347   pConcealChannelInfo->concealState   = ConcealState_Ok;
348 
349 }
350 
351 
352 /*!
353   \brief Set error concealment parameters
354 
355   \concealParams
356   \method
357   \fadeOutSlope
358   \fadeInSlope
359   \muteRelease
360   \comfNoiseLevel
361 
362   \return  none
363 */
364 AAC_DECODER_ERROR
CConcealment_SetParams(CConcealParams * concealParams,int method,int fadeOutSlope,int fadeInSlope,int muteRelease,int comfNoiseLevel)365   CConcealment_SetParams (
366     CConcealParams *concealParams,
367     int  method,
368     int  fadeOutSlope,
369     int  fadeInSlope,
370     int  muteRelease,
371     int  comfNoiseLevel )
372 {
373   /* set concealment technique */
374   if (method != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
375     switch ((CConcealmentMethod)method)
376     {
377     case ConcealMethodMute:
378     case ConcealMethodNoise:
379     case ConcealMethodInter:
380       /* Be sure to enable delay adjustment of SBR decoder! */
381       if (concealParams == NULL) {
382         return AAC_DEC_INVALID_HANDLE;
383       } else {
384         /* set param */
385         concealParams->method = (CConcealmentMethod)method;
386       }
387       break;
388 
389     default:
390       return AAC_DEC_SET_PARAM_FAIL;
391     }
392   }
393 
394   /* set number of frames for fade-out slope */
395   if (fadeOutSlope != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
396     if ( (fadeOutSlope < CONCEAL_MAX_NUM_FADE_FACTORS)
397       && (fadeOutSlope >= 0) )
398     {
399       if (concealParams == NULL) {
400         return AAC_DEC_INVALID_HANDLE;
401       } else {
402         /* set param */
403         concealParams->numFadeOutFrames = fadeOutSlope;
404       }
405     } else {
406       return AAC_DEC_SET_PARAM_FAIL;
407     }
408   }
409 
410   /* set number of frames for fade-in slope */
411   if (fadeInSlope != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
412     if ( (fadeInSlope < CONCEAL_MAX_NUM_FADE_FACTORS)
413       && (fadeInSlope >= 1) )
414     {
415       if (concealParams == NULL) {
416         return AAC_DEC_INVALID_HANDLE;
417       } else {
418         /* set param */
419         concealParams->numFadeInFrames = fadeInSlope;
420       }
421     } else {
422       return AAC_DEC_SET_PARAM_FAIL;
423     }
424   }
425 
426   /* set number of error-free frames after which the muting will be released */
427   if (muteRelease != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
428     if ( (muteRelease < (CONCEAL_MAX_NUM_FADE_FACTORS<<1))
429       && (muteRelease >= 0) )
430     {
431       if (concealParams == NULL) {
432         return AAC_DEC_INVALID_HANDLE;
433       } else {
434         /* set param */
435         concealParams->numMuteReleaseFrames = muteRelease;
436       }
437     } else {
438       return AAC_DEC_SET_PARAM_FAIL;
439     }
440   }
441 
442   /* set confort noise level which will be inserted while in state 'muting' */
443   if (comfNoiseLevel != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
444     if ( (comfNoiseLevel < 0)
445       || (comfNoiseLevel > 127) ) {
446       return AAC_DEC_SET_PARAM_FAIL;
447     }
448     if (concealParams == NULL) {
449       return AAC_DEC_INVALID_HANDLE;
450     } else {
451       concealParams->comfortNoiseLevel = comfNoiseLevel;
452     }
453   }
454 
455   return (AAC_DEC_OK);
456 }
457 
458 
459 /*!
460   \brief Set fade-out/in attenuation factor vectors
461 
462   \concealParams
463   \fadeOutAttenuationVector
464   \fadeInAttenuationVector
465 
466   \return 0 if OK all other values indicate errors
467 */
468 AAC_DECODER_ERROR
CConcealment_SetAttenuation(CConcealParams * concealParams,SHORT * fadeOutAttenuationVector,SHORT * fadeInAttenuationVector)469   CConcealment_SetAttenuation (
470     CConcealParams *concealParams,
471     SHORT *fadeOutAttenuationVector,
472     SHORT *fadeInAttenuationVector )
473 {
474   if ( (fadeOutAttenuationVector == NULL)
475     && (fadeInAttenuationVector  == NULL) ) {
476     return AAC_DEC_SET_PARAM_FAIL;
477   }
478 
479   /* Fade-out factors */
480   if (fadeOutAttenuationVector != NULL)
481   {
482     int i;
483 
484     /* check quantized factors first */
485     for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
486       if ((fadeOutAttenuationVector[i] < 0) || (fadeOutAttenuationVector[i] > CONCEAL_MAX_QUANT_FACTOR)) {
487         return AAC_DEC_SET_PARAM_FAIL;
488       }
489     }
490     if (concealParams == NULL) {
491       return AAC_DEC_INVALID_HANDLE;
492     }
493 
494     /* now dequantize factors */
495     for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++)
496     {
497       concealParams->fadeOutFactor[i] =
498         FX_DBL2FX_SGL( fLdPow(    CONCEAL_MIN_ATTENUATION_FACTOR_025_LD,
499                                   0,
500                                   (FIXP_DBL)((INT)(FL2FXCONST_DBL(1.0/2.0)>>(CONCEAL_PARAMETER_BITS-1)) * (INT)fadeOutAttenuationVector[i]),
501                                   CONCEAL_PARAMETER_BITS
502                                   )
503                      );
504     }
505   }
506 
507   /* Fade-in factors */
508   if (fadeInAttenuationVector != NULL)
509   {
510     int i;
511 
512     /* check quantized factors first */
513     for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
514       if ((fadeInAttenuationVector[i] < 0) || (fadeInAttenuationVector[i] > CONCEAL_MAX_QUANT_FACTOR)) {
515         return AAC_DEC_SET_PARAM_FAIL;
516       }
517     }
518     if (concealParams == NULL) {
519       return AAC_DEC_INVALID_HANDLE;
520     }
521 
522     /* now dequantize factors */
523     for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++)
524     {
525       concealParams->fadeInFactor[i] =
526         FX_DBL2FX_SGL( fLdPow( CONCEAL_MIN_ATTENUATION_FACTOR_025_LD,
527                                0,
528                              (FIXP_DBL)((INT)(FIXP_ONE>>CONCEAL_PARAMETER_BITS) * (INT)fadeInAttenuationVector[i]),
529                              CONCEAL_PARAMETER_BITS
530                              )
531                      );
532     }
533   }
534 
535   return (AAC_DEC_OK);
536 }
537 
538 
539 /*!
540   \brief Get state of concealment module.
541 
542   \pConcealChannelInfo
543 
544   \return Concealment state.
545 */
546 CConcealmentState
CConcealment_GetState(CConcealmentInfo * pConcealChannelInfo)547   CConcealment_GetState (
548     CConcealmentInfo *pConcealChannelInfo
549   )
550 {
551   CConcealmentState state = ConcealState_Ok;
552 
553   if (pConcealChannelInfo != NULL) {
554     state = pConcealChannelInfo->concealState;
555   }
556 
557   return (state);
558 }
559 
560 
CConcealment_fakePnsData(CPnsData * pPnsData,CIcsInfo * pIcsInfo,const SamplingRateInfo * pSamplingRateInfo,SHORT * pSpecScale,SHORT * pScaleFactor,const int level)561 static void CConcealment_fakePnsData (
562    CPnsData *pPnsData,
563    CIcsInfo *pIcsInfo,
564    const SamplingRateInfo *pSamplingRateInfo,
565    SHORT *pSpecScale,
566    SHORT *pScaleFactor,
567    const int level )
568 {
569   CPnsInterChannelData *pInterChannelData = pPnsData->pPnsInterChannelData;
570 
571   int  pnsBand, band, group, win;
572   //int  delta = 0;
573   int  windowsPerFrame = GetWindowsPerFrame(pIcsInfo);
574   int  refLevel = (windowsPerFrame > 1) ? 82 : 91;
575 
576   FDK_ASSERT(level >= 0 && level <= 127);
577 
578   for (win = 0; win < windowsPerFrame; win++) {
579     pSpecScale[win] = 31;
580   }
581 
582   /* fake ICS info if necessary */
583   if (!IsValid(pIcsInfo)) {
584     pIcsInfo->WindowGroups = 1;
585     if (IsLongBlock(pIcsInfo)) {
586       pIcsInfo->TotalSfBands = pSamplingRateInfo->NumberOfScaleFactorBands_Long;
587       pIcsInfo->WindowGroupLength[0] = 1;
588     }
589     else {
590       pIcsInfo->TotalSfBands = pSamplingRateInfo->NumberOfScaleFactorBands_Short;
591       pIcsInfo->WindowGroupLength[0] = 8;
592     }
593     pIcsInfo->MaxSfBands = pIcsInfo->TotalSfBands;
594   }
595 
596   /* global activate PNS */
597   pPnsData->PnsActive = 1;
598   /* set energy level */
599   pPnsData->CurrentEnergy = fixMax( 0, refLevel - level );
600 
601   /*
602     value: | Avg. RMS power | Avg. RMS power |
603            | specScale = 22 | specScale = 31 |
604     -------+----------------+----------------+
605         5  |                |  -99.0 dB
606        15  |                |  -90.0 dB
607        25  |                |  -89.7 dB
608        35  |                |  -85.3 dB
609       ...  |    ...         |   ...
610        45  |  -69.9 dB      |  -70.0 dB
611        50  |  -62.2 dB      |
612        55  |  -55.6 dB      |  -54.6 dB
613        60  |  -47.0 dB      |
614        65  |  -39.5 dB      |  -39.5 dB
615        70  |  -31.9 dB      |
616        75  |  -24.4 dB      |  -24.4 dB
617        80  |  -16.9 dB      |
618        85  |   -9.4 dB (c)  |   -9.4 dB
619        90  |   -3.9 dB (c)  |
620        95  |                |   -2.1 dB
621       100  |                |   -1.6 dB
622       105  |                |   -1.4 dB
623   */
624 
625   for (group=0; group < GetWindowGroups(pIcsInfo); group++)
626   {
627     for (band=0; band < GetScaleFactorBandsTransmitted(pIcsInfo); band++)
628     {
629       pnsBand = group * 16 + band;
630 
631       if (pnsBand >= NO_OFBANDS) {
632         return;
633       }
634       //pPnsData->CurrentEnergy += delta ;
635       pScaleFactor[pnsBand] = pPnsData->CurrentEnergy;
636       pInterChannelData->correlated[pnsBand] = 0;
637       pPnsData->pnsUsed[pnsBand] = 1;
638     }
639   }
640 }
641 
642 
643 /*!
644   \brief Store data for concealment techniques applied later
645 
646   Interface function to store data for different concealment strategies
647 
648    \return  none
649  */
650 void
CConcealment_Store(CConcealmentInfo * hConcealmentInfo,CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo)651   CConcealment_Store (
652     CConcealmentInfo *hConcealmentInfo,
653     CAacDecoderChannelInfo *pAacDecoderChannelInfo,
654     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo )
655 {
656   if ( !(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD
657       ) )
658   {
659     FIXP_DBL *pSpectralCoefficient =  SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
660     SHORT    *pSpecScale           =  pAacDecoderChannelInfo->specScale;
661     CIcsInfo *pIcsInfo             = &pAacDecoderChannelInfo->icsInfo;
662 
663     SHORT  tSpecScale[8];
664     UCHAR  tWindowShape, tWindowSequence;
665 
666     /* store old window infos for swapping */
667     tWindowSequence = hConcealmentInfo->windowSequence;
668     tWindowShape    = hConcealmentInfo->windowShape;
669 
670     /* store old scale factors for swapping */
671     FDKmemcpy(tSpecScale, hConcealmentInfo->specScale, 8*sizeof(SHORT));
672 
673     /* store new window infos */
674     hConcealmentInfo->windowSequence = GetWindowSequence(pIcsInfo);
675     hConcealmentInfo->windowShape    = GetWindowShape(pIcsInfo);
676     hConcealmentInfo->lastWinGrpLen  = *(GetWindowGroupLengthTable(pIcsInfo)+GetWindowGroups(pIcsInfo)-1);
677 
678     /* store new scale factors */
679     FDKmemcpy(hConcealmentInfo->specScale, pSpecScale, 8*sizeof(SHORT));
680 
681     if (CConcealment_GetDelay(hConcealmentInfo->pConcealParams) == 0)
682     {
683       /* store new spectral bins */
684 #if (CNCL_FRACT_BITS == DFRACT_BITS)
685       FDKmemcpy(hConcealmentInfo->spectralCoefficient, pSpectralCoefficient, 1024 * sizeof(FIXP_CNCL));
686 #else
687       FIXP_CNCL *RESTRICT pCncl = &hConcealmentInfo->spectralCoefficient[1024-1];
688       FIXP_DBL  *RESTRICT pSpec = &pSpectralCoefficient[1024-1];
689       int i;
690 
691       for (i = 1024; i != 0; i--) {
692         *pCncl-- = FX_DBL2FX_CNCL(*pSpec--);
693       }
694 #endif
695     }
696     else
697     {
698       FIXP_CNCL *RESTRICT pCncl = &hConcealmentInfo->spectralCoefficient[1024-1];
699       FIXP_DBL  *RESTRICT pSpec = &pSpectralCoefficient[1024-1];
700       int i;
701 
702       /* swap spectral data */
703       for (i = 1024; i != 0; i--) {
704         FIXP_DBL tSpec = *pSpec;
705         *pSpec-- = FX_CNCL2FX_DBL(*pCncl);
706         *pCncl-- = FX_DBL2FX_CNCL( tSpec);
707       }
708 
709       /* complete swapping of window infos */
710       pIcsInfo->WindowSequence = tWindowSequence;
711       pIcsInfo->WindowShape    = tWindowShape;
712 
713       /* complete swapping of scale factors */
714       FDKmemcpy(pSpecScale, tSpecScale, 8*sizeof(SHORT));
715     }
716   }
717 
718 }
719 
720 
721 /*!
722   \brief Apply concealment
723 
724   Interface function to different concealment strategies
725 
726    \return  none
727  */
728 int
CConcealment_Apply(CConcealmentInfo * hConcealmentInfo,CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,const SamplingRateInfo * pSamplingRateInfo,const int samplesPerFrame,const UCHAR lastLpdMode,const int frameOk,const UINT flags)729   CConcealment_Apply (
730     CConcealmentInfo *hConcealmentInfo,
731     CAacDecoderChannelInfo *pAacDecoderChannelInfo,
732     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
733     const SamplingRateInfo *pSamplingRateInfo,
734     const int samplesPerFrame,
735     const UCHAR lastLpdMode,
736     const int frameOk,
737     const UINT flags)
738 {
739   int appliedProcessing = 0;
740 
741   if ( (frameOk == 0)
742     && (pAacDecoderChannelInfo->renderMode != (AACDEC_RENDER_MODE)hConcealmentInfo->lastRenderMode) ) {
743     /* restore the last render mode to stay in the same domain which allows to do a proper concealment */
744     pAacDecoderChannelInfo->renderMode = (AACDEC_RENDER_MODE)hConcealmentInfo->lastRenderMode;
745   } else {
746     /* otherwise store the current mode */
747     hConcealmentInfo->lastRenderMode = (SCHAR)pAacDecoderChannelInfo->renderMode;
748   }
749 
750   if ( frameOk )
751   {
752     /* Rescue current data for concealment in future frames */
753     CConcealment_Store ( hConcealmentInfo,
754                          pAacDecoderChannelInfo,
755                          pAacDecoderStaticChannelInfo );
756     /* Reset index to random sign vector to make sign calculation frame agnostic
757        (only depends on number of subsequently concealed spectral blocks) */
758         hConcealmentInfo->iRandomPhase = 0;
759   }
760 
761   /* hand current frame status to the state machine */
762   CConcealment_UpdateState( hConcealmentInfo,
763                             frameOk );
764 
765   if ( !frameOk )
766   {
767     /* Create data for signal rendering according to the selected concealment method and decoder operating mode. */
768 
769 
770     if ( !(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD
771         )
772         )
773     {
774       switch (hConcealmentInfo->pConcealParams->method)
775       {
776       default:
777       case ConcealMethodMute:
778         /* Mute spectral data in case of errors */
779         FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL));
780         /* Set last window shape */
781         pAacDecoderChannelInfo->icsInfo.WindowShape = hConcealmentInfo->windowShape;
782         appliedProcessing = 1;
783         break;
784 
785       case ConcealMethodNoise:
786         /* Noise substitution error concealment technique */
787         appliedProcessing =
788           CConcealment_ApplyNoise (hConcealmentInfo,
789                                    pAacDecoderChannelInfo,
790                                    pAacDecoderStaticChannelInfo,
791                                    pSamplingRateInfo,
792                                    samplesPerFrame,
793                                    flags);
794         break;
795 
796       case ConcealMethodInter:
797         /* Energy interpolation concealment based on 3GPP */
798         appliedProcessing =
799           CConcealment_ApplyInter (hConcealmentInfo,
800                                    pAacDecoderChannelInfo,
801                                    pSamplingRateInfo,
802                                    samplesPerFrame,
803                                    0,  /* don't use tonal improvement */
804                                    0);
805         break;
806 
807       }
808     }
809   }
810   /* update history */
811   hConcealmentInfo->prevFrameOk[0] = hConcealmentInfo->prevFrameOk[1];
812   hConcealmentInfo->prevFrameOk[1] = frameOk;
813 
814   return appliedProcessing;
815 }
816 
817 /*!
818 \brief Apply concealment noise substitution
819 
820   In case of frame lost this function produces a noisy frame with respect to the
821   energies values of past frame.
822 
823 \return  none
824  */
825 static int
CConcealment_ApplyNoise(CConcealmentInfo * pConcealmentInfo,CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,const SamplingRateInfo * pSamplingRateInfo,const int samplesPerFrame,const UINT flags)826   CConcealment_ApplyNoise (CConcealmentInfo *pConcealmentInfo,
827                            CAacDecoderChannelInfo *pAacDecoderChannelInfo,
828                            CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
829                            const SamplingRateInfo *pSamplingRateInfo,
830                            const int samplesPerFrame,
831                            const UINT flags)
832 {
833   CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams;
834 
835   FIXP_DBL *pSpectralCoefficient =  SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
836   SHORT    *pSpecScale           =  pAacDecoderChannelInfo->specScale;
837   CIcsInfo *pIcsInfo             = &pAacDecoderChannelInfo->icsInfo;
838 
839   int appliedProcessing = 0;
840 
841   FDK_ASSERT((samplesPerFrame>=480) && (samplesPerFrame<=1024));
842   FDK_ASSERT((samplesPerFrame&0x1F) == 0);
843 
844   switch (pConcealmentInfo->concealState)
845   {
846   case ConcealState_Ok:
847     /* Nothing to do here! */
848     break;
849 
850   case ConcealState_Single:
851   case ConcealState_FadeOut:
852     {
853       /* restore frequency coefficients from buffer with a specific muting */
854       FIXP_SGL  fac;
855       int win, numWindows = 1;
856       int windowLen = samplesPerFrame;
857       int tFadeFrames, lastWindow = 0;
858       int win_idx_stride = 1;
859 
860       FDK_ASSERT(pConcealmentInfo != NULL);
861       FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0);
862       FDK_ASSERT(pConcealmentInfo->cntFadeFrames < CONCEAL_MAX_NUM_FADE_FACTORS);
863       FDK_ASSERT(pConcealmentInfo->cntFadeFrames <= pConcealCommonData->numFadeOutFrames);
864 
865       /* get attenuation factor */
866       tFadeFrames = pConcealmentInfo->cntFadeFrames;
867       fac = pConcealCommonData->fadeOutFactor[tFadeFrames];
868 
869       /* set old window parameters */
870       {
871         pIcsInfo->WindowShape    = pConcealmentInfo->windowShape;
872         pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence;
873 
874         if (pConcealmentInfo->windowSequence == 2) {
875           /* short block handling */
876           numWindows = 8;
877           windowLen  = samplesPerFrame >> 3;
878           lastWindow = numWindows - pConcealmentInfo->lastWinGrpLen;
879         }
880       }
881 
882       for (win = 0; win < numWindows; win++) {
883         FIXP_CNCL *pCncl = pConcealmentInfo->spectralCoefficient + (lastWindow * windowLen);
884         FIXP_DBL  *pOut  = pSpectralCoefficient + (win * windowLen);
885         int i;
886 
887         FDK_ASSERT((lastWindow * windowLen + windowLen) <= samplesPerFrame);
888 
889         /* restore frequency coefficients from buffer with a specific attenuation */
890         for (i = 0; i < windowLen; i++) {
891           pOut[i] = fMult(pCncl[i], fac);
892         }
893 
894         /* apply random change of sign for spectral coefficients */
895         CConcealment_ApplyRandomSign(pConcealmentInfo->iRandomPhase,
896                                             pOut,
897                                             windowLen );
898 
899         /* Increment random phase index to avoid repetition artifacts. */
900         pConcealmentInfo->iRandomPhase = (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);
901 
902         /* set old scale factors */
903         pSpecScale[win*win_idx_stride] = pConcealmentInfo->specScale[win_idx_stride*lastWindow++];
904 
905         if ( (lastWindow >= numWindows)
906           && (numWindows >  1) )
907         {
908           /* end of sequence -> rewind */
909           lastWindow = numWindows - pConcealmentInfo->lastWinGrpLen;
910           /* update the attenuation factor to get a faster fade-out */
911           tFadeFrames += 1;
912           if (tFadeFrames < pConcealCommonData->numFadeOutFrames) {
913             fac = pConcealCommonData->fadeOutFactor[tFadeFrames];
914           } else {
915             fac = (FIXP_SGL)0;
916           }
917         }
918       }
919 
920       /* store temp vars */
921       pConcealmentInfo->cntFadeFrames = tFadeFrames;
922       appliedProcessing = 1;
923     }
924     break;
925 
926   case ConcealState_Mute:
927     {
928       /* set dummy window parameters */
929       pIcsInfo->Valid          = 0;                                /* Trigger the generation of a consitent IcsInfo */
930       pIcsInfo->WindowShape    = pConcealmentInfo->windowShape;    /* Prevent an invalid WindowShape (required for F/T transform) */
931       pIcsInfo->WindowSequence = CConcealment_GetWinSeq(pConcealmentInfo->windowSequence);
932       pConcealmentInfo->windowSequence = pIcsInfo->WindowSequence; /* Store for next frame (spectrum in concealment buffer can't be used at all) */
933 
934       /* mute spectral data */
935       FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL));
936 
937       if ( !(flags & (AC_USAC|AC_RSVD50))
938            && pConcealCommonData->comfortNoiseLevel >= 0
939            && pConcealCommonData->comfortNoiseLevel <= 61 /* -90dB */)
940         {
941         /* insert comfort noise using PNS */
942         CConcealment_fakePnsData (
943          &pAacDecoderChannelInfo->data.aac.PnsData,
944           pIcsInfo,
945           pSamplingRateInfo,
946           pAacDecoderChannelInfo->pDynData->aSfbScale,
947           pAacDecoderChannelInfo->pDynData->aScaleFactor,
948           pConcealCommonData->comfortNoiseLevel
949         );
950 
951         CPns_Apply (
952                &pAacDecoderChannelInfo->data.aac.PnsData,
953                 pIcsInfo,
954                 pAacDecoderChannelInfo->pSpectralCoefficient,
955                 pAacDecoderChannelInfo->specScale,
956                 pAacDecoderChannelInfo->pDynData->aScaleFactor,
957                 pSamplingRateInfo,
958                 pAacDecoderChannelInfo->granuleLength,
959                 0  /* always apply to first channel */
960               );
961       }
962       appliedProcessing = 1;
963     }
964     break;
965 
966   case ConcealState_FadeIn:
967     {
968       FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0);
969       FDK_ASSERT(pConcealmentInfo->cntFadeFrames < CONCEAL_MAX_NUM_FADE_FACTORS);
970       FDK_ASSERT(pConcealmentInfo->cntFadeFrames < pConcealCommonData->numFadeInFrames);
971 
972       /* attenuate signal to get a smooth fade-in */
973       FIXP_DBL *RESTRICT pOut = &pSpectralCoefficient[samplesPerFrame-1];
974       FIXP_SGL fac = pConcealCommonData->fadeInFactor[pConcealmentInfo->cntFadeFrames];
975       int i;
976 
977       for (i = samplesPerFrame; i != 0; i--) {
978         *pOut = fMult(*pOut, fac);
979         pOut--;
980       }
981       appliedProcessing = 1;
982     }
983     break;
984 
985   default:
986     /* we shouldn't come here anyway */
987     FDK_ASSERT(0);
988     break;
989   }
990 
991   return appliedProcessing;
992 }
993 
994 
995 /*!
996   \brief Apply concealment interpolation
997 
998   The function swaps the data from the current and the previous frame. If an
999   error has occured, frame interpolation is performed to restore the missing
1000   frame. In case of multiple faulty frames, fade-in and fade-out is applied.
1001 
1002   \return  none
1003 */
1004 static int
CConcealment_ApplyInter(CConcealmentInfo * pConcealmentInfo,CAacDecoderChannelInfo * pAacDecoderChannelInfo,const SamplingRateInfo * pSamplingRateInfo,const int samplesPerFrame,const int improveTonal,const int frameOk)1005   CConcealment_ApplyInter (
1006     CConcealmentInfo       *pConcealmentInfo,
1007     CAacDecoderChannelInfo *pAacDecoderChannelInfo,
1008     const SamplingRateInfo *pSamplingRateInfo,
1009     const int  samplesPerFrame,
1010     const int  improveTonal,
1011     const int  frameOk )
1012 {
1013   CConcealParams   *pConcealCommonData    =  pConcealmentInfo->pConcealParams;
1014 
1015   FIXP_DBL         *pSpectralCoefficient  =  SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
1016   CIcsInfo         *pIcsInfo              = &pAacDecoderChannelInfo->icsInfo;
1017   SHORT            *pSpecScale            =  pAacDecoderChannelInfo->specScale;
1018 
1019 
1020   int sfbEnergyPrev[64];
1021   int sfbEnergyAct [64];
1022 
1023   int i, appliedProcessing = 0;
1024 
1025   /* clear/init */
1026   FDKmemclear(sfbEnergyPrev, 64 * sizeof(int));
1027   FDKmemclear(sfbEnergyAct,  64 * sizeof(int));
1028 
1029 
1030   if (!frameOk)
1031   {
1032     /* Restore last frame from concealment buffer */
1033     pIcsInfo->WindowShape    = pConcealmentInfo->windowShape;
1034     pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence;
1035 
1036     /* Restore spectral data */
1037     for (i = 0; i < samplesPerFrame; i++) {
1038       pSpectralCoefficient[i] = FX_CNCL2FX_DBL(pConcealmentInfo->spectralCoefficient[i]);
1039     }
1040 
1041     /* Restore scale factors */
1042     FDKmemcpy(pSpecScale, pConcealmentInfo->specScale, 8*sizeof(SHORT));
1043   }
1044 
1045   /* if previous frame was not ok */
1046   if (!pConcealmentInfo->prevFrameOk[1]) {
1047 
1048     /* if current frame (f_n) is ok and the last but one frame (f_(n-2))
1049        was ok, too, then interpolate both frames in order to generate
1050        the current output frame (f_(n-1)). Otherwise, use the last stored
1051        frame (f_(n-2) or f_(n-3) or ...). */
1052     if (frameOk && pConcealmentInfo->prevFrameOk[0])
1053     {
1054       appliedProcessing = 1;
1055 
1056 
1057       /* Interpolate both frames in order to generate the current output frame (f_(n-1)). */
1058       if (pIcsInfo->WindowSequence == EightShortSequence) {
1059         /* f_(n-2) == EightShortSequence */
1060         /* short--??????--short, short--??????--long interpolation */
1061         /* short--short---short, short---long---long interpolation */
1062 
1063         int wnd;
1064 
1065         if (pConcealmentInfo->windowSequence == EightShortSequence) { /* f_n == EightShortSequence */
1066           /* short--short---short interpolation */
1067 
1068           int scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Short;
1069           const SHORT *pSfbOffset   = pSamplingRateInfo->ScaleFactorBands_Short;
1070           pIcsInfo->WindowShape = 1;
1071           pIcsInfo->WindowSequence = EightShortSequence;
1072 
1073           for (wnd = 0; wnd < 8; wnd++)
1074           {
1075             CConcealment_CalcBandEnergy(
1076               &pSpectralCoefficient[wnd * (samplesPerFrame / 8)], /* spec_(n-2) */
1077                pSamplingRateInfo,
1078                EightShortSequence,
1079                CConcealment_NoExpand,
1080                sfbEnergyPrev);
1081 
1082             CConcealment_CalcBandEnergy(
1083               &pConcealmentInfo->spectralCoefficient[wnd * (samplesPerFrame / 8)], /* spec_n */
1084                pSamplingRateInfo,
1085                EightShortSequence,
1086                CConcealment_NoExpand,
1087                sfbEnergyAct);
1088 
1089             CConcealment_InterpolateBuffer(
1090               &pSpectralCoefficient[wnd * (samplesPerFrame / 8)], /* spec_(n-1) */
1091               &pSpecScale[wnd],
1092               &pConcealmentInfo->specScale[wnd],
1093               &pSpecScale[wnd],
1094                sfbEnergyPrev,
1095                sfbEnergyAct,
1096                scaleFactorBandsTotal,
1097                pSfbOffset);
1098 
1099           }
1100         } else { /* f_n != EightShortSequence */
1101           /* short---long---long interpolation */
1102 
1103           int scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Long;
1104           const SHORT *pSfbOffset   = pSamplingRateInfo->ScaleFactorBands_Long;
1105           SHORT specScaleOut;
1106 
1107           CConcealment_CalcBandEnergy(&pSpectralCoefficient[samplesPerFrame - (samplesPerFrame / 8)], /* [wnd] spec_(n-2) */
1108                                       pSamplingRateInfo,
1109                                       EightShortSequence,
1110                                       CConcealment_Expand,
1111                                       sfbEnergyAct);
1112 
1113           CConcealment_CalcBandEnergy(pConcealmentInfo->spectralCoefficient, /* spec_n */
1114                                       pSamplingRateInfo,
1115                                       OnlyLongSequence,
1116                                       CConcealment_NoExpand,
1117                                       sfbEnergyPrev);
1118 
1119           pIcsInfo->WindowShape = 0;
1120           pIcsInfo->WindowSequence = LongStopSequence;
1121 
1122           for (i = 0; i < samplesPerFrame ; i++) {
1123             pSpectralCoefficient[i] = pConcealmentInfo->spectralCoefficient[i]; /* spec_n */
1124           }
1125 
1126           for (i = 0; i < 8; i++) { /* search for max(specScale) */
1127             if (pSpecScale[i] > pSpecScale[0]) {
1128               pSpecScale[0] = pSpecScale[i];
1129             }
1130           }
1131 
1132           CConcealment_InterpolateBuffer(
1133             pSpectralCoefficient, /* spec_(n-1) */
1134            &pConcealmentInfo->specScale[0],
1135            &pSpecScale[0],
1136            &specScaleOut,
1137             sfbEnergyPrev,
1138             sfbEnergyAct,
1139             scaleFactorBandsTotal,
1140             pSfbOffset);
1141 
1142           pSpecScale[0] = specScaleOut;
1143         }
1144       } else {
1145         /* long--??????--short, long--??????--long interpolation */
1146         /* long---long---short, long---long---long interpolation */
1147 
1148         int scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Long;
1149         const SHORT *pSfbOffset   = pSamplingRateInfo->ScaleFactorBands_Long;
1150         SHORT specScaleAct        = pConcealmentInfo->specScale[0];
1151 
1152         CConcealment_CalcBandEnergy(pSpectralCoefficient,  /* spec_(n-2) */
1153                                     pSamplingRateInfo,
1154                                     OnlyLongSequence,
1155                                     CConcealment_NoExpand,
1156                                     sfbEnergyPrev);
1157 
1158         if (pConcealmentInfo->windowSequence == EightShortSequence) {  /* f_n == EightShortSequence */
1159           /* long---long---short interpolation */
1160 
1161           pIcsInfo->WindowShape = 1;
1162           pIcsInfo->WindowSequence = LongStartSequence;
1163 
1164           for (i = 1; i < 8; i++) { /* search for max(specScale) */
1165             if (pConcealmentInfo->specScale[i] > specScaleAct) {
1166               specScaleAct = pConcealmentInfo->specScale[i];
1167             }
1168           }
1169 
1170           /* Expand first short spectrum */
1171           CConcealment_CalcBandEnergy(pConcealmentInfo->spectralCoefficient,  /* spec_n */
1172                                       pSamplingRateInfo,
1173                                       EightShortSequence,
1174                                       CConcealment_Expand,  /* !!! */
1175                                       sfbEnergyAct);
1176         } else {
1177           /* long---long---long interpolation */
1178 
1179           pIcsInfo->WindowShape = 0;
1180           pIcsInfo->WindowSequence = OnlyLongSequence;
1181 
1182           CConcealment_CalcBandEnergy(pConcealmentInfo->spectralCoefficient,  /* spec_n */
1183                                       pSamplingRateInfo,
1184                                       OnlyLongSequence,
1185                                       CConcealment_NoExpand,
1186                                       sfbEnergyAct);
1187         }
1188 
1189           CConcealment_InterpolateBuffer(
1190             pSpectralCoefficient,  /* spec_(n-1) */
1191            &pSpecScale[0],
1192            &specScaleAct,
1193            &pSpecScale[0],
1194             sfbEnergyPrev,
1195             sfbEnergyAct,
1196             scaleFactorBandsTotal,
1197             pSfbOffset);
1198 
1199       }
1200     }
1201 
1202       /* Noise substitution of sign of the output spectral coefficients */
1203       CConcealment_ApplyRandomSign (pConcealmentInfo->iRandomPhase,
1204                                     pSpectralCoefficient,
1205                                     samplesPerFrame);
1206       /* Increment random phase index to avoid repetition artifacts. */
1207       pConcealmentInfo->iRandomPhase = (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);
1208   }
1209 
1210   /* scale spectrum according to concealment state */
1211   switch (pConcealmentInfo->concealState)
1212   {
1213   case ConcealState_Single:
1214     appliedProcessing = 1;
1215     break;
1216 
1217   case ConcealState_FadeOut:
1218     {
1219       FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0);
1220       FDK_ASSERT(pConcealmentInfo->cntFadeFrames < CONCEAL_MAX_NUM_FADE_FACTORS);
1221       FDK_ASSERT(pConcealmentInfo->cntFadeFrames < pConcealCommonData->numFadeOutFrames);
1222 
1223       /* restore frequency coefficients from buffer with a specific muting */
1224       FIXP_DBL *RESTRICT pOut = &pSpectralCoefficient[samplesPerFrame-1];
1225       FIXP_SGL fac = pConcealCommonData->fadeOutFactor[pConcealmentInfo->cntFadeFrames];
1226 
1227       for (i = samplesPerFrame; i != 0; i--) {
1228         *pOut = fMult(*pOut, fac);
1229         pOut--;
1230       }
1231       appliedProcessing = 1;
1232     }
1233     break;
1234 
1235   case ConcealState_FadeIn:
1236     {
1237       FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0);
1238       FDK_ASSERT(pConcealmentInfo->cntFadeFrames < CONCEAL_MAX_NUM_FADE_FACTORS);
1239       FDK_ASSERT(pConcealmentInfo->cntFadeFrames < pConcealCommonData->numFadeInFrames);
1240 
1241       /* attenuate signal to get a smooth fade-in */
1242       FIXP_DBL *RESTRICT pOut = &pSpectralCoefficient[samplesPerFrame-1];
1243       FIXP_SGL fac = pConcealCommonData->fadeInFactor[pConcealmentInfo->cntFadeFrames];
1244 
1245       for (i = samplesPerFrame; i != 0; i--) {
1246         *pOut = fMult(*pOut, fac);
1247         pOut--;
1248       }
1249       appliedProcessing = 1;
1250     }
1251     break;
1252 
1253   case ConcealState_Mute:
1254     {
1255       int fac = pConcealCommonData->comfortNoiseLevel;
1256 
1257       /* set dummy window parameters */
1258       pIcsInfo->Valid          = 0;                                /* Trigger the generation of a consitent IcsInfo */
1259       pIcsInfo->WindowShape    = pConcealmentInfo->windowShape;    /* Prevent an invalid WindowShape (required for F/T transform) */
1260       pIcsInfo->WindowSequence = CConcealment_GetWinSeq(pConcealmentInfo->windowSequence);
1261       pConcealmentInfo->windowSequence = pIcsInfo->WindowSequence; /* Store for next frame (spectrum in concealment buffer can't be used at all) */
1262 
1263       /* mute spectral data */
1264       FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL));
1265 
1266       if (fac >= 0 && fac <= 61) {
1267         /* insert comfort noise using PNS */
1268         CConcealment_fakePnsData (
1269          &pAacDecoderChannelInfo->data.aac.PnsData,
1270           pIcsInfo,
1271           pSamplingRateInfo,
1272           pAacDecoderChannelInfo->specScale,
1273           pAacDecoderChannelInfo->pDynData->aScaleFactor,
1274           fac
1275         );
1276 
1277         CPns_Apply (
1278                &pAacDecoderChannelInfo->data.aac.PnsData,
1279                 pIcsInfo,
1280                 pAacDecoderChannelInfo->pSpectralCoefficient,
1281                 pAacDecoderChannelInfo->specScale,
1282                 pAacDecoderChannelInfo->pDynData->aScaleFactor,
1283                 pSamplingRateInfo,
1284                 pAacDecoderChannelInfo->granuleLength,
1285                 0  /* always apply to first channel */
1286               );
1287       }
1288       appliedProcessing = 1;
1289     }
1290     break;
1291 
1292   default:
1293     /* nothing to do here */
1294     break;
1295   }
1296 
1297   return appliedProcessing;
1298 }
1299 
1300 
1301 /*!
1302   \brief Calculate the spectral energy
1303 
1304   The function calculates band-wise the spectral energy. This is used for
1305   frame interpolation.
1306 
1307   \return  none
1308 */
1309 static void
CConcealment_CalcBandEnergy(FIXP_DBL * spectrum,const SamplingRateInfo * pSamplingRateInfo,const int blockType,CConcealmentExpandType expandType,int * sfbEnergy)1310   CConcealment_CalcBandEnergy (
1311     FIXP_DBL               *spectrum,
1312     const SamplingRateInfo *pSamplingRateInfo,
1313     const int               blockType,
1314     CConcealmentExpandType  expandType,
1315     int                    *sfbEnergy )
1316 {
1317   const SHORT *pSfbOffset;
1318   int line, sfb, scaleFactorBandsTotal = 0;
1319 
1320   /* In the following calculations, enAccu is initialized with LSB-value in order to avoid zero energy-level */
1321 
1322   line = 0;
1323 
1324   switch(blockType) {
1325 
1326   case OnlyLongSequence:
1327   case LongStartSequence:
1328   case LongStopSequence:
1329 
1330     if (expandType == CConcealment_NoExpand) {
1331       /* standard long calculation */
1332       scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Long;
1333       pSfbOffset            = pSamplingRateInfo->ScaleFactorBands_Long;
1334 
1335       for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
1336         FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
1337         int sfbScale = (sizeof(LONG)<<3) - CntLeadingZeros(pSfbOffset[sfb+1] - pSfbOffset[sfb]) - 1;
1338         /* scaling depends on sfb width. */
1339         for ( ; line < pSfbOffset[sfb+1]; line++) {
1340           enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale;
1341         }
1342         *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
1343       }
1344     }
1345     else {
1346       /* compress long to short */
1347       scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Short;
1348       pSfbOffset            = pSamplingRateInfo->ScaleFactorBands_Short;
1349 
1350       for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
1351         FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
1352         int sfbScale = (sizeof(LONG)<<3) - CntLeadingZeros(pSfbOffset[sfb+1] - pSfbOffset[sfb]) - 1;
1353         /* scaling depends on sfb width. */
1354         for (; line < pSfbOffset[sfb+1] << 3; line++) {
1355           enAccu += (enAccu + (fPow2Div2(*(spectrum + line)) >> sfbScale)) >> 3;
1356         }
1357         *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
1358       }
1359     }
1360     break;
1361 
1362   case EightShortSequence:
1363 
1364     if (expandType == CConcealment_NoExpand) {
1365       /*   standard short calculation */
1366       scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Short;
1367       pSfbOffset            = pSamplingRateInfo->ScaleFactorBands_Short;
1368 
1369       for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
1370         FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
1371         int sfbScale = (sizeof(LONG)<<3) - CntLeadingZeros(pSfbOffset[sfb+1] - pSfbOffset[sfb]) - 1;
1372         /* scaling depends on sfb width. */
1373         for ( ; line < pSfbOffset[sfb+1]; line++) {
1374           enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale;
1375         }
1376         *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
1377       }
1378     }
1379     else {
1380       /*  expand short to long spectrum */
1381       scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Long;
1382       pSfbOffset            = pSamplingRateInfo->ScaleFactorBands_Long;
1383 
1384       for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
1385         FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
1386         int sfbScale = (sizeof(LONG)<<3) - CntLeadingZeros(pSfbOffset[sfb+1] - pSfbOffset[sfb]) - 1;
1387         /* scaling depends on sfb width. */
1388         for ( ; line < pSfbOffset[sfb+1]; line++) {
1389           enAccu += fPow2Div2(*(spectrum + (line >> 3))) >> sfbScale;
1390         }
1391         *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
1392       }
1393     }
1394     break;
1395   }
1396 }
1397 
1398 
1399 /*!
1400   \brief Interpolate buffer
1401 
1402   The function creates the interpolated spectral data according to the
1403   energy of the last good frame and the current (good) frame.
1404 
1405   \return  none
1406 */
1407 static void
CConcealment_InterpolateBuffer(FIXP_DBL * spectrum,SHORT * pSpecScalePrv,SHORT * pSpecScaleAct,SHORT * pSpecScaleOut,int * enPrv,int * enAct,int sfbCnt,const SHORT * pSfbOffset)1408   CConcealment_InterpolateBuffer (
1409     FIXP_DBL    *spectrum,
1410     SHORT       *pSpecScalePrv,
1411     SHORT       *pSpecScaleAct,
1412     SHORT       *pSpecScaleOut,
1413     int         *enPrv,
1414     int         *enAct,
1415     int          sfbCnt,
1416     const SHORT *pSfbOffset )
1417 {
1418   int    sfb, line = 0;
1419   int    fac_shift;
1420   int    fac_mod;
1421   FIXP_DBL accu;
1422 
1423   for (sfb = 0; sfb < sfbCnt; sfb++) {
1424 
1425     fac_shift = enPrv[sfb] - enAct[sfb] + ((*pSpecScaleAct - *pSpecScalePrv) << 1);
1426     fac_mod   = fac_shift & 3;
1427     fac_shift = (fac_shift >> 2) + 1;
1428     fac_shift += *pSpecScalePrv - fixMax(*pSpecScalePrv, *pSpecScaleAct);
1429 
1430     for (; line < pSfbOffset[sfb+1]; line++) {
1431       accu = fMult(*(spectrum+line), facMod4Table[fac_mod]);
1432       if (fac_shift < 0) {
1433         accu >>= -fac_shift;
1434       } else {
1435         accu <<= fac_shift;
1436       }
1437       *(spectrum+line) = accu;
1438     }
1439   }
1440   *pSpecScaleOut = fixMax(*pSpecScalePrv, *pSpecScaleAct);
1441 }
1442 
1443 
1444 
1445 
findEquiFadeFrame(CConcealParams * pConcealCommonData,INT actFadeIndex,int direction)1446 static INT findEquiFadeFrame (
1447     CConcealParams *pConcealCommonData,
1448     INT actFadeIndex,
1449     int direction )
1450 {
1451   FIXP_SGL *pFactor;
1452   FIXP_SGL  referenceVal;
1453   FIXP_SGL  minDiff = (FIXP_SGL)MAXVAL_SGL;
1454 
1455   INT  numFrames = 0;
1456   INT  nextFadeIndex = 0;
1457 
1458   int  i;
1459 
1460   /* init depending on direction */
1461   if (direction == 0) {  /* FADE-OUT => FADE-IN */
1462     numFrames = pConcealCommonData->numFadeInFrames;
1463     referenceVal = pConcealCommonData->fadeOutFactor[actFadeIndex] >> 1;
1464     pFactor = pConcealCommonData->fadeInFactor;
1465   }
1466   else {  /* FADE-IN => FADE-OUT */
1467     numFrames = pConcealCommonData->numFadeOutFrames;
1468     referenceVal = pConcealCommonData->fadeInFactor[actFadeIndex] >> 1;
1469     pFactor = pConcealCommonData->fadeOutFactor;
1470   }
1471 
1472   /* search for minimum difference */
1473   for (i = 0; i < numFrames; i++) {
1474     FIXP_SGL diff = fixp_abs((pFactor[i]>>1) - referenceVal);
1475     if (diff < minDiff) {
1476       minDiff = diff;
1477       nextFadeIndex = i;
1478     }
1479   }
1480 
1481   /* check and adjust depending on direction */
1482   if (direction == 0) {  /* FADE-OUT => FADE-IN */
1483     if (((pFactor[nextFadeIndex]>>1) <= referenceVal) && (nextFadeIndex > 0)) {
1484       nextFadeIndex -= 1;
1485     }
1486   }
1487   else {  /* FADE-IN => FADE-OUT */
1488     if (((pFactor[nextFadeIndex]>>1) >= referenceVal) && (nextFadeIndex < numFrames-1)) {
1489       nextFadeIndex += 1;
1490     }
1491   }
1492 
1493   return (nextFadeIndex);
1494 }
1495 
1496 
1497 /*!
1498   \brief Update the concealment state
1499 
1500   The function updates the state of the concealment state-machine. The
1501   states are: mute, fade-in, fade-out, interpolate and frame-ok.
1502 
1503   \return  none
1504 */
1505 static void
CConcealment_UpdateState(CConcealmentInfo * pConcealmentInfo,int frameOk)1506   CConcealment_UpdateState (
1507     CConcealmentInfo *pConcealmentInfo,
1508     int frameOk )
1509 {
1510   CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams;
1511 
1512   switch (pConcealCommonData->method)
1513   {
1514   case ConcealMethodNoise:
1515     {
1516       if (pConcealmentInfo->concealState != ConcealState_Ok) {
1517         /* count the valid frames during concealment process */
1518         if (frameOk) {
1519           pConcealmentInfo->cntValidFrames += 1;
1520         } else {
1521           pConcealmentInfo->cntValidFrames  = 0;
1522         }
1523       }
1524 
1525       /* -- STATE MACHINE for Noise Substitution -- */
1526       switch (pConcealmentInfo->concealState)
1527       {
1528       case ConcealState_Ok:
1529         if (!frameOk) {
1530           /* change to state SINGLE-FRAME-LOSS */
1531           pConcealmentInfo->concealState   = ConcealState_Single;
1532           pConcealmentInfo->cntFadeFrames  = 0;
1533           pConcealmentInfo->cntValidFrames = 0;
1534         }
1535         break;
1536 
1537       case ConcealState_Single:  /* Just a pre-stage before fade-out begins. Stay here only one frame! */
1538         pConcealmentInfo->cntFadeFrames += 1;
1539         if (frameOk) {
1540           if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) {
1541             /* change to state FADE-IN */
1542             pConcealmentInfo->concealState  = ConcealState_FadeIn;
1543             pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData,
1544                                                                  pConcealmentInfo->cntFadeFrames-1,
1545                                                                  0 /* FadeOut -> FadeIn */);
1546           } else {
1547             /* change to state OK */
1548             pConcealmentInfo->concealState = ConcealState_Ok;
1549           }
1550         } else {
1551           if (pConcealmentInfo->cntFadeFrames >= pConcealCommonData->numFadeOutFrames) {
1552             /* change to state MUTE */
1553             pConcealmentInfo->concealState = ConcealState_Mute;
1554           } else {
1555             /* change to state FADE-OUT */
1556             pConcealmentInfo->concealState = ConcealState_FadeOut;
1557           }
1558         }
1559         break;
1560 
1561       case ConcealState_FadeOut:
1562         pConcealmentInfo->cntFadeFrames += 1;  /* used to address the fade-out factors */
1563         if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) {
1564           /* change to state FADE-IN */
1565           pConcealmentInfo->concealState  = ConcealState_FadeIn;
1566           pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData,
1567                                                                pConcealmentInfo->cntFadeFrames-1,
1568                                                                0 /* FadeOut -> FadeIn */);
1569         } else {
1570           if (pConcealmentInfo->cntFadeFrames >= pConcealCommonData->numFadeOutFrames) {
1571             /* change to state MUTE */
1572             pConcealmentInfo->concealState = ConcealState_Mute;
1573           }
1574         }
1575         break;
1576 
1577       case ConcealState_Mute:
1578         if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) {
1579           /* change to state FADE-IN */
1580           pConcealmentInfo->concealState = ConcealState_FadeIn;
1581           pConcealmentInfo->cntFadeFrames = pConcealCommonData->numFadeInFrames - 1;
1582         }
1583         break;
1584 
1585       case ConcealState_FadeIn:
1586         pConcealmentInfo->cntFadeFrames -= 1;  /* used to address the fade-in factors */
1587         if (frameOk) {
1588           if (pConcealmentInfo->cntFadeFrames < 0) {
1589             /* change to state OK */
1590             pConcealmentInfo->concealState = ConcealState_Ok;
1591           }
1592         } else {
1593           /* change to state FADE-OUT */
1594           pConcealmentInfo->concealState  = ConcealState_FadeOut;
1595           pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData,
1596                                                                pConcealmentInfo->cntFadeFrames+1,
1597                                                                1 /* FadeIn -> FadeOut */);
1598         }
1599         break;
1600 
1601       default:
1602         FDK_ASSERT(0);
1603         break;
1604       }
1605     }
1606     break;
1607 
1608   case ConcealMethodInter:
1609   case ConcealMethodTonal:
1610     {
1611       if (pConcealmentInfo->concealState != ConcealState_Ok) {
1612         /* count the valid frames during concealment process */
1613         if ( pConcealmentInfo->prevFrameOk[1] ||
1614             (pConcealmentInfo->prevFrameOk[0] && !pConcealmentInfo->prevFrameOk[1] && frameOk) ) {
1615           /* The frame is OK even if it can be estimated by the energy interpolation algorithm */
1616           pConcealmentInfo->cntValidFrames += 1;
1617         } else {
1618           pConcealmentInfo->cntValidFrames  = 0;
1619         }
1620       }
1621 
1622       /* -- STATE MACHINE for energy interpolation -- */
1623       switch (pConcealmentInfo->concealState)
1624       {
1625       case ConcealState_Ok:
1626         if (!(pConcealmentInfo->prevFrameOk[1] ||
1627              (pConcealmentInfo->prevFrameOk[0] && !pConcealmentInfo->prevFrameOk[1] && frameOk))) {
1628           /* Fade out only if the energy interpolation algorithm can not be applied! */
1629           pConcealmentInfo->concealState   = ConcealState_FadeOut;
1630           pConcealmentInfo->cntFadeFrames  = 0;
1631           pConcealmentInfo->cntValidFrames = 0;
1632         }
1633         break;
1634 
1635       case ConcealState_Single:
1636         pConcealmentInfo->concealState = ConcealState_Ok;
1637         break;
1638 
1639       case ConcealState_FadeOut:
1640         pConcealmentInfo->cntFadeFrames += 1;
1641 
1642         if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) {
1643           /* change to state FADE-IN */
1644           pConcealmentInfo->concealState  = ConcealState_FadeIn;
1645           pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData,
1646                                                                pConcealmentInfo->cntFadeFrames-1,
1647                                                                0 /* FadeOut -> FadeIn */);
1648         } else {
1649           if (pConcealmentInfo->cntFadeFrames >= pConcealCommonData->numFadeOutFrames) {
1650             /* change to state MUTE */
1651             pConcealmentInfo->concealState = ConcealState_Mute;
1652           }
1653         }
1654         break;
1655 
1656       case ConcealState_Mute:
1657         if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) {
1658           /* change to state FADE-IN */
1659           pConcealmentInfo->concealState = ConcealState_FadeIn;
1660           pConcealmentInfo->cntFadeFrames = pConcealCommonData->numFadeInFrames - 1;
1661         }
1662         break;
1663 
1664       case ConcealState_FadeIn:
1665         pConcealmentInfo->cntFadeFrames -= 1;  /* used to address the fade-in factors */
1666 
1667         if (frameOk || pConcealmentInfo->prevFrameOk[1]) {
1668           if (pConcealmentInfo->cntFadeFrames < 0) {
1669             /* change to state OK */
1670             pConcealmentInfo->concealState = ConcealState_Ok;
1671           }
1672         } else {
1673           /* change to state FADE-OUT */
1674           pConcealmentInfo->concealState  = ConcealState_FadeOut;
1675           pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData,
1676                                                                pConcealmentInfo->cntFadeFrames+1,
1677                                                                1 /* FadeIn -> FadeOut */);
1678         }
1679         break;
1680       } /* End switch(pConcealmentInfo->concealState) */
1681     }
1682     break;
1683 
1684   default:
1685     /* Don't need a state machine for other concealment methods. */
1686     break;
1687   }
1688 
1689 }
1690 
1691 
1692 /*!
1693 \brief Randomizes the sign of the spectral data
1694 
1695   The function toggles the sign of the spectral data randomly. This is
1696   useful to ensure the quality of the concealed frames.
1697 
1698 \return  none
1699  */
1700 static
CConcealment_ApplyRandomSign(int randomPhase,FIXP_DBL * spec,int samplesPerFrame)1701 void CConcealment_ApplyRandomSign (int randomPhase,
1702                                    FIXP_DBL *spec,
1703                                    int samplesPerFrame
1704                                                )
1705 {
1706   int i;
1707   USHORT packedSign=0;
1708 
1709   /* random table 512x16bit has been reduced to 512 packed sign bits = 32x16 bit */
1710 
1711   /* read current packed sign word */
1712   packedSign = randomSign[randomPhase>>4];
1713   packedSign >>= (randomPhase&0xf);
1714 
1715   for (i = 0; i < samplesPerFrame ; i++) {
1716     if ((randomPhase & 0xf) == 0) {
1717       packedSign = randomSign[randomPhase>>4];
1718     }
1719 
1720     if (packedSign & 0x1) {
1721       spec[i] = -spec[i];
1722     }
1723     packedSign >>= 1;
1724 
1725     randomPhase = (randomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);
1726   }
1727 }
1728 
1729 
1730 /*!
1731   \brief Get fadeing factor for current concealment state.
1732 
1733   The function returns the factor used for fading that belongs to the current internal state.
1734 
1735   \return Fade factor
1736  */
1737 FIXP_DBL
CConcealment_GetFadeFactor(CConcealmentInfo * hConcealmentInfo,const int fPreviousFactor)1738   CConcealment_GetFadeFactor (
1739       CConcealmentInfo *hConcealmentInfo,
1740       const int fPreviousFactor
1741   )
1742 {
1743   FIXP_DBL fac = (FIXP_DBL)0;
1744 
1745   CConcealParams *pConcealCommonData = hConcealmentInfo->pConcealParams;
1746 
1747   if (hConcealmentInfo->pConcealParams->method > ConcealMethodMute) {
1748     switch (hConcealmentInfo->concealState) {
1749       default:
1750       case ConcealState_Mute:
1751         /* Nothing to do here */
1752         break;
1753       case ConcealState_Ok:
1754         fac = (FIXP_DBL)MAXVAL_DBL;
1755         break;
1756       case ConcealState_Single:
1757       case ConcealState_FadeOut:
1758         {
1759           int idx = hConcealmentInfo->cntFadeFrames - ((fPreviousFactor != 0) ? 1 : 0);
1760           fac = (idx < 0) ? (FIXP_DBL)MAXVAL_DBL : FX_SGL2FX_DBL(pConcealCommonData->fadeOutFactor[idx]);
1761         }
1762         break;
1763       case ConcealState_FadeIn:
1764         {
1765           int idx = hConcealmentInfo->cntFadeFrames + ((fPreviousFactor != 0) ? 1 : 0);
1766           fac = (idx >= hConcealmentInfo->pConcealParams->numFadeInFrames) ? (FIXP_DBL)0 : FX_SGL2FX_DBL(pConcealCommonData->fadeInFactor[idx]);
1767         }
1768         break;
1769     }
1770   }
1771 
1772   return (fac);
1773 }
1774 
1775 
1776 /*!
1777   \brief Get fadeing factor for current concealment state.
1778 
1779   The function returns the state (ok or not) of the previous frame.
1780   If called before the function CConcealment_Apply() set the fBeforeApply
1781   flag to get the correct value.
1782 
1783   \return Frame OK flag of previous frame.
1784  */
1785 int
CConcealment_GetLastFrameOk(CConcealmentInfo * hConcealmentInfo,const int fBeforeApply)1786   CConcealment_GetLastFrameOk (
1787       CConcealmentInfo *hConcealmentInfo,
1788       const int fBeforeApply
1789   )
1790 {
1791   int prevFrameOk = 1;
1792 
1793   if (hConcealmentInfo != NULL) {
1794     prevFrameOk = hConcealmentInfo->prevFrameOk[fBeforeApply & 0x1];
1795   }
1796 
1797   return prevFrameOk;
1798 }
1799 
1800 /*!
1801   \brief Get the number of delay frames introduced by concealment technique.
1802 
1803   \return Number of delay frames.
1804  */
1805 UINT
CConcealment_GetDelay(CConcealParams * pConcealCommonData)1806   CConcealment_GetDelay (
1807       CConcealParams *pConcealCommonData
1808   )
1809 {
1810   UINT frameDelay = 0;
1811 
1812   if (pConcealCommonData != NULL) {
1813     switch (pConcealCommonData->method) {
1814     case ConcealMethodTonal:
1815     case ConcealMethodInter:
1816       frameDelay = 1;
1817       break;
1818     default:
1819       break;
1820     }
1821   }
1822 
1823   return frameDelay;
1824 }
1825 
1826