1 
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4 
5 � Copyright  1995 - 2013 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 < -1)
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   {
766     /* Create data for signal rendering according to the selected concealment method and decoder operating mode. */
767 
768 
769     if ( !(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD
770         )
771         )
772     {
773       switch (hConcealmentInfo->pConcealParams->method)
774       {
775       default:
776       case ConcealMethodMute:
777         if (!frameOk) {
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         }
784         break;
785 
786       case ConcealMethodNoise:
787         /* Noise substitution error concealment technique */
788         appliedProcessing =
789           CConcealment_ApplyNoise (hConcealmentInfo,
790                                    pAacDecoderChannelInfo,
791                                    pAacDecoderStaticChannelInfo,
792                                    pSamplingRateInfo,
793                                    samplesPerFrame,
794                                    flags);
795         break;
796 
797       case ConcealMethodInter:
798         /* Energy interpolation concealment based on 3GPP */
799         appliedProcessing =
800           CConcealment_ApplyInter (hConcealmentInfo,
801                                    pAacDecoderChannelInfo,
802                                    pSamplingRateInfo,
803                                    samplesPerFrame,
804                                    0,  /* don't use tonal improvement */
805                                    frameOk);
806         break;
807 
808       }
809     }
810   }
811   /* update history */
812   hConcealmentInfo->prevFrameOk[0] = hConcealmentInfo->prevFrameOk[1];
813   hConcealmentInfo->prevFrameOk[1] = frameOk;
814 
815   return appliedProcessing;
816 }
817 
818 /*!
819 \brief Apply concealment noise substitution
820 
821   In case of frame lost this function produces a noisy frame with respect to the
822   energies values of past frame.
823 
824 \return  none
825  */
826 static int
CConcealment_ApplyNoise(CConcealmentInfo * pConcealmentInfo,CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,const SamplingRateInfo * pSamplingRateInfo,const int samplesPerFrame,const UINT flags)827   CConcealment_ApplyNoise (CConcealmentInfo *pConcealmentInfo,
828                            CAacDecoderChannelInfo *pAacDecoderChannelInfo,
829                            CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
830                            const SamplingRateInfo *pSamplingRateInfo,
831                            const int samplesPerFrame,
832                            const UINT flags)
833 {
834   CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams;
835 
836   FIXP_DBL *pSpectralCoefficient =  SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
837   SHORT    *pSpecScale           =  pAacDecoderChannelInfo->specScale;
838   CIcsInfo *pIcsInfo             = &pAacDecoderChannelInfo->icsInfo;
839 
840   int appliedProcessing = 0;
841 
842   FDK_ASSERT((samplesPerFrame>=480) && (samplesPerFrame<=1024));
843   FDK_ASSERT((samplesPerFrame&0x1F) == 0);
844 
845   switch (pConcealmentInfo->concealState)
846   {
847   case ConcealState_Ok:
848     /* Nothing to do here! */
849     break;
850 
851   case ConcealState_Single:
852   case ConcealState_FadeOut:
853     {
854       /* restore frequency coefficients from buffer with a specific muting */
855       FIXP_SGL  fac;
856       int win, numWindows = 1;
857       int windowLen = samplesPerFrame;
858       int tFadeFrames, lastWindow = 0;
859       int win_idx_stride = 1;
860 
861       FDK_ASSERT(pConcealmentInfo != NULL);
862       FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0);
863       FDK_ASSERT(pConcealmentInfo->cntFadeFrames < CONCEAL_MAX_NUM_FADE_FACTORS);
864       FDK_ASSERT(pConcealmentInfo->cntFadeFrames <= pConcealCommonData->numFadeOutFrames);
865 
866       /* get attenuation factor */
867       tFadeFrames = pConcealmentInfo->cntFadeFrames;
868       fac = pConcealCommonData->fadeOutFactor[tFadeFrames];
869 
870       /* set old window parameters */
871       {
872         pIcsInfo->WindowShape    = pConcealmentInfo->windowShape;
873         pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence;
874 
875         if (pConcealmentInfo->windowSequence == 2) {
876           /* short block handling */
877           numWindows = 8;
878           windowLen  = samplesPerFrame >> 3;
879           lastWindow = numWindows - pConcealmentInfo->lastWinGrpLen;
880         }
881       }
882 
883       for (win = 0; win < numWindows; win++) {
884         FIXP_CNCL *pCncl = pConcealmentInfo->spectralCoefficient + (lastWindow * windowLen);
885         FIXP_DBL  *pOut  = pSpectralCoefficient + (win * windowLen);
886         int i;
887 
888         FDK_ASSERT((lastWindow * windowLen + windowLen) <= samplesPerFrame);
889 
890         /* restore frequency coefficients from buffer with a specific attenuation */
891         for (i = 0; i < windowLen; i++) {
892           pOut[i] = fMult(pCncl[i], fac);
893         }
894 
895         /* apply random change of sign for spectral coefficients */
896         CConcealment_ApplyRandomSign(pConcealmentInfo->iRandomPhase,
897                                             pOut,
898                                             windowLen );
899 
900         /* Increment random phase index to avoid repetition artifacts. */
901         pConcealmentInfo->iRandomPhase = (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);
902 
903         /* set old scale factors */
904         pSpecScale[win*win_idx_stride] = pConcealmentInfo->specScale[win_idx_stride*lastWindow++];
905 
906         if ( (lastWindow >= numWindows)
907           && (numWindows >  1) )
908         {
909           /* end of sequence -> rewind */
910           lastWindow = numWindows - pConcealmentInfo->lastWinGrpLen;
911           /* update the attenuation factor to get a faster fade-out */
912           tFadeFrames += 1;
913           if (tFadeFrames < pConcealCommonData->numFadeOutFrames) {
914             fac = pConcealCommonData->fadeOutFactor[tFadeFrames];
915           } else {
916             fac = (FIXP_SGL)0;
917           }
918         }
919       }
920 
921       /* store temp vars */
922       pConcealmentInfo->cntFadeFrames = tFadeFrames;
923       appliedProcessing = 1;
924     }
925     break;
926 
927   case ConcealState_Mute:
928     {
929       /* set dummy window parameters */
930       pIcsInfo->Valid          = 0;                                /* Trigger the generation of a consitent IcsInfo */
931       pIcsInfo->WindowShape    = pConcealmentInfo->windowShape;    /* Prevent an invalid WindowShape (required for F/T transform) */
932       pIcsInfo->WindowSequence = CConcealment_GetWinSeq(pConcealmentInfo->windowSequence);
933       pConcealmentInfo->windowSequence = pIcsInfo->WindowSequence; /* Store for next frame (spectrum in concealment buffer can't be used at all) */
934 
935       /* mute spectral data */
936       FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL));
937 
938       if ( !(flags & (AC_USAC|AC_RSVD50))
939            && pConcealCommonData->comfortNoiseLevel >= 0
940            && pConcealCommonData->comfortNoiseLevel <= 61 /* -90dB */)
941         {
942         /* insert comfort noise using PNS */
943         CConcealment_fakePnsData (
944          &pAacDecoderChannelInfo->data.aac.PnsData,
945           pIcsInfo,
946           pSamplingRateInfo,
947           pAacDecoderChannelInfo->pDynData->aSfbScale,
948           pAacDecoderChannelInfo->pDynData->aScaleFactor,
949           pConcealCommonData->comfortNoiseLevel
950         );
951 
952         CPns_Apply (
953                &pAacDecoderChannelInfo->data.aac.PnsData,
954                 pIcsInfo,
955                 pAacDecoderChannelInfo->pSpectralCoefficient,
956                 pAacDecoderChannelInfo->specScale,
957                 pAacDecoderChannelInfo->pDynData->aScaleFactor,
958                 pSamplingRateInfo,
959                 pAacDecoderChannelInfo->granuleLength,
960                 0  /* always apply to first channel */
961               );
962       }
963       appliedProcessing = 1;
964     }
965     break;
966 
967   case ConcealState_FadeIn:
968     {
969       FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0);
970       FDK_ASSERT(pConcealmentInfo->cntFadeFrames < CONCEAL_MAX_NUM_FADE_FACTORS);
971       FDK_ASSERT(pConcealmentInfo->cntFadeFrames < pConcealCommonData->numFadeInFrames);
972 
973       /* attenuate signal to get a smooth fade-in */
974       FIXP_DBL *RESTRICT pOut = &pSpectralCoefficient[samplesPerFrame-1];
975       FIXP_SGL fac = pConcealCommonData->fadeInFactor[pConcealmentInfo->cntFadeFrames];
976       int i;
977 
978       for (i = samplesPerFrame; i != 0; i--) {
979         *pOut = fMult(*pOut, fac);
980         pOut--;
981       }
982       appliedProcessing = 1;
983     }
984     break;
985 
986   default:
987     /* we shouldn't come here anyway */
988     FDK_ASSERT(0);
989     break;
990   }
991 
992   return appliedProcessing;
993 }
994 
995 
996 /*!
997   \brief Apply concealment interpolation
998 
999   The function swaps the data from the current and the previous frame. If an
1000   error has occured, frame interpolation is performed to restore the missing
1001   frame. In case of multiple faulty frames, fade-in and fade-out is applied.
1002 
1003   \return  none
1004 */
1005 static int
CConcealment_ApplyInter(CConcealmentInfo * pConcealmentInfo,CAacDecoderChannelInfo * pAacDecoderChannelInfo,const SamplingRateInfo * pSamplingRateInfo,const int samplesPerFrame,const int improveTonal,const int frameOk)1006   CConcealment_ApplyInter (
1007     CConcealmentInfo       *pConcealmentInfo,
1008     CAacDecoderChannelInfo *pAacDecoderChannelInfo,
1009     const SamplingRateInfo *pSamplingRateInfo,
1010     const int  samplesPerFrame,
1011     const int  improveTonal,
1012     const int  frameOk )
1013 {
1014   CConcealParams   *pConcealCommonData    =  pConcealmentInfo->pConcealParams;
1015 
1016   FIXP_DBL         *pSpectralCoefficient  =  SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
1017   CIcsInfo         *pIcsInfo              = &pAacDecoderChannelInfo->icsInfo;
1018   SHORT            *pSpecScale            =  pAacDecoderChannelInfo->specScale;
1019 
1020 
1021   int sfbEnergyPrev[64];
1022   int sfbEnergyAct [64];
1023 
1024   int i, appliedProcessing = 0;
1025 
1026   /* clear/init */
1027   FDKmemclear(sfbEnergyPrev, 64 * sizeof(int));
1028   FDKmemclear(sfbEnergyAct,  64 * sizeof(int));
1029 
1030 
1031   if (!frameOk)
1032   {
1033     /* Restore last frame from concealment buffer */
1034     pIcsInfo->WindowShape    = pConcealmentInfo->windowShape;
1035     pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence;
1036 
1037     /* Restore spectral data */
1038     for (i = 0; i < samplesPerFrame; i++) {
1039       pSpectralCoefficient[i] = FX_CNCL2FX_DBL(pConcealmentInfo->spectralCoefficient[i]);
1040     }
1041 
1042     /* Restore scale factors */
1043     FDKmemcpy(pSpecScale, pConcealmentInfo->specScale, 8*sizeof(SHORT));
1044   }
1045 
1046   /* if previous frame was not ok */
1047   if (!pConcealmentInfo->prevFrameOk[1]) {
1048 
1049     /* if current frame (f_n) is ok and the last but one frame (f_(n-2))
1050        was ok, too, then interpolate both frames in order to generate
1051        the current output frame (f_(n-1)). Otherwise, use the last stored
1052        frame (f_(n-2) or f_(n-3) or ...). */
1053     if (frameOk && pConcealmentInfo->prevFrameOk[0])
1054     {
1055       appliedProcessing = 1;
1056 
1057 
1058       /* Interpolate both frames in order to generate the current output frame (f_(n-1)). */
1059       if (pIcsInfo->WindowSequence == EightShortSequence) {
1060         /* f_(n-2) == EightShortSequence */
1061         /* short--??????--short, short--??????--long interpolation */
1062         /* short--short---short, short---long---long interpolation */
1063 
1064         int wnd;
1065 
1066         if (pConcealmentInfo->windowSequence == EightShortSequence) { /* f_n == EightShortSequence */
1067           /* short--short---short interpolation */
1068 
1069           int scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Short;
1070           const SHORT *pSfbOffset   = pSamplingRateInfo->ScaleFactorBands_Short;
1071           pIcsInfo->WindowShape = 1;
1072           pIcsInfo->WindowSequence = EightShortSequence;
1073 
1074           for (wnd = 0; wnd < 8; wnd++)
1075           {
1076             CConcealment_CalcBandEnergy(
1077               &pSpectralCoefficient[wnd * (samplesPerFrame / 8)], /* spec_(n-2) */
1078                pSamplingRateInfo,
1079                EightShortSequence,
1080                CConcealment_NoExpand,
1081                sfbEnergyPrev);
1082 
1083             CConcealment_CalcBandEnergy(
1084               &pConcealmentInfo->spectralCoefficient[wnd * (samplesPerFrame / 8)], /* spec_n */
1085                pSamplingRateInfo,
1086                EightShortSequence,
1087                CConcealment_NoExpand,
1088                sfbEnergyAct);
1089 
1090             CConcealment_InterpolateBuffer(
1091               &pSpectralCoefficient[wnd * (samplesPerFrame / 8)], /* spec_(n-1) */
1092               &pSpecScale[wnd],
1093               &pConcealmentInfo->specScale[wnd],
1094               &pSpecScale[wnd],
1095                sfbEnergyPrev,
1096                sfbEnergyAct,
1097                scaleFactorBandsTotal,
1098                pSfbOffset);
1099 
1100           }
1101         } else { /* f_n != EightShortSequence */
1102           /* short---long---long interpolation */
1103 
1104           int scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Long;
1105           const SHORT *pSfbOffset   = pSamplingRateInfo->ScaleFactorBands_Long;
1106           SHORT specScaleOut;
1107 
1108           CConcealment_CalcBandEnergy(&pSpectralCoefficient[samplesPerFrame - (samplesPerFrame / 8)], /* [wnd] spec_(n-2) */
1109                                       pSamplingRateInfo,
1110                                       EightShortSequence,
1111                                       CConcealment_Expand,
1112                                       sfbEnergyAct);
1113 
1114           CConcealment_CalcBandEnergy(pConcealmentInfo->spectralCoefficient, /* spec_n */
1115                                       pSamplingRateInfo,
1116                                       OnlyLongSequence,
1117                                       CConcealment_NoExpand,
1118                                       sfbEnergyPrev);
1119 
1120           pIcsInfo->WindowShape = 0;
1121           pIcsInfo->WindowSequence = LongStopSequence;
1122 
1123           for (i = 0; i < samplesPerFrame ; i++) {
1124             pSpectralCoefficient[i] = pConcealmentInfo->spectralCoefficient[i]; /* spec_n */
1125           }
1126 
1127           for (i = 0; i < 8; i++) { /* search for max(specScale) */
1128             if (pSpecScale[i] > pSpecScale[0]) {
1129               pSpecScale[0] = pSpecScale[i];
1130             }
1131           }
1132 
1133           CConcealment_InterpolateBuffer(
1134             pSpectralCoefficient, /* spec_(n-1) */
1135            &pConcealmentInfo->specScale[0],
1136            &pSpecScale[0],
1137            &specScaleOut,
1138             sfbEnergyPrev,
1139             sfbEnergyAct,
1140             scaleFactorBandsTotal,
1141             pSfbOffset);
1142 
1143           pSpecScale[0] = specScaleOut;
1144         }
1145       } else {
1146         /* long--??????--short, long--??????--long interpolation */
1147         /* long---long---short, long---long---long interpolation */
1148 
1149         int scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Long;
1150         const SHORT *pSfbOffset   = pSamplingRateInfo->ScaleFactorBands_Long;
1151         SHORT specScaleAct        = pConcealmentInfo->specScale[0];
1152 
1153         CConcealment_CalcBandEnergy(pSpectralCoefficient,  /* spec_(n-2) */
1154                                     pSamplingRateInfo,
1155                                     OnlyLongSequence,
1156                                     CConcealment_NoExpand,
1157                                     sfbEnergyPrev);
1158 
1159         if (pConcealmentInfo->windowSequence == EightShortSequence) {  /* f_n == EightShortSequence */
1160           /* long---long---short interpolation */
1161 
1162           pIcsInfo->WindowShape = 1;
1163           pIcsInfo->WindowSequence = LongStartSequence;
1164 
1165           for (i = 1; i < 8; i++) { /* search for max(specScale) */
1166             if (pConcealmentInfo->specScale[i] > specScaleAct) {
1167               specScaleAct = pConcealmentInfo->specScale[i];
1168             }
1169           }
1170 
1171           /* Expand first short spectrum */
1172           CConcealment_CalcBandEnergy(pConcealmentInfo->spectralCoefficient,  /* spec_n */
1173                                       pSamplingRateInfo,
1174                                       EightShortSequence,
1175                                       CConcealment_Expand,  /* !!! */
1176                                       sfbEnergyAct);
1177         } else {
1178           /* long---long---long interpolation */
1179 
1180           pIcsInfo->WindowShape = 0;
1181           pIcsInfo->WindowSequence = OnlyLongSequence;
1182 
1183           CConcealment_CalcBandEnergy(pConcealmentInfo->spectralCoefficient,  /* spec_n */
1184                                       pSamplingRateInfo,
1185                                       OnlyLongSequence,
1186                                       CConcealment_NoExpand,
1187                                       sfbEnergyAct);
1188         }
1189 
1190           CConcealment_InterpolateBuffer(
1191             pSpectralCoefficient,  /* spec_(n-1) */
1192            &pSpecScale[0],
1193            &specScaleAct,
1194            &pSpecScale[0],
1195             sfbEnergyPrev,
1196             sfbEnergyAct,
1197             scaleFactorBandsTotal,
1198             pSfbOffset);
1199 
1200       }
1201     }
1202 
1203       /* Noise substitution of sign of the output spectral coefficients */
1204       CConcealment_ApplyRandomSign (pConcealmentInfo->iRandomPhase,
1205                                     pSpectralCoefficient,
1206                                     samplesPerFrame);
1207       /* Increment random phase index to avoid repetition artifacts. */
1208       pConcealmentInfo->iRandomPhase = (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);
1209   }
1210 
1211   /* scale spectrum according to concealment state */
1212   switch (pConcealmentInfo->concealState)
1213   {
1214   case ConcealState_Single:
1215     appliedProcessing = 1;
1216     break;
1217 
1218   case ConcealState_FadeOut:
1219     {
1220       FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0);
1221       FDK_ASSERT(pConcealmentInfo->cntFadeFrames < CONCEAL_MAX_NUM_FADE_FACTORS);
1222       FDK_ASSERT(pConcealmentInfo->cntFadeFrames < pConcealCommonData->numFadeOutFrames);
1223 
1224       /* restore frequency coefficients from buffer with a specific muting */
1225       FIXP_DBL *RESTRICT pOut = &pSpectralCoefficient[samplesPerFrame-1];
1226       FIXP_SGL fac = pConcealCommonData->fadeOutFactor[pConcealmentInfo->cntFadeFrames];
1227 
1228       for (i = samplesPerFrame; i != 0; i--) {
1229         *pOut = fMult(*pOut, fac);
1230         pOut--;
1231       }
1232       appliedProcessing = 1;
1233     }
1234     break;
1235 
1236   case ConcealState_FadeIn:
1237     {
1238       FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0);
1239       FDK_ASSERT(pConcealmentInfo->cntFadeFrames < CONCEAL_MAX_NUM_FADE_FACTORS);
1240       FDK_ASSERT(pConcealmentInfo->cntFadeFrames < pConcealCommonData->numFadeInFrames);
1241 
1242       /* attenuate signal to get a smooth fade-in */
1243       FIXP_DBL *RESTRICT pOut = &pSpectralCoefficient[samplesPerFrame-1];
1244       FIXP_SGL fac = pConcealCommonData->fadeInFactor[pConcealmentInfo->cntFadeFrames];
1245 
1246       for (i = samplesPerFrame; i != 0; i--) {
1247         *pOut = fMult(*pOut, fac);
1248         pOut--;
1249       }
1250       appliedProcessing = 1;
1251     }
1252     break;
1253 
1254   case ConcealState_Mute:
1255     {
1256       int fac = pConcealCommonData->comfortNoiseLevel;
1257 
1258       /* set dummy window parameters */
1259       pIcsInfo->Valid          = 0;                                /* Trigger the generation of a consitent IcsInfo */
1260       pIcsInfo->WindowShape    = pConcealmentInfo->windowShape;    /* Prevent an invalid WindowShape (required for F/T transform) */
1261       pIcsInfo->WindowSequence = CConcealment_GetWinSeq(pConcealmentInfo->windowSequence);
1262       pConcealmentInfo->windowSequence = pIcsInfo->WindowSequence; /* Store for next frame (spectrum in concealment buffer can't be used at all) */
1263 
1264       /* mute spectral data */
1265       FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL));
1266 
1267       if (fac >= 0 && fac <= 61) {
1268         /* insert comfort noise using PNS */
1269         CConcealment_fakePnsData (
1270          &pAacDecoderChannelInfo->data.aac.PnsData,
1271           pIcsInfo,
1272           pSamplingRateInfo,
1273           pAacDecoderChannelInfo->specScale,
1274           pAacDecoderChannelInfo->pDynData->aScaleFactor,
1275           fac
1276         );
1277 
1278         CPns_Apply (
1279                &pAacDecoderChannelInfo->data.aac.PnsData,
1280                 pIcsInfo,
1281                 pAacDecoderChannelInfo->pSpectralCoefficient,
1282                 pAacDecoderChannelInfo->specScale,
1283                 pAacDecoderChannelInfo->pDynData->aScaleFactor,
1284                 pSamplingRateInfo,
1285                 pAacDecoderChannelInfo->granuleLength,
1286                 0  /* always apply to first channel */
1287               );
1288       }
1289       appliedProcessing = 1;
1290     }
1291     break;
1292 
1293   default:
1294     /* nothing to do here */
1295     break;
1296   }
1297 
1298   return appliedProcessing;
1299 }
1300 
1301 
1302 /*!
1303   \brief Calculate the spectral energy
1304 
1305   The function calculates band-wise the spectral energy. This is used for
1306   frame interpolation.
1307 
1308   \return  none
1309 */
1310 static void
CConcealment_CalcBandEnergy(FIXP_DBL * spectrum,const SamplingRateInfo * pSamplingRateInfo,const int blockType,CConcealmentExpandType expandType,int * sfbEnergy)1311   CConcealment_CalcBandEnergy (
1312     FIXP_DBL               *spectrum,
1313     const SamplingRateInfo *pSamplingRateInfo,
1314     const int               blockType,
1315     CConcealmentExpandType  expandType,
1316     int                    *sfbEnergy )
1317 {
1318   const SHORT *pSfbOffset;
1319   int line, sfb, scaleFactorBandsTotal = 0;
1320 
1321   /* In the following calculations, enAccu is initialized with LSB-value in order to avoid zero energy-level */
1322 
1323   line = 0;
1324 
1325   switch(blockType) {
1326 
1327   case OnlyLongSequence:
1328   case LongStartSequence:
1329   case LongStopSequence:
1330 
1331     if (expandType == CConcealment_NoExpand) {
1332       /* standard long calculation */
1333       scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Long;
1334       pSfbOffset            = pSamplingRateInfo->ScaleFactorBands_Long;
1335 
1336       for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
1337         FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
1338         int sfbScale = (sizeof(LONG)<<3) - CntLeadingZeros(pSfbOffset[sfb+1] - pSfbOffset[sfb]) - 1;
1339         /* scaling depends on sfb width. */
1340         for ( ; line < pSfbOffset[sfb+1]; line++) {
1341           enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale;
1342         }
1343         *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
1344       }
1345     }
1346     else {
1347       /* compress long to short */
1348       scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Short;
1349       pSfbOffset            = pSamplingRateInfo->ScaleFactorBands_Short;
1350 
1351       for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
1352         FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
1353         int sfbScale = (sizeof(LONG)<<3) - CntLeadingZeros(pSfbOffset[sfb+1] - pSfbOffset[sfb]) - 1;
1354         /* scaling depends on sfb width. */
1355         for (; line < pSfbOffset[sfb+1] << 3; line++) {
1356           enAccu += (enAccu + (fPow2Div2(*(spectrum + line)) >> sfbScale)) >> 3;
1357         }
1358         *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
1359       }
1360     }
1361     break;
1362 
1363   case EightShortSequence:
1364 
1365     if (expandType == CConcealment_NoExpand) {
1366       /*   standard short calculation */
1367       scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Short;
1368       pSfbOffset            = pSamplingRateInfo->ScaleFactorBands_Short;
1369 
1370       for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
1371         FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
1372         int sfbScale = (sizeof(LONG)<<3) - CntLeadingZeros(pSfbOffset[sfb+1] - pSfbOffset[sfb]) - 1;
1373         /* scaling depends on sfb width. */
1374         for ( ; line < pSfbOffset[sfb+1]; line++) {
1375           enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale;
1376         }
1377         *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
1378       }
1379     }
1380     else {
1381       /*  expand short to long spectrum */
1382       scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Long;
1383       pSfbOffset            = pSamplingRateInfo->ScaleFactorBands_Long;
1384 
1385       for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
1386         FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
1387         int sfbScale = (sizeof(LONG)<<3) - CntLeadingZeros(pSfbOffset[sfb+1] - pSfbOffset[sfb]) - 1;
1388         /* scaling depends on sfb width. */
1389         for ( ; line < pSfbOffset[sfb+1]; line++) {
1390           enAccu += fPow2Div2(*(spectrum + (line >> 3))) >> sfbScale;
1391         }
1392         *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
1393       }
1394     }
1395     break;
1396   }
1397 }
1398 
1399 
1400 /*!
1401   \brief Interpolate buffer
1402 
1403   The function creates the interpolated spectral data according to the
1404   energy of the last good frame and the current (good) frame.
1405 
1406   \return  none
1407 */
1408 static void
CConcealment_InterpolateBuffer(FIXP_DBL * spectrum,SHORT * pSpecScalePrv,SHORT * pSpecScaleAct,SHORT * pSpecScaleOut,int * enPrv,int * enAct,int sfbCnt,const SHORT * pSfbOffset)1409   CConcealment_InterpolateBuffer (
1410     FIXP_DBL    *spectrum,
1411     SHORT       *pSpecScalePrv,
1412     SHORT       *pSpecScaleAct,
1413     SHORT       *pSpecScaleOut,
1414     int         *enPrv,
1415     int         *enAct,
1416     int          sfbCnt,
1417     const SHORT *pSfbOffset )
1418 {
1419   int    sfb, line = 0;
1420   int    fac_shift;
1421   int    fac_mod;
1422   FIXP_DBL accu;
1423 
1424   for (sfb = 0; sfb < sfbCnt; sfb++) {
1425 
1426     fac_shift = enPrv[sfb] - enAct[sfb] + ((*pSpecScaleAct - *pSpecScalePrv) << 1);
1427     fac_mod   = fac_shift & 3;
1428     fac_shift = (fac_shift >> 2) + 1;
1429     fac_shift += *pSpecScalePrv - fixMax(*pSpecScalePrv, *pSpecScaleAct);
1430 
1431     for (; line < pSfbOffset[sfb+1]; line++) {
1432       accu = fMult(*(spectrum+line), facMod4Table[fac_mod]);
1433       if (fac_shift < 0) {
1434         accu >>= -fac_shift;
1435       } else {
1436         accu <<= fac_shift;
1437       }
1438       *(spectrum+line) = accu;
1439     }
1440   }
1441   *pSpecScaleOut = fixMax(*pSpecScalePrv, *pSpecScaleAct);
1442 }
1443 
1444 
1445 
1446 
findEquiFadeFrame(CConcealParams * pConcealCommonData,INT actFadeIndex,int direction)1447 static INT findEquiFadeFrame (
1448     CConcealParams *pConcealCommonData,
1449     INT actFadeIndex,
1450     int direction )
1451 {
1452   FIXP_SGL *pFactor;
1453   FIXP_SGL  referenceVal;
1454   FIXP_SGL  minDiff = (FIXP_SGL)MAXVAL_SGL;
1455 
1456   INT  numFrames = 0;
1457   INT  nextFadeIndex = 0;
1458 
1459   int  i;
1460 
1461   /* init depending on direction */
1462   if (direction == 0) {  /* FADE-OUT => FADE-IN */
1463     numFrames = pConcealCommonData->numFadeInFrames;
1464     referenceVal = pConcealCommonData->fadeOutFactor[actFadeIndex] >> 1;
1465     pFactor = pConcealCommonData->fadeInFactor;
1466   }
1467   else {  /* FADE-IN => FADE-OUT */
1468     numFrames = pConcealCommonData->numFadeOutFrames;
1469     referenceVal = pConcealCommonData->fadeInFactor[actFadeIndex] >> 1;
1470     pFactor = pConcealCommonData->fadeOutFactor;
1471   }
1472 
1473   /* search for minimum difference */
1474   for (i = 0; i < numFrames; i++) {
1475     FIXP_SGL diff = fixp_abs((pFactor[i]>>1) - referenceVal);
1476     if (diff < minDiff) {
1477       minDiff = diff;
1478       nextFadeIndex = i;
1479     }
1480   }
1481 
1482   /* check and adjust depending on direction */
1483   if (direction == 0) {  /* FADE-OUT => FADE-IN */
1484     if (((pFactor[nextFadeIndex]>>1) <= referenceVal) && (nextFadeIndex > 0)) {
1485       nextFadeIndex -= 1;
1486     }
1487   }
1488   else {  /* FADE-IN => FADE-OUT */
1489     if (((pFactor[nextFadeIndex]>>1) >= referenceVal) && (nextFadeIndex < numFrames-1)) {
1490       nextFadeIndex += 1;
1491     }
1492   }
1493 
1494   return (nextFadeIndex);
1495 }
1496 
1497 
1498 /*!
1499   \brief Update the concealment state
1500 
1501   The function updates the state of the concealment state-machine. The
1502   states are: mute, fade-in, fade-out, interpolate and frame-ok.
1503 
1504   \return  none
1505 */
1506 static void
CConcealment_UpdateState(CConcealmentInfo * pConcealmentInfo,int frameOk)1507   CConcealment_UpdateState (
1508     CConcealmentInfo *pConcealmentInfo,
1509     int frameOk )
1510 {
1511   CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams;
1512 
1513   switch (pConcealCommonData->method)
1514   {
1515   case ConcealMethodNoise:
1516     {
1517       if (pConcealmentInfo->concealState != ConcealState_Ok) {
1518         /* count the valid frames during concealment process */
1519         if (frameOk) {
1520           pConcealmentInfo->cntValidFrames += 1;
1521         } else {
1522           pConcealmentInfo->cntValidFrames  = 0;
1523         }
1524       }
1525 
1526       /* -- STATE MACHINE for Noise Substitution -- */
1527       switch (pConcealmentInfo->concealState)
1528       {
1529       case ConcealState_Ok:
1530         if (!frameOk) {
1531           if (pConcealCommonData->numFadeOutFrames > 0) {
1532             /* change to state SINGLE-FRAME-LOSS */
1533             pConcealmentInfo->concealState   = ConcealState_Single;
1534           } else {
1535             /* change to state MUTE */
1536             pConcealmentInfo->concealState = ConcealState_Mute;
1537           }
1538           pConcealmentInfo->cntFadeFrames  = 0;
1539           pConcealmentInfo->cntValidFrames = 0;
1540         }
1541         break;
1542 
1543       case ConcealState_Single:  /* Just a pre-stage before fade-out begins. Stay here only one frame! */
1544         pConcealmentInfo->cntFadeFrames += 1;
1545         if (frameOk) {
1546           if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) {
1547             /* change to state FADE-IN */
1548             pConcealmentInfo->concealState  = ConcealState_FadeIn;
1549             pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData,
1550                                                                  pConcealmentInfo->cntFadeFrames-1,
1551                                                                  0 /* FadeOut -> FadeIn */);
1552           } else {
1553             /* change to state OK */
1554             pConcealmentInfo->concealState = ConcealState_Ok;
1555           }
1556         } else {
1557           if (pConcealmentInfo->cntFadeFrames >= pConcealCommonData->numFadeOutFrames) {
1558             /* change to state MUTE */
1559             pConcealmentInfo->concealState = ConcealState_Mute;
1560           } else {
1561             /* change to state FADE-OUT */
1562             pConcealmentInfo->concealState = ConcealState_FadeOut;
1563           }
1564         }
1565         break;
1566 
1567       case ConcealState_FadeOut:
1568         pConcealmentInfo->cntFadeFrames += 1;  /* used to address the fade-out factors */
1569         if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) {
1570           if (pConcealCommonData->numFadeInFrames > 0) {
1571             /* change to state FADE-IN */
1572             pConcealmentInfo->concealState  = ConcealState_FadeIn;
1573             pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData,
1574                                                                  pConcealmentInfo->cntFadeFrames-1,
1575                                                                  0 /* FadeOut -> FadeIn */);
1576           } else {
1577             /* change to state OK */
1578             pConcealmentInfo->concealState = ConcealState_Ok;
1579           }
1580         } else {
1581           if (pConcealmentInfo->cntFadeFrames >= pConcealCommonData->numFadeOutFrames) {
1582             /* change to state MUTE */
1583             pConcealmentInfo->concealState = ConcealState_Mute;
1584           }
1585         }
1586         break;
1587 
1588       case ConcealState_Mute:
1589         if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) {
1590           if (pConcealCommonData->numFadeInFrames > 0) {
1591             /* change to state FADE-IN */
1592             pConcealmentInfo->concealState = ConcealState_FadeIn;
1593             pConcealmentInfo->cntFadeFrames = pConcealCommonData->numFadeInFrames - 1;
1594           } else {
1595             /* change to state OK */
1596             pConcealmentInfo->concealState = ConcealState_Ok;
1597           }
1598         }
1599         break;
1600 
1601       case ConcealState_FadeIn:
1602         pConcealmentInfo->cntFadeFrames -= 1;  /* used to address the fade-in factors */
1603         if (frameOk) {
1604           if (pConcealmentInfo->cntFadeFrames < 0) {
1605             /* change to state OK */
1606             pConcealmentInfo->concealState = ConcealState_Ok;
1607           }
1608         } else {
1609           if (pConcealCommonData->numFadeOutFrames > 0) {
1610             /* change to state FADE-OUT */
1611             pConcealmentInfo->concealState  = ConcealState_FadeOut;
1612             pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData,
1613                                                                  pConcealmentInfo->cntFadeFrames+1,
1614                                                                  1 /* FadeIn -> FadeOut */);
1615           } else {
1616             /* change to state MUTE */
1617             pConcealmentInfo->concealState = ConcealState_Mute;
1618           }
1619         }
1620         break;
1621 
1622       default:
1623         FDK_ASSERT(0);
1624         break;
1625       }
1626     }
1627     break;
1628 
1629   case ConcealMethodInter:
1630   case ConcealMethodTonal:
1631     {
1632       if (pConcealmentInfo->concealState != ConcealState_Ok) {
1633         /* count the valid frames during concealment process */
1634         if ( pConcealmentInfo->prevFrameOk[1] ||
1635             (pConcealmentInfo->prevFrameOk[0] && !pConcealmentInfo->prevFrameOk[1] && frameOk) ) {
1636           /* The frame is OK even if it can be estimated by the energy interpolation algorithm */
1637           pConcealmentInfo->cntValidFrames += 1;
1638         } else {
1639           pConcealmentInfo->cntValidFrames  = 0;
1640         }
1641       }
1642 
1643       /* -- STATE MACHINE for energy interpolation -- */
1644       switch (pConcealmentInfo->concealState)
1645       {
1646       case ConcealState_Ok:
1647         if (!(pConcealmentInfo->prevFrameOk[1] ||
1648              (pConcealmentInfo->prevFrameOk[0] && !pConcealmentInfo->prevFrameOk[1] && frameOk))) {
1649           if (pConcealCommonData->numFadeOutFrames > 0) {
1650             /* Fade out only if the energy interpolation algorithm can not be applied! */
1651             pConcealmentInfo->concealState   = ConcealState_FadeOut;
1652           } else {
1653             /* change to state MUTE */
1654             pConcealmentInfo->concealState = ConcealState_Mute;
1655           }
1656           pConcealmentInfo->cntFadeFrames  = 0;
1657           pConcealmentInfo->cntValidFrames = 0;
1658         }
1659         break;
1660 
1661       case ConcealState_Single:
1662         pConcealmentInfo->concealState = ConcealState_Ok;
1663         break;
1664 
1665       case ConcealState_FadeOut:
1666         pConcealmentInfo->cntFadeFrames += 1;
1667 
1668         if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) {
1669           if (pConcealCommonData->numFadeInFrames > 0) {
1670             /* change to state FADE-IN */
1671             pConcealmentInfo->concealState  = ConcealState_FadeIn;
1672             pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData,
1673                                                                  pConcealmentInfo->cntFadeFrames-1,
1674                                                                  0 /* FadeOut -> FadeIn */);
1675           } else {
1676             /* change to state OK */
1677             pConcealmentInfo->concealState = ConcealState_Ok;
1678           }
1679         } else {
1680           if (pConcealmentInfo->cntFadeFrames >= pConcealCommonData->numFadeOutFrames) {
1681             /* change to state MUTE */
1682             pConcealmentInfo->concealState = ConcealState_Mute;
1683           }
1684         }
1685         break;
1686 
1687       case ConcealState_Mute:
1688         if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) {
1689           if (pConcealCommonData->numFadeInFrames > 0) {
1690             /* change to state FADE-IN */
1691             pConcealmentInfo->concealState = ConcealState_FadeIn;
1692             pConcealmentInfo->cntFadeFrames = pConcealCommonData->numFadeInFrames - 1;
1693           } else {
1694             /* change to state OK */
1695             pConcealmentInfo->concealState = ConcealState_Ok;
1696           }
1697         }
1698         break;
1699 
1700       case ConcealState_FadeIn:
1701         pConcealmentInfo->cntFadeFrames -= 1;  /* used to address the fade-in factors */
1702 
1703         if (frameOk || pConcealmentInfo->prevFrameOk[1]) {
1704           if (pConcealmentInfo->cntFadeFrames < 0) {
1705             /* change to state OK */
1706             pConcealmentInfo->concealState = ConcealState_Ok;
1707           }
1708         } else {
1709           if (pConcealCommonData->numFadeOutFrames > 0) {
1710             /* change to state FADE-OUT */
1711             pConcealmentInfo->concealState  = ConcealState_FadeOut;
1712             pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData,
1713                                                                  pConcealmentInfo->cntFadeFrames+1,
1714                                                                  1 /* FadeIn -> FadeOut */);
1715           } else {
1716             /* change to state MUTE */
1717             pConcealmentInfo->concealState = ConcealState_Mute;
1718           }
1719         }
1720         break;
1721       } /* End switch(pConcealmentInfo->concealState) */
1722     }
1723     break;
1724 
1725   default:
1726     /* Don't need a state machine for other concealment methods. */
1727     break;
1728   }
1729 
1730 }
1731 
1732 
1733 /*!
1734 \brief Randomizes the sign of the spectral data
1735 
1736   The function toggles the sign of the spectral data randomly. This is
1737   useful to ensure the quality of the concealed frames.
1738 
1739 \return  none
1740  */
1741 static
CConcealment_ApplyRandomSign(int randomPhase,FIXP_DBL * spec,int samplesPerFrame)1742 void CConcealment_ApplyRandomSign (int randomPhase,
1743                                    FIXP_DBL *spec,
1744                                    int samplesPerFrame
1745                                                )
1746 {
1747   int i;
1748   USHORT packedSign=0;
1749 
1750   /* random table 512x16bit has been reduced to 512 packed sign bits = 32x16 bit */
1751 
1752   /* read current packed sign word */
1753   packedSign = randomSign[randomPhase>>4];
1754   packedSign >>= (randomPhase&0xf);
1755 
1756   for (i = 0; i < samplesPerFrame ; i++) {
1757     if ((randomPhase & 0xf) == 0) {
1758       packedSign = randomSign[randomPhase>>4];
1759     }
1760 
1761     if (packedSign & 0x1) {
1762       spec[i] = -spec[i];
1763     }
1764     packedSign >>= 1;
1765 
1766     randomPhase = (randomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);
1767   }
1768 }
1769 
1770 
1771 /*!
1772   \brief Get fadeing factor for current concealment state.
1773 
1774   The function returns the factor used for fading that belongs to the current internal state.
1775 
1776   \return Fade factor
1777  */
1778 FIXP_DBL
CConcealment_GetFadeFactor(CConcealmentInfo * hConcealmentInfo,const int fPreviousFactor)1779   CConcealment_GetFadeFactor (
1780       CConcealmentInfo *hConcealmentInfo,
1781       const int fPreviousFactor
1782   )
1783 {
1784   FIXP_DBL fac = (FIXP_DBL)0;
1785 
1786   CConcealParams *pConcealCommonData = hConcealmentInfo->pConcealParams;
1787 
1788   if (hConcealmentInfo->pConcealParams->method > ConcealMethodMute) {
1789     switch (hConcealmentInfo->concealState) {
1790       default:
1791       case ConcealState_Mute:
1792         /* Nothing to do here */
1793         break;
1794       case ConcealState_Ok:
1795         fac = (FIXP_DBL)MAXVAL_DBL;
1796         break;
1797       case ConcealState_Single:
1798       case ConcealState_FadeOut:
1799         {
1800           int idx = hConcealmentInfo->cntFadeFrames - ((fPreviousFactor != 0) ? 1 : 0);
1801           fac = (idx < 0) ? (FIXP_DBL)MAXVAL_DBL : FX_SGL2FX_DBL(pConcealCommonData->fadeOutFactor[idx]);
1802         }
1803         break;
1804       case ConcealState_FadeIn:
1805         {
1806           int idx = hConcealmentInfo->cntFadeFrames + ((fPreviousFactor != 0) ? 1 : 0);
1807           fac = (idx >= hConcealmentInfo->pConcealParams->numFadeInFrames) ? (FIXP_DBL)0 : FX_SGL2FX_DBL(pConcealCommonData->fadeInFactor[idx]);
1808         }
1809         break;
1810     }
1811   }
1812 
1813   return (fac);
1814 }
1815 
1816 
1817 /*!
1818   \brief Get fadeing factor for current concealment state.
1819 
1820   The function returns the state (ok or not) of the previous frame.
1821   If called before the function CConcealment_Apply() set the fBeforeApply
1822   flag to get the correct value.
1823 
1824   \return Frame OK flag of previous frame.
1825  */
1826 int
CConcealment_GetLastFrameOk(CConcealmentInfo * hConcealmentInfo,const int fBeforeApply)1827   CConcealment_GetLastFrameOk (
1828       CConcealmentInfo *hConcealmentInfo,
1829       const int fBeforeApply
1830   )
1831 {
1832   int prevFrameOk = 1;
1833 
1834   if (hConcealmentInfo != NULL) {
1835     prevFrameOk = hConcealmentInfo->prevFrameOk[fBeforeApply & 0x1];
1836   }
1837 
1838   return prevFrameOk;
1839 }
1840 
1841 /*!
1842   \brief Get the number of delay frames introduced by concealment technique.
1843 
1844   \return Number of delay frames.
1845  */
1846 UINT
CConcealment_GetDelay(CConcealParams * pConcealCommonData)1847   CConcealment_GetDelay (
1848       CConcealParams *pConcealCommonData
1849   )
1850 {
1851   UINT frameDelay = 0;
1852 
1853   if (pConcealCommonData != NULL) {
1854     switch (pConcealCommonData->method) {
1855     case ConcealMethodTonal:
1856     case ConcealMethodInter:
1857       frameDelay = 1;
1858       break;
1859     default:
1860       break;
1861     }
1862   }
1863 
1864   return frameDelay;
1865 }
1866 
1867