• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
5 Forschung e.V. All rights reserved.
6 
7  1.    INTRODUCTION
8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
11 a wide variety of Android devices.
12 
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14 general perceptual audio codecs. AAC-ELD is considered the best-performing
15 full-bandwidth communications codec by independent studies and is widely
16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17 specifications.
18 
19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
20 those of Fraunhofer) may be obtained through Via Licensing
21 (www.vialicensing.com) or through the respective patent owners individually for
22 the purpose of encoding or decoding bit streams in products that are compliant
23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24 Android devices already license these patent claims through Via Licensing or
25 directly from the patent owners, and therefore FDK AAC Codec software may
26 already be covered under those patent licenses when it is used for those
27 licensed purposes only.
28 
29 Commercially-licensed AAC software libraries, including floating-point versions
30 with enhanced sound quality, are also available from Fraunhofer. Users are
31 encouraged to check the Fraunhofer website for additional applications
32 information and documentation.
33 
34 2.    COPYRIGHT LICENSE
35 
36 Redistribution and use in source and binary forms, with or without modification,
37 are permitted without payment of copyright license fees provided that you
38 satisfy the following conditions:
39 
40 You must retain the complete text of this software license in redistributions of
41 the FDK AAC Codec or your modifications thereto in source code form.
42 
43 You must retain the complete text of this software license in the documentation
44 and/or other materials provided with redistributions of the FDK AAC Codec or
45 your modifications thereto in binary form. You must make available free of
46 charge copies of the complete source code of the FDK AAC Codec and your
47 modifications thereto to recipients of copies in binary form.
48 
49 The name of Fraunhofer may not be used to endorse or promote products derived
50 from this library without prior written permission.
51 
52 You may not charge copyright license fees for anyone to use, copy or distribute
53 the FDK AAC Codec software or your modifications thereto.
54 
55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
56 that you changed the software and the date of any change. For modified versions
57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59 AAC Codec Library for Android."
60 
61 3.    NO PATENT LICENSE
62 
63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65 Fraunhofer provides no warranty of patent non-infringement with respect to this
66 software.
67 
68 You may use this FDK AAC Codec software or modifications thereto only for
69 purposes that are authorized by appropriate patent licenses.
70 
71 4.    DISCLAIMER
72 
73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75 including but not limited to the implied warranties of merchantability and
76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78 or consequential damages, including but not limited to procurement of substitute
79 goods or services; loss of use, data, or profits, or business interruption,
80 however caused and on any theory of liability, whether in contract, strict
81 liability, or tort (including negligence), arising in any way out of the use of
82 this software, even if advised of the possibility of such damage.
83 
84 5.    CONTACT INFORMATION
85 
86 Fraunhofer Institute for Integrated Circuits IIS
87 Attention: Audio and Multimedia Departments - FDK AAC LL
88 Am Wolfsmantel 33
89 91058 Erlangen, Germany
90 
91 www.iis.fraunhofer.de/amm
92 amm-info@iis.fraunhofer.de
93 ----------------------------------------------------------------------------- */
94 
95 /**************************** AAC decoder library ******************************
96 
97    Author(s):   Josef Hoepfl
98 
99    Description: independent channel concealment
100 
101 *******************************************************************************/
102 
103 /*!
104   \page concealment AAC core concealment
105 
106   This AAC core implementation includes a concealment function, which can be
107   enabled using the several defines during compilation.
108 
109   There are various tests inside the core, starting with simple CRC tests and
110   ending in a variety of plausibility checks. If such a check indicates an
111   invalid bitstream, then concealment is applied.
112 
113   Concealment is also applied when the calling main program indicates a
114   distorted or missing data frame using the frameOK flag. This is used for error
115   detection on the transport layer. (See below)
116 
117   There are three concealment-modes:
118 
119   1) Muting: The spectral data is simply set to zero in case of an detected
120   error.
121 
122   2) Noise substitution: In case of an detected error, concealment copies the
123   last frame and adds attenuates the spectral data. For this mode you have to
124   set the #CONCEAL_NOISE define. Noise substitution adds no additional delay.
125 
126   3) Interpolation: The interpolation routine swaps the spectral data from the
127   previous and the current frame just before the final frequency to time
128   conversion. In case a single frame is corrupted, concealmant interpolates
129   between the last good and the first good frame to create the spectral data for
130   the missing frame. If multiple frames are corrupted, concealment implements
131   first a fade out based on slightly modified spectral values from the last good
132      frame. As soon as good frames are available, concealmant fades in the new
133   spectral data. For this mode you have to set the #CONCEAL_INTER define. Note
134   that in this case, you also need to set #SBR_BS_DELAY_ENABLE, which basically
135   adds approriate delay in the SBR decoder. Note that the
136   Interpolating-Concealment increases the delay of your decoder by one frame and
137   that it does require additional resources such as memory and computational
138   complexity.
139 
140   <h2>How concealment can be used with errors on the transport layer</h2>
141 
142   Many errors can or have to be detected on the transport layer. For example in
143   IP based systems packet loss can occur. The transport protocol used should
144   indicate such packet loss by inserting an empty frame with frameOK=0.
145 */
146 
147 #include "conceal.h"
148 
149 #include "aac_rom.h"
150 #include "genericStds.h"
151 
152 /* PNS (of block) */
153 #include "aacdec_pns.h"
154 #include "block.h"
155 
156 #define CONCEAL_DFLT_COMF_NOISE_LEVEL (0x100000)
157 
158 #define CONCEAL_NOT_DEFINED ((UCHAR)-1)
159 
160 /* default settings */
161 #define CONCEAL_DFLT_FADEOUT_FRAMES (6)
162 #define CONCEAL_DFLT_FADEIN_FRAMES (5)
163 #define CONCEAL_DFLT_MUTE_RELEASE_FRAMES (0)
164 
165 #define CONCEAL_DFLT_FADE_FACTOR (0.707106781186548f) /* 1/sqrt(2) */
166 
167 /* some often used constants: */
168 #define FIXP_ZERO FL2FXCONST_DBL(0.0f)
169 #define FIXP_ONE FL2FXCONST_DBL(1.0f)
170 #define FIXP_FL_CORRECTION FL2FXCONST_DBL(0.53333333333333333f)
171 
172 /* For parameter conversion */
173 #define CONCEAL_PARAMETER_BITS (8)
174 #define CONCEAL_MAX_QUANT_FACTOR ((1 << CONCEAL_PARAMETER_BITS) - 1)
175 /*#define CONCEAL_MIN_ATTENUATION_FACTOR_025  ( FL2FXCONST_DBL(0.971627951577106174) )*/ /* -0.25 dB */
176 #define CONCEAL_MIN_ATTENUATION_FACTOR_025_LD \
177   FL2FXCONST_DBL(-0.041524101186092029596853445212299)
178 /*#define CONCEAL_MIN_ATTENUATION_FACTOR_050  ( FL2FXCONST_DBL(0.944060876285923380) )*/ /* -0.50 dB */
179 #define CONCEAL_MIN_ATTENUATION_FACTOR_050_LD \
180   FL2FXCONST_DBL(-0.083048202372184059253597008145293)
181 
182 typedef enum {
183   CConcealment_NoExpand,
184   CConcealment_Expand,
185   CConcealment_Compress
186 } CConcealmentExpandType;
187 
188 static const FIXP_SGL facMod4Table[4] = {
189     FL2FXCONST_SGL(0.500000000f), /* FIXP_SGL(0x4000),  2^-(1-0,00) */
190     FL2FXCONST_SGL(0.594603558f), /* FIXP_SGL(0x4c1b),  2^-(1-0,25) */
191     FL2FXCONST_SGL(0.707106781f), /* FIXP_SGL(0x5a82),  2^-(1-0,50) */
192     FL2FXCONST_SGL(0.840896415f)  /* FIXP_SGL(0x6ba2)   2^-(1-0,75) */
193 };
194 
195 static void CConcealment_CalcBandEnergy(
196     FIXP_DBL *spectrum, const SamplingRateInfo *pSamplingRateInfo,
197     const int blockType, CConcealmentExpandType ex, int *sfbEnergy);
198 
199 static void CConcealment_InterpolateBuffer(FIXP_DBL *spectrum,
200                                            SHORT *pSpecScalePrev,
201                                            SHORT *pSpecScaleAct,
202                                            SHORT *pSpecScaleOut, int *enPrv,
203                                            int *enAct, int sfbCnt,
204                                            const SHORT *pSfbOffset);
205 
206 static int CConcealment_ApplyInter(
207     CConcealmentInfo *pConcealmentInfo,
208     CAacDecoderChannelInfo *pAacDecoderChannelInfo,
209     const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
210     const int improveTonal, const int frameOk, const int mute_release_active);
211 
212 static int CConcealment_ApplyNoise(
213     CConcealmentInfo *pConcealmentInfo,
214     CAacDecoderChannelInfo *pAacDecoderChannelInfo,
215     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
216     const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
217     const UINT flags);
218 
219 static void CConcealment_UpdateState(
220     CConcealmentInfo *pConcealmentInfo, int frameOk,
221     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
222     const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo);
223 
224 static void CConcealment_ApplyRandomSign(int iRandomPhase, FIXP_DBL *spec,
225                                          int samplesPerFrame);
226 
227 /* TimeDomainFading */
228 static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart,
229                                       FIXP_DBL fadeStop, PCM_DEC *pcmdata);
230 static void CConcealment_TDFadeFillFadingStations(FIXP_DBL *fadingStations,
231                                                   int *fadingSteps,
232                                                   FIXP_DBL fadeStop,
233                                                   FIXP_DBL fadeStart,
234                                                   TDfadingType fadingType);
235 static void CConcealment_TDFading_doLinearFadingSteps(int *fadingSteps);
236 
237 /* Streamline the state machine */
238 static int CConcealment_ApplyFadeOut(
239     int mode, CConcealmentInfo *pConcealmentInfo,
240     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
241     const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo);
242 
243 static int CConcealment_TDNoise_Random(ULONG *seed);
244 static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo,
245                                        const int len,
246                                        const INT aacOutDataHeadroom,
247                                        PCM_DEC *const pcmdata);
248 
CConcealment_GetWinSeq(int prevWinSeq)249 static BLOCK_TYPE CConcealment_GetWinSeq(int prevWinSeq) {
250   BLOCK_TYPE newWinSeq = BLOCK_LONG;
251 
252   /* Try to have only long blocks */
253   if (prevWinSeq == BLOCK_START || prevWinSeq == BLOCK_SHORT) {
254     newWinSeq = BLOCK_STOP;
255   }
256 
257   return (newWinSeq);
258 }
259 
260 /*!
261   \brief Init common concealment information data
262 
263   \param pConcealCommonData Pointer to the concealment common data structure.
264 */
CConcealment_InitCommonData(CConcealParams * pConcealCommonData)265 void CConcealment_InitCommonData(CConcealParams *pConcealCommonData) {
266   if (pConcealCommonData != NULL) {
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 =
277         (FIXP_DBL)CONCEAL_DFLT_COMF_NOISE_LEVEL;
278 
279     /* Init fade factors (symetric) */
280     pConcealCommonData->fadeOutFactor[0] =
281         FL2FXCONST_SGL(CONCEAL_DFLT_FADE_FACTOR);
282     pConcealCommonData->fadeInFactor[0] = pConcealCommonData->fadeOutFactor[0];
283 
284     for (i = 1; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
285       pConcealCommonData->fadeOutFactor[i] =
286           FX_DBL2FX_SGL(fMult(pConcealCommonData->fadeOutFactor[i - 1],
287                               FL2FXCONST_SGL(CONCEAL_DFLT_FADE_FACTOR)));
288       pConcealCommonData->fadeInFactor[i] =
289           pConcealCommonData->fadeOutFactor[i];
290     }
291   }
292 }
293 
294 /*!
295   \brief Get current concealment method.
296 
297   \param pConcealCommonData Pointer to common concealment data (for all
298   channels)
299 */
CConcealment_GetMethod(CConcealParams * pConcealCommonData)300 CConcealmentMethod CConcealment_GetMethod(CConcealParams *pConcealCommonData) {
301   CConcealmentMethod method = ConcealMethodNone;
302 
303   if (pConcealCommonData != NULL) {
304     method = pConcealCommonData->method;
305   }
306 
307   return (method);
308 }
309 
310 /*!
311   \brief Init concealment information for each channel
312 
313   \param pConcealChannelInfo Pointer to the channel related concealment info
314   structure to be initialized. \param pConcealCommonData  Pointer to common
315   concealment data (for all channels) \param initRenderMode      Initial render
316   mode to be set for the current channel. \param samplesPerFrame     The number
317   of samples per frame.
318 */
CConcealment_InitChannelData(CConcealmentInfo * pConcealChannelInfo,CConcealParams * pConcealCommonData,AACDEC_RENDER_MODE initRenderMode,int samplesPerFrame)319 void CConcealment_InitChannelData(CConcealmentInfo *pConcealChannelInfo,
320                                   CConcealParams *pConcealCommonData,
321                                   AACDEC_RENDER_MODE initRenderMode,
322                                   int samplesPerFrame) {
323   int i;
324   pConcealChannelInfo->TDNoiseSeed = 0;
325   FDKmemclear(pConcealChannelInfo->TDNoiseStates,
326               sizeof(pConcealChannelInfo->TDNoiseStates));
327   pConcealChannelInfo->TDNoiseCoef[0] = FL2FXCONST_SGL(0.05f);
328   pConcealChannelInfo->TDNoiseCoef[1] = FL2FXCONST_SGL(0.5f);
329   pConcealChannelInfo->TDNoiseCoef[2] = FL2FXCONST_SGL(0.45f);
330 
331   pConcealChannelInfo->pConcealParams = pConcealCommonData;
332 
333   pConcealChannelInfo->lastRenderMode = initRenderMode;
334 
335   pConcealChannelInfo->windowShape = CONCEAL_NOT_DEFINED;
336   pConcealChannelInfo->windowSequence = BLOCK_LONG; /* default type */
337   pConcealChannelInfo->lastWinGrpLen = 1;
338 
339   pConcealChannelInfo->concealState = ConcealState_Ok;
340 
341   FDKmemclear(pConcealChannelInfo->spectralCoefficient,
342               1024 * sizeof(FIXP_CNCL));
343 
344   for (i = 0; i < 8; i++) {
345     pConcealChannelInfo->specScale[i] = 0;
346   }
347 
348   pConcealChannelInfo->iRandomPhase = 0;
349 
350   pConcealChannelInfo->prevFrameOk[0] = 1;
351   pConcealChannelInfo->prevFrameOk[1] = 1;
352 
353   pConcealChannelInfo->cntFadeFrames = 0;
354   pConcealChannelInfo->cntValidFrames = 0;
355   pConcealChannelInfo->fade_old = (FIXP_DBL)MAXVAL_DBL;
356   pConcealChannelInfo->winGrpOffset[0] = 0;
357   pConcealChannelInfo->winGrpOffset[1] = 0;
358   pConcealChannelInfo->attGrpOffset[0] = 0;
359   pConcealChannelInfo->attGrpOffset[1] = 0;
360 }
361 
362 /*!
363   \brief Set error concealment parameters
364 
365   \param concealParams
366   \param method
367   \param fadeOutSlope
368   \param fadeInSlope
369   \param muteRelease
370   \param comfNoiseLevel
371 */
372 AAC_DECODER_ERROR
CConcealment_SetParams(CConcealParams * concealParams,int method,int fadeOutSlope,int fadeInSlope,int muteRelease,FIXP_DBL comfNoiseLevel)373 CConcealment_SetParams(CConcealParams *concealParams, int method,
374                        int fadeOutSlope, int fadeInSlope, int muteRelease,
375                        FIXP_DBL comfNoiseLevel) {
376   /* set concealment technique */
377   if (method != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
378     switch ((CConcealmentMethod)method) {
379       case ConcealMethodMute:
380       case ConcealMethodNoise:
381       case ConcealMethodInter:
382         /* Be sure to enable delay adjustment of SBR decoder! */
383         if (concealParams == NULL) {
384           return AAC_DEC_INVALID_HANDLE;
385         } else {
386           /* set param */
387           concealParams->method = (CConcealmentMethod)method;
388         }
389         break;
390 
391       default:
392         return AAC_DEC_SET_PARAM_FAIL;
393     }
394   }
395 
396   /* set number of frames for fade-out slope */
397   if (fadeOutSlope != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
398     if ((fadeOutSlope < CONCEAL_MAX_NUM_FADE_FACTORS) && (fadeOutSlope >= 0)) {
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) && (fadeInSlope >= 0)) {
413       if (concealParams == NULL) {
414         return AAC_DEC_INVALID_HANDLE;
415       } else {
416         /* set param */
417         concealParams->numFadeInFrames = fadeInSlope;
418       }
419     } else {
420       return AAC_DEC_SET_PARAM_FAIL;
421     }
422   }
423 
424   /* set number of error-free frames after which the muting will be released */
425   if (muteRelease != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
426     if ((muteRelease < (CONCEAL_MAX_NUM_FADE_FACTORS << 1)) &&
427         (muteRelease >= 0)) {
428       if (concealParams == NULL) {
429         return AAC_DEC_INVALID_HANDLE;
430       } else {
431         /* set param */
432         concealParams->numMuteReleaseFrames = muteRelease;
433       }
434     } else {
435       return AAC_DEC_SET_PARAM_FAIL;
436     }
437   }
438 
439   /* set confort noise level which will be inserted while in state 'muting' */
440   if (comfNoiseLevel != (FIXP_DBL)AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
441     if ((comfNoiseLevel < (FIXP_DBL)0) ||
442         (comfNoiseLevel > (FIXP_DBL)MAXVAL_DBL)) {
443       return AAC_DEC_SET_PARAM_FAIL;
444     }
445     if (concealParams == NULL) {
446       return AAC_DEC_INVALID_HANDLE;
447     } else {
448       concealParams->comfortNoiseLevel = (FIXP_DBL)comfNoiseLevel;
449     }
450   }
451 
452   return (AAC_DEC_OK);
453 }
454 
455 /*!
456   \brief Set fade-out/in attenuation factor vectors
457 
458   \param concealParams
459   \param fadeOutAttenuationVector
460   \param fadeInAttenuationVector
461 
462   \return 0 if OK all other values indicate errors
463 */
464 AAC_DECODER_ERROR
CConcealment_SetAttenuation(CConcealParams * concealParams,const SHORT * fadeOutAttenuationVector,const SHORT * fadeInAttenuationVector)465 CConcealment_SetAttenuation(CConcealParams *concealParams,
466                             const SHORT *fadeOutAttenuationVector,
467                             const SHORT *fadeInAttenuationVector) {
468   if ((fadeOutAttenuationVector == NULL) && (fadeInAttenuationVector == NULL)) {
469     return AAC_DEC_SET_PARAM_FAIL;
470   }
471 
472   /* Fade-out factors */
473   if (fadeOutAttenuationVector != NULL) {
474     int i;
475 
476     /* check quantized factors first */
477     for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
478       if ((fadeOutAttenuationVector[i] < 0) ||
479           (fadeOutAttenuationVector[i] > CONCEAL_MAX_QUANT_FACTOR)) {
480         return AAC_DEC_SET_PARAM_FAIL;
481       }
482     }
483     if (concealParams == NULL) {
484       return AAC_DEC_INVALID_HANDLE;
485     }
486 
487     /* now dequantize factors */
488     for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
489       concealParams->fadeOutFactor[i] =
490           FX_DBL2FX_SGL(fLdPow(CONCEAL_MIN_ATTENUATION_FACTOR_025_LD, 0,
491                                (FIXP_DBL)((INT)(FL2FXCONST_DBL(1.0 / 2.0) >>
492                                                 (CONCEAL_PARAMETER_BITS - 1)) *
493                                           (INT)fadeOutAttenuationVector[i]),
494                                CONCEAL_PARAMETER_BITS));
495     }
496   }
497 
498   /* Fade-in factors */
499   if (fadeInAttenuationVector != NULL) {
500     int i;
501 
502     /* check quantized factors first */
503     for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
504       if ((fadeInAttenuationVector[i] < 0) ||
505           (fadeInAttenuationVector[i] > CONCEAL_MAX_QUANT_FACTOR)) {
506         return AAC_DEC_SET_PARAM_FAIL;
507       }
508     }
509     if (concealParams == NULL) {
510       return AAC_DEC_INVALID_HANDLE;
511     }
512 
513     /* now dequantize factors */
514     for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
515       concealParams->fadeInFactor[i] = FX_DBL2FX_SGL(
516           fLdPow(CONCEAL_MIN_ATTENUATION_FACTOR_025_LD, 0,
517                  (FIXP_DBL)((INT)(FIXP_ONE >> CONCEAL_PARAMETER_BITS) *
518                             (INT)fadeInAttenuationVector[i]),
519                  CONCEAL_PARAMETER_BITS));
520     }
521   }
522 
523   return (AAC_DEC_OK);
524 }
525 
526 /*!
527   \brief Get state of concealment module.
528 
529   \param pConcealChannelInfo
530 
531   \return Concealment state.
532 */
CConcealment_GetState(CConcealmentInfo * pConcealChannelInfo)533 CConcealmentState CConcealment_GetState(CConcealmentInfo *pConcealChannelInfo) {
534   CConcealmentState state = ConcealState_Ok;
535 
536   if (pConcealChannelInfo != NULL) {
537     state = pConcealChannelInfo->concealState;
538   }
539 
540   return (state);
541 }
542 
543 /*!
544   \brief Store data for concealment techniques applied later
545 
546   Interface function to store data for different concealment strategies
547  */
CConcealment_Store(CConcealmentInfo * hConcealmentInfo,CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo)548 void CConcealment_Store(
549     CConcealmentInfo *hConcealmentInfo,
550     CAacDecoderChannelInfo *pAacDecoderChannelInfo,
551     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) {
552   UCHAR nbDiv = NB_DIV;
553 
554   if (!(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD &&
555         pAacDecoderChannelInfo->data.usac.mod[nbDiv - 1] == 0))
556 
557   {
558     FIXP_DBL *pSpectralCoefficient =
559         SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
560     SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
561     CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
562 
563     SHORT tSpecScale[8];
564     UCHAR tWindowShape;
565     BLOCK_TYPE tWindowSequence;
566 
567     /* store old window infos for swapping */
568     tWindowSequence = hConcealmentInfo->windowSequence;
569     tWindowShape = hConcealmentInfo->windowShape;
570 
571     /* store old scale factors for swapping */
572     FDKmemcpy(tSpecScale, hConcealmentInfo->specScale, 8 * sizeof(SHORT));
573 
574     /* store new window infos */
575     hConcealmentInfo->windowSequence = GetWindowSequence(pIcsInfo);
576     hConcealmentInfo->windowShape = GetWindowShape(pIcsInfo);
577     hConcealmentInfo->lastWinGrpLen =
578         *(GetWindowGroupLengthTable(pIcsInfo) + GetWindowGroups(pIcsInfo) - 1);
579 
580     /* store new scale factors */
581     FDKmemcpy(hConcealmentInfo->specScale, pSpecScale, 8 * sizeof(SHORT));
582 
583     if (hConcealmentInfo->pConcealParams->method < ConcealMethodInter) {
584     /* store new spectral bins */
585 #if (CNCL_FRACT_BITS == DFRACT_BITS)
586       FDKmemcpy(hConcealmentInfo->spectralCoefficient, pSpectralCoefficient,
587                 1024 * sizeof(FIXP_CNCL));
588 #else
589       FIXP_CNCL *RESTRICT pCncl =
590           &hConcealmentInfo->spectralCoefficient[1024 - 1];
591       FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024 - 1];
592       int i;
593       for (i = 1024; i != 0; i--) {
594         *pCncl-- = FX_DBL2FX_CNCL(*pSpec--);
595       }
596 #endif
597     } else {
598     /* swap spectral data */
599 #if (FIXP_CNCL == FIXP_DBL)
600       C_ALLOC_SCRATCH_START(pSpecTmp, FIXP_DBL, 1024);
601       FDKmemcpy(pSpecTmp, pSpectralCoefficient, 1024 * sizeof(FIXP_DBL));
602       FDKmemcpy(pSpectralCoefficient, hConcealmentInfo->spectralCoefficient,
603                 1024 * sizeof(FIXP_DBL));
604       FDKmemcpy(hConcealmentInfo->spectralCoefficient, pSpecTmp,
605                 1024 * sizeof(FIXP_DBL));
606       C_ALLOC_SCRATCH_END(pSpecTmp, FIXP_DBL, 1024);
607 #else
608       FIXP_CNCL *RESTRICT pCncl =
609           &hConcealmentInfo->spectralCoefficient[1024 - 1];
610       FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024 - 1];
611       FIXP_DBL tSpec;
612 
613       for (int i = 1024; i != 0; i--) {
614         tSpec = *pSpec;
615         *pSpec-- = FX_CNCL2FX_DBL(*pCncl);
616         *pCncl-- = FX_DBL2FX_CNCL(tSpec);
617       }
618 #endif
619 
620       /* complete swapping of window infos */
621       pIcsInfo->WindowSequence = tWindowSequence;
622       pIcsInfo->WindowShape = tWindowShape;
623 
624       /* complete swapping of scale factors */
625       FDKmemcpy(pSpecScale, tSpecScale, 8 * sizeof(SHORT));
626     }
627   }
628 
629   if (pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD) {
630     /* Store LSF4 */
631     FDKmemcpy(hConcealmentInfo->lsf4, pAacDecoderStaticChannelInfo->lpc4_lsf,
632               sizeof(hConcealmentInfo->lsf4));
633     /* Store TCX gain */
634     hConcealmentInfo->last_tcx_gain =
635         pAacDecoderStaticChannelInfo->last_tcx_gain;
636     hConcealmentInfo->last_tcx_gain_e =
637         pAacDecoderStaticChannelInfo->last_tcx_gain_e;
638   }
639 }
640 
641 /*!
642   \brief Apply concealment
643 
644   Interface function to different concealment strategies
645  */
CConcealment_Apply(CConcealmentInfo * hConcealmentInfo,CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,const SamplingRateInfo * pSamplingRateInfo,const int samplesPerFrame,const UCHAR lastLpdMode,const int frameOk,const UINT flags)646 int CConcealment_Apply(
647     CConcealmentInfo *hConcealmentInfo,
648     CAacDecoderChannelInfo *pAacDecoderChannelInfo,
649     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
650     const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
651     const UCHAR lastLpdMode, const int frameOk, const UINT flags) {
652   int appliedProcessing = 0;
653   const int mute_release_active =
654       frameOk && (hConcealmentInfo->concealState >= ConcealState_Mute) &&
655       (hConcealmentInfo->cntValidFrames + 1 <=
656        hConcealmentInfo->pConcealParams->numMuteReleaseFrames);
657 
658   if (hConcealmentInfo->windowShape == CONCEAL_NOT_DEFINED) {
659     /* Initialize window_shape with same value as in the current (parsed) frame.
660        Because section 4.6.11.3.2 (Windowing and block switching) of ISO/IEC
661        14496-3:2009 says: For the first raw_data_block() to be decoded the
662        window_shape of the left and right half of the window are identical. */
663     hConcealmentInfo->windowShape = pAacDecoderChannelInfo->icsInfo.WindowShape;
664   }
665 
666   if (frameOk && !mute_release_active) {
667     /* Update render mode if frameOk except for ongoing mute release state. */
668     hConcealmentInfo->lastRenderMode =
669         (SCHAR)pAacDecoderChannelInfo->renderMode;
670 
671     /* Rescue current data for concealment in future frames */
672     CConcealment_Store(hConcealmentInfo, pAacDecoderChannelInfo,
673                        pAacDecoderStaticChannelInfo);
674     /* Reset index to random sign vector to make sign calculation frame agnostic
675        (only depends on number of subsequently concealed spectral blocks) */
676     hConcealmentInfo->iRandomPhase = 0;
677   } else {
678     if (hConcealmentInfo->lastRenderMode == AACDEC_RENDER_INVALID) {
679       hConcealmentInfo->lastRenderMode = AACDEC_RENDER_IMDCT;
680     }
681     pAacDecoderChannelInfo->renderMode =
682         (AACDEC_RENDER_MODE)hConcealmentInfo->lastRenderMode;
683   }
684 
685   /* hand current frame status to the state machine */
686   CConcealment_UpdateState(hConcealmentInfo, frameOk,
687                            pAacDecoderStaticChannelInfo, samplesPerFrame,
688                            pAacDecoderChannelInfo);
689 
690   {
691     if (!frameOk && pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_IMDCT) {
692       /* LPC extrapolation */
693       CLpc_Conceal(pAacDecoderChannelInfo->data.usac.lsp_coeff,
694                    pAacDecoderStaticChannelInfo->lpc4_lsf,
695                    pAacDecoderStaticChannelInfo->lsf_adaptive_mean,
696                    hConcealmentInfo->lastRenderMode == AACDEC_RENDER_IMDCT);
697       FDKmemcpy(hConcealmentInfo->lsf4, pAacDecoderStaticChannelInfo->lpc4_lsf,
698                 sizeof(pAacDecoderStaticChannelInfo->lpc4_lsf));
699     }
700 
701     /* Create data for signal rendering according to the selected concealment
702      * method and decoder operating mode. */
703 
704     if ((!frameOk || mute_release_active) &&
705         (pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD)) {
706       /* Restore old LSF4 */
707       FDKmemcpy(pAacDecoderStaticChannelInfo->lpc4_lsf, hConcealmentInfo->lsf4,
708                 sizeof(pAacDecoderStaticChannelInfo->lpc4_lsf));
709       /* Restore old TCX gain */
710       pAacDecoderStaticChannelInfo->last_tcx_gain =
711           hConcealmentInfo->last_tcx_gain;
712       pAacDecoderStaticChannelInfo->last_tcx_gain_e =
713           hConcealmentInfo->last_tcx_gain_e;
714     }
715 
716     if (!(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD &&
717           pAacDecoderStaticChannelInfo->last_lpd_mode == 0)) {
718       switch (hConcealmentInfo->pConcealParams->method) {
719         default:
720         case ConcealMethodMute:
721           if (!frameOk) {
722             /* Mute spectral data in case of errors */
723             FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient,
724                         samplesPerFrame * sizeof(FIXP_DBL));
725             /* Set last window shape */
726             pAacDecoderChannelInfo->icsInfo.WindowShape =
727                 hConcealmentInfo->windowShape;
728             appliedProcessing = 1;
729           }
730           break;
731 
732         case ConcealMethodNoise:
733           /* Noise substitution error concealment technique */
734           appliedProcessing = CConcealment_ApplyNoise(
735               hConcealmentInfo, pAacDecoderChannelInfo,
736               pAacDecoderStaticChannelInfo, pSamplingRateInfo, samplesPerFrame,
737               flags);
738           break;
739 
740         case ConcealMethodInter:
741           /* Energy interpolation concealment based on 3GPP */
742           appliedProcessing = CConcealment_ApplyInter(
743               hConcealmentInfo, pAacDecoderChannelInfo, pSamplingRateInfo,
744               samplesPerFrame, 0, /* don't use tonal improvement */
745               frameOk, mute_release_active);
746           break;
747       }
748     } else if (!frameOk || mute_release_active) {
749       /* simply restore the buffer */
750       FIXP_DBL *pSpectralCoefficient =
751           SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
752       SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
753       CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
754 #if (CNCL_FRACT_BITS != DFRACT_BITS)
755       FIXP_CNCL *RESTRICT pCncl =
756           &hConcealmentInfo->spectralCoefficient[1024 - 1];
757       FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024 - 1];
758       int i;
759 #endif
760 
761       /* restore window infos (gri) do we need that? */
762       pIcsInfo->WindowSequence = hConcealmentInfo->windowSequence;
763       pIcsInfo->WindowShape = hConcealmentInfo->windowShape;
764 
765       if (hConcealmentInfo->concealState != ConcealState_Mute) {
766         /* restore scale factors */
767         FDKmemcpy(pSpecScale, hConcealmentInfo->specScale, 8 * sizeof(SHORT));
768 
769         /* restore spectral bins */
770 #if (CNCL_FRACT_BITS == DFRACT_BITS)
771         FDKmemcpy(pSpectralCoefficient, hConcealmentInfo->spectralCoefficient,
772                   1024 * sizeof(FIXP_DBL));
773 #else
774         for (i = 1024; i != 0; i--) {
775           *pSpec-- = FX_CNCL2FX_DBL(*pCncl--);
776         }
777 #endif
778       } else {
779         /* clear scale factors */
780         FDKmemclear(pSpecScale, 8 * sizeof(SHORT));
781 
782         /* clear buffer */
783         FDKmemclear(pSpectralCoefficient, 1024 * sizeof(FIXP_CNCL));
784       }
785     }
786   }
787   /* update history */
788   hConcealmentInfo->prevFrameOk[0] = hConcealmentInfo->prevFrameOk[1];
789   hConcealmentInfo->prevFrameOk[1] = frameOk;
790 
791   return mute_release_active ? -1 : appliedProcessing;
792 }
793 
794 /*!
795 \brief Apply concealment noise substitution
796 
797   In case of frame lost this function produces a noisy frame with respect to the
798   energies values of past frame.
799  */
CConcealment_ApplyNoise(CConcealmentInfo * pConcealmentInfo,CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,const SamplingRateInfo * pSamplingRateInfo,const int samplesPerFrame,const UINT flags)800 static int CConcealment_ApplyNoise(
801     CConcealmentInfo *pConcealmentInfo,
802     CAacDecoderChannelInfo *pAacDecoderChannelInfo,
803     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
804     const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
805     const UINT flags) {
806   FIXP_DBL *pSpectralCoefficient =
807       SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
808   CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
809 
810   int appliedProcessing = 0;
811 
812   FDK_ASSERT(pConcealmentInfo != NULL);
813   FDK_ASSERT((samplesPerFrame >= 120) && (samplesPerFrame <= 1024));
814 
815   switch (pConcealmentInfo->concealState) {
816     case ConcealState_Ok:
817       /* Nothing to do here! */
818       break;
819 
820     case ConcealState_Single:
821     case ConcealState_FadeOut:
822       appliedProcessing = CConcealment_ApplyFadeOut(
823           /*mode =*/1, pConcealmentInfo, pAacDecoderStaticChannelInfo,
824           samplesPerFrame, pAacDecoderChannelInfo);
825       break;
826 
827     case ConcealState_Mute: {
828       /* set dummy window parameters */
829       pIcsInfo->Valid = 0; /* Trigger the generation of a consitent IcsInfo */
830       pIcsInfo->WindowShape =
831           pConcealmentInfo->windowShape; /* Prevent an invalid WindowShape
832                                             (required for F/T transform) */
833       pIcsInfo->WindowSequence =
834           CConcealment_GetWinSeq(pConcealmentInfo->windowSequence);
835       pConcealmentInfo->windowSequence =
836           pIcsInfo->WindowSequence; /* Store for next frame
837                                        (spectrum in concealment
838                                        buffer can't be used at
839                                        all) */
840 
841       /* mute spectral data */
842       FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL));
843       FDKmemclear(pConcealmentInfo->spectralCoefficient,
844                   samplesPerFrame * sizeof(FIXP_DBL));
845 
846       appliedProcessing = 1;
847     } break;
848 
849     case ConcealState_FadeIn: {
850       /* TimeDomainFading:                                        */
851       /* Attenuation of signal is done in CConcealment_TDFading() */
852 
853       appliedProcessing = 1;
854     } break;
855 
856     default:
857       /* we shouldn't come here anyway */
858       FDK_ASSERT(0);
859       break;
860   }
861 
862   return appliedProcessing;
863 }
864 
865 /*!
866   \brief Apply concealment interpolation
867 
868   The function swaps the data from the current and the previous frame. If an
869   error has occured, frame interpolation is performed to restore the missing
870   frame. In case of multiple faulty frames, fade-in and fade-out is applied.
871 */
CConcealment_ApplyInter(CConcealmentInfo * pConcealmentInfo,CAacDecoderChannelInfo * pAacDecoderChannelInfo,const SamplingRateInfo * pSamplingRateInfo,const int samplesPerFrame,const int improveTonal,const int frameOk,const int mute_release_active)872 static int CConcealment_ApplyInter(
873     CConcealmentInfo *pConcealmentInfo,
874     CAacDecoderChannelInfo *pAacDecoderChannelInfo,
875     const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
876     const int improveTonal, const int frameOk, const int mute_release_active) {
877 #if defined(FDK_ASSERT_ENABLE)
878   CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams;
879 #endif
880 
881   FIXP_DBL *pSpectralCoefficient =
882       SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
883   CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
884   SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
885 
886   int sfbEnergyPrev[64];
887   int sfbEnergyAct[64];
888 
889   int i, appliedProcessing = 0;
890 
891   /* clear/init */
892   FDKmemclear(sfbEnergyPrev, 64 * sizeof(int));
893   FDKmemclear(sfbEnergyAct, 64 * sizeof(int));
894 
895   if (!frameOk || mute_release_active) {
896     /* Restore last frame from concealment buffer */
897     pIcsInfo->WindowShape = pConcealmentInfo->windowShape;
898     pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence;
899 
900     /* Restore spectral data */
901     for (i = 0; i < samplesPerFrame; i++) {
902       pSpectralCoefficient[i] =
903           FX_CNCL2FX_DBL(pConcealmentInfo->spectralCoefficient[i]);
904     }
905 
906     /* Restore scale factors */
907     FDKmemcpy(pSpecScale, pConcealmentInfo->specScale, 8 * sizeof(SHORT));
908   }
909 
910   /* if previous frame was not ok */
911   if (!pConcealmentInfo->prevFrameOk[1] || mute_release_active) {
912     /* if current frame (f_n) is ok and the last but one frame (f_(n-2))
913        was ok, too, then interpolate both frames in order to generate
914        the current output frame (f_(n-1)). Otherwise, use the last stored
915        frame (f_(n-2) or f_(n-3) or ...). */
916     if (frameOk && pConcealmentInfo->prevFrameOk[0] && !mute_release_active) {
917       appliedProcessing = 1;
918 
919       /* Interpolate both frames in order to generate the current output frame
920        * (f_(n-1)). */
921       if (pIcsInfo->WindowSequence == BLOCK_SHORT) {
922         /* f_(n-2) == BLOCK_SHORT */
923         /* short--??????--short, short--??????--long interpolation */
924         /* short--short---short, short---long---long interpolation */
925 
926         int wnd;
927 
928         if (pConcealmentInfo->windowSequence ==
929             BLOCK_SHORT) { /* f_n == BLOCK_SHORT */
930           /* short--short---short interpolation */
931 
932           int scaleFactorBandsTotal =
933               pSamplingRateInfo->NumberOfScaleFactorBands_Short;
934           const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short;
935           pIcsInfo->WindowShape = (samplesPerFrame <= 512) ? 2 : 1;
936           pIcsInfo->WindowSequence = BLOCK_SHORT;
937 
938           for (wnd = 0; wnd < 8; wnd++) {
939             CConcealment_CalcBandEnergy(
940                 &pSpectralCoefficient[wnd *
941                                       (samplesPerFrame / 8)], /* spec_(n-2) */
942                 pSamplingRateInfo, BLOCK_SHORT, CConcealment_NoExpand,
943                 sfbEnergyPrev);
944 
945             CConcealment_CalcBandEnergy(
946                 &pConcealmentInfo->spectralCoefficient[wnd * (samplesPerFrame /
947                                                               8)], /* spec_n */
948                 pSamplingRateInfo, BLOCK_SHORT, CConcealment_NoExpand,
949                 sfbEnergyAct);
950 
951             CConcealment_InterpolateBuffer(
952                 &pSpectralCoefficient[wnd *
953                                       (samplesPerFrame / 8)], /* spec_(n-1) */
954                 &pSpecScale[wnd], &pConcealmentInfo->specScale[wnd],
955                 &pSpecScale[wnd], sfbEnergyPrev, sfbEnergyAct,
956                 scaleFactorBandsTotal, pSfbOffset);
957           }
958         } else { /* f_n != BLOCK_SHORT */
959           /* short---long---long interpolation */
960 
961           int scaleFactorBandsTotal =
962               pSamplingRateInfo->NumberOfScaleFactorBands_Long;
963           const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long;
964           SHORT specScaleOut;
965 
966           CConcealment_CalcBandEnergy(
967               &pSpectralCoefficient[samplesPerFrame -
968                                     (samplesPerFrame /
969                                      8)], /* [wnd] spec_(n-2) */
970               pSamplingRateInfo, BLOCK_SHORT, CConcealment_Expand,
971               sfbEnergyAct);
972 
973           CConcealment_CalcBandEnergy(
974               pConcealmentInfo->spectralCoefficient, /* spec_n */
975               pSamplingRateInfo, BLOCK_LONG, CConcealment_NoExpand,
976               sfbEnergyPrev);
977 
978           pIcsInfo->WindowShape = 0;
979           pIcsInfo->WindowSequence = BLOCK_STOP;
980 
981           for (i = 0; i < samplesPerFrame; i++) {
982             pSpectralCoefficient[i] =
983                 pConcealmentInfo->spectralCoefficient[i]; /* spec_n */
984           }
985 
986           for (i = 0; i < 8; i++) { /* search for max(specScale) */
987             if (pSpecScale[i] > pSpecScale[0]) {
988               pSpecScale[0] = pSpecScale[i];
989             }
990           }
991 
992           CConcealment_InterpolateBuffer(
993               pSpectralCoefficient, /* spec_(n-1) */
994               &pConcealmentInfo->specScale[0], &pSpecScale[0], &specScaleOut,
995               sfbEnergyPrev, sfbEnergyAct, scaleFactorBandsTotal, pSfbOffset);
996 
997           pSpecScale[0] = specScaleOut;
998         }
999       } else {
1000         /* long--??????--short, long--??????--long interpolation */
1001         /* long---long---short, long---long---long interpolation */
1002 
1003         int scaleFactorBandsTotal =
1004             pSamplingRateInfo->NumberOfScaleFactorBands_Long;
1005         const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long;
1006         SHORT specScaleAct = pConcealmentInfo->specScale[0];
1007 
1008         CConcealment_CalcBandEnergy(pSpectralCoefficient, /* spec_(n-2) */
1009                                     pSamplingRateInfo, BLOCK_LONG,
1010                                     CConcealment_NoExpand, sfbEnergyPrev);
1011 
1012         if (pConcealmentInfo->windowSequence ==
1013             BLOCK_SHORT) { /* f_n == BLOCK_SHORT */
1014           /* long---long---short interpolation */
1015 
1016           pIcsInfo->WindowShape = (samplesPerFrame <= 512) ? 2 : 1;
1017           pIcsInfo->WindowSequence = BLOCK_START;
1018 
1019           for (i = 1; i < 8; i++) { /* search for max(specScale) */
1020             if (pConcealmentInfo->specScale[i] > specScaleAct) {
1021               specScaleAct = pConcealmentInfo->specScale[i];
1022             }
1023           }
1024 
1025           /* Expand first short spectrum */
1026           CConcealment_CalcBandEnergy(
1027               pConcealmentInfo->spectralCoefficient,               /* spec_n */
1028               pSamplingRateInfo, BLOCK_SHORT, CConcealment_Expand, /* !!! */
1029               sfbEnergyAct);
1030         } else {
1031           /* long---long---long interpolation */
1032 
1033           pIcsInfo->WindowShape = 0;
1034           pIcsInfo->WindowSequence = BLOCK_LONG;
1035 
1036           CConcealment_CalcBandEnergy(
1037               pConcealmentInfo->spectralCoefficient, /* spec_n */
1038               pSamplingRateInfo, BLOCK_LONG, CConcealment_NoExpand,
1039               sfbEnergyAct);
1040         }
1041 
1042         CConcealment_InterpolateBuffer(
1043             pSpectralCoefficient, /* spec_(n-1) */
1044             &pSpecScale[0], &specScaleAct, &pSpecScale[0], sfbEnergyPrev,
1045             sfbEnergyAct, scaleFactorBandsTotal, pSfbOffset);
1046       }
1047     }
1048 
1049     /* Noise substitution of sign of the output spectral coefficients */
1050     CConcealment_ApplyRandomSign(pConcealmentInfo->iRandomPhase,
1051                                  pSpectralCoefficient, samplesPerFrame);
1052     /* Increment random phase index to avoid repetition artifacts. */
1053     pConcealmentInfo->iRandomPhase =
1054         (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);
1055   }
1056 
1057   /* scale spectrum according to concealment state */
1058   switch (pConcealmentInfo->concealState) {
1059     case ConcealState_Single:
1060       appliedProcessing = 1;
1061       break;
1062 
1063     case ConcealState_FadeOut: {
1064       FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0);
1065       FDK_ASSERT(pConcealmentInfo->cntFadeFrames <
1066                  CONCEAL_MAX_NUM_FADE_FACTORS);
1067       FDK_ASSERT(pConcealmentInfo->cntFadeFrames <
1068                  pConcealCommonData->numFadeOutFrames);
1069 
1070       /* TimeDomainFading:                                        */
1071       /* Attenuation of signal is done in CConcealment_TDFading() */
1072 
1073       appliedProcessing = 1;
1074     } break;
1075 
1076     case ConcealState_FadeIn: {
1077       FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0);
1078       FDK_ASSERT(pConcealmentInfo->cntFadeFrames <
1079                  CONCEAL_MAX_NUM_FADE_FACTORS);
1080       FDK_ASSERT(pConcealmentInfo->cntFadeFrames <
1081                  pConcealCommonData->numFadeInFrames);
1082 
1083       /* TimeDomainFading:                                        */
1084       /* Attenuation of signal is done in CConcealment_TDFading() */
1085 
1086       appliedProcessing = 1;
1087     } break;
1088 
1089     case ConcealState_Mute: {
1090       /* set dummy window parameters */
1091       pIcsInfo->Valid = 0; /* Trigger the generation of a consitent IcsInfo */
1092       pIcsInfo->WindowShape =
1093           pConcealmentInfo->windowShape; /* Prevent an invalid WindowShape
1094                                             (required for F/T transform) */
1095       pIcsInfo->WindowSequence =
1096           CConcealment_GetWinSeq(pConcealmentInfo->windowSequence);
1097       pConcealmentInfo->windowSequence =
1098           pIcsInfo->WindowSequence; /* Store for next frame
1099                                        (spectrum in concealment
1100                                        buffer can't be used at
1101                                        all) */
1102 
1103       /* mute spectral data */
1104       FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL));
1105 
1106       appliedProcessing = 1;
1107     } break;
1108 
1109     default:
1110       /* nothing to do here */
1111       break;
1112   }
1113 
1114   return appliedProcessing;
1115 }
1116 
1117 /*!
1118   \brief Calculate the spectral energy
1119 
1120   The function calculates band-wise the spectral energy. This is used for
1121   frame interpolation.
1122 */
CConcealment_CalcBandEnergy(FIXP_DBL * spectrum,const SamplingRateInfo * pSamplingRateInfo,const int blockType,CConcealmentExpandType expandType,int * sfbEnergy)1123 static void CConcealment_CalcBandEnergy(
1124     FIXP_DBL *spectrum, const SamplingRateInfo *pSamplingRateInfo,
1125     const int blockType, CConcealmentExpandType expandType, int *sfbEnergy) {
1126   const SHORT *pSfbOffset;
1127   int line, sfb, scaleFactorBandsTotal = 0;
1128 
1129   /* In the following calculations, enAccu is initialized with LSB-value in
1130    * order to avoid zero energy-level */
1131 
1132   line = 0;
1133 
1134   switch (blockType) {
1135     case BLOCK_LONG:
1136     case BLOCK_START:
1137     case BLOCK_STOP:
1138 
1139       if (expandType == CConcealment_NoExpand) {
1140         /* standard long calculation */
1141         scaleFactorBandsTotal =
1142             pSamplingRateInfo->NumberOfScaleFactorBands_Long;
1143         pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long;
1144 
1145         for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
1146           FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
1147           int sfbScale =
1148               (sizeof(LONG) << 3) -
1149               CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1;
1150           /* scaling depends on sfb width. */
1151           for (; line < pSfbOffset[sfb + 1]; line++) {
1152             enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale;
1153           }
1154           *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
1155         }
1156       } else {
1157         /* compress long to short */
1158         scaleFactorBandsTotal =
1159             pSamplingRateInfo->NumberOfScaleFactorBands_Short;
1160         pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short;
1161 
1162         for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
1163           FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
1164           int sfbScale =
1165               (sizeof(LONG) << 3) -
1166               CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1;
1167           /* scaling depends on sfb width. */
1168           for (; line < pSfbOffset[sfb + 1] << 3; line++) {
1169             enAccu +=
1170                 (enAccu + (fPow2Div2(*(spectrum + line)) >> sfbScale)) >> 3;
1171           }
1172           *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
1173         }
1174       }
1175       break;
1176 
1177     case BLOCK_SHORT:
1178 
1179       if (expandType == CConcealment_NoExpand) {
1180         /*   standard short calculation */
1181         scaleFactorBandsTotal =
1182             pSamplingRateInfo->NumberOfScaleFactorBands_Short;
1183         pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short;
1184 
1185         for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
1186           FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
1187           int sfbScale =
1188               (sizeof(LONG) << 3) -
1189               CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1;
1190           /* scaling depends on sfb width. */
1191           for (; line < pSfbOffset[sfb + 1]; line++) {
1192             enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale;
1193           }
1194           *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
1195         }
1196       } else {
1197         /*  expand short to long spectrum */
1198         scaleFactorBandsTotal =
1199             pSamplingRateInfo->NumberOfScaleFactorBands_Long;
1200         pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long;
1201 
1202         for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
1203           FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
1204           int sfbScale =
1205               (sizeof(LONG) << 3) -
1206               CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1;
1207           /* scaling depends on sfb width. */
1208           for (; line < pSfbOffset[sfb + 1]; line++) {
1209             enAccu += fPow2Div2(*(spectrum + (line >> 3))) >> sfbScale;
1210           }
1211           *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
1212         }
1213       }
1214       break;
1215   }
1216 }
1217 
1218 /*!
1219   \brief Interpolate buffer
1220 
1221   The function creates the interpolated spectral data according to the
1222   energy of the last good frame and the current (good) frame.
1223 */
CConcealment_InterpolateBuffer(FIXP_DBL * spectrum,SHORT * pSpecScalePrv,SHORT * pSpecScaleAct,SHORT * pSpecScaleOut,int * enPrv,int * enAct,int sfbCnt,const SHORT * pSfbOffset)1224 static void CConcealment_InterpolateBuffer(FIXP_DBL *spectrum,
1225                                            SHORT *pSpecScalePrv,
1226                                            SHORT *pSpecScaleAct,
1227                                            SHORT *pSpecScaleOut, int *enPrv,
1228                                            int *enAct, int sfbCnt,
1229                                            const SHORT *pSfbOffset) {
1230   int sfb, line = 0;
1231   int fac_shift;
1232   int fac_mod;
1233 
1234   for (sfb = 0; sfb < sfbCnt; sfb++) {
1235     fac_shift =
1236         enPrv[sfb] - enAct[sfb] + ((*pSpecScaleAct - *pSpecScalePrv) << 1);
1237     fac_mod = fac_shift & 3;
1238     fac_shift = (fac_shift >> 2) + 1;
1239     fac_shift += *pSpecScalePrv - fixMax(*pSpecScalePrv, *pSpecScaleAct);
1240     fac_shift = fMax(fMin(fac_shift, DFRACT_BITS - 1), -(DFRACT_BITS - 1));
1241 
1242     for (; line < pSfbOffset[sfb + 1]; line++) {
1243       FIXP_DBL accu = fMult(*(spectrum + line), facMod4Table[fac_mod]);
1244       *(spectrum + line) = scaleValue(accu, fac_shift);
1245     }
1246   }
1247   *pSpecScaleOut = fixMax(*pSpecScalePrv, *pSpecScaleAct);
1248 }
1249 
1250 /*!
1251   \brief Find next fading frame in case of changing fading direction
1252 
1253   \param pConcealCommonData Pointer to the concealment common data structure.
1254   \param actFadeIndex Last index used for fading
1255   \param direction Direction of change: 0 : change from FADE-OUT to FADE-IN,  1
1256   : change from FADE-IN to FADE-OUT
1257 
1258   This function determines the next fading index to be used for the fading
1259   direction to be changed to.
1260 */
1261 
findEquiFadeFrame(CConcealParams * pConcealCommonData,INT actFadeIndex,int direction)1262 static INT findEquiFadeFrame(CConcealParams *pConcealCommonData,
1263                              INT actFadeIndex, int direction) {
1264   FIXP_SGL *pFactor;
1265   FIXP_SGL referenceVal;
1266   FIXP_SGL minDiff = (FIXP_SGL)MAXVAL_SGL;
1267 
1268   INT nextFadeIndex = 0;
1269 
1270   int i;
1271 
1272   /* init depending on direction */
1273   if (direction == 0) { /* FADE-OUT => FADE-IN */
1274     if (actFadeIndex < 0) {
1275       referenceVal = (FIXP_SGL)MAXVAL_SGL;
1276     } else {
1277       referenceVal = pConcealCommonData->fadeOutFactor[actFadeIndex] >> 1;
1278     }
1279     pFactor = pConcealCommonData->fadeInFactor;
1280   } else { /* FADE-IN => FADE-OUT */
1281     if (actFadeIndex < 0) {
1282       referenceVal = (FIXP_SGL)MAXVAL_SGL;
1283     } else {
1284       referenceVal = pConcealCommonData->fadeInFactor[actFadeIndex] >> 1;
1285     }
1286     pFactor = pConcealCommonData->fadeOutFactor;
1287   }
1288 
1289   /* search for minimum difference */
1290   for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
1291     FIXP_SGL diff = fixp_abs((pFactor[i] >> 1) - referenceVal);
1292     if (diff < minDiff) {
1293       minDiff = diff;
1294       nextFadeIndex = i;
1295     }
1296   }
1297 
1298   /* check and adjust depending on direction */
1299   if (direction == 0) { /* FADE-OUT => FADE-IN */
1300     if (nextFadeIndex > pConcealCommonData->numFadeInFrames) {
1301       nextFadeIndex = fMax(pConcealCommonData->numFadeInFrames - 1, 0);
1302     }
1303     if (((pFactor[nextFadeIndex] >> 1) <= referenceVal) &&
1304         (nextFadeIndex > 0)) {
1305       nextFadeIndex -= 1;
1306     }
1307   } else { /* FADE-IN => FADE-OUT */
1308     if (((pFactor[nextFadeIndex] >> 1) >= referenceVal) &&
1309         (nextFadeIndex < CONCEAL_MAX_NUM_FADE_FACTORS - 1)) {
1310       nextFadeIndex += 1;
1311     }
1312   }
1313 
1314   return (nextFadeIndex);
1315 }
1316 
1317 /*!
1318   \brief Update the concealment state
1319 
1320   The function updates the state of the concealment state-machine. The
1321   states are: mute, fade-in, fade-out, interpolate and frame-ok.
1322 */
CConcealment_UpdateState(CConcealmentInfo * pConcealmentInfo,int frameOk,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,const int samplesPerFrame,CAacDecoderChannelInfo * pAacDecoderChannelInfo)1323 static void CConcealment_UpdateState(
1324     CConcealmentInfo *pConcealmentInfo, int frameOk,
1325     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
1326     const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
1327   CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams;
1328 
1329   switch (pConcealCommonData->method) {
1330     case ConcealMethodNoise: {
1331       if (pConcealmentInfo->concealState != ConcealState_Ok) {
1332         /* count the valid frames during concealment process */
1333         if (frameOk) {
1334           pConcealmentInfo->cntValidFrames += 1;
1335         } else {
1336           pConcealmentInfo->cntValidFrames = 0;
1337         }
1338       }
1339 
1340       /* -- STATE MACHINE for Noise Substitution -- */
1341       switch (pConcealmentInfo->concealState) {
1342         case ConcealState_Ok:
1343           if (!frameOk) {
1344             pConcealmentInfo->cntFadeFrames = 0;
1345             pConcealmentInfo->cntValidFrames = 0;
1346             pConcealmentInfo->attGrpOffset[0] = 0;
1347             pConcealmentInfo->attGrpOffset[1] = 0;
1348             pConcealmentInfo->winGrpOffset[0] = 0;
1349             pConcealmentInfo->winGrpOffset[1] = 0;
1350             if (pConcealCommonData->numFadeOutFrames > 0) {
1351               /* change to state SINGLE-FRAME-LOSS */
1352               pConcealmentInfo->concealState = ConcealState_Single;
1353               /* mode 0 just updates the Fading counter */
1354               CConcealment_ApplyFadeOut(
1355                   /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo,
1356                   samplesPerFrame, pAacDecoderChannelInfo);
1357 
1358             } else {
1359               /* change to state MUTE */
1360               pConcealmentInfo->concealState = ConcealState_Mute;
1361             }
1362           }
1363           break;
1364 
1365         case ConcealState_Single: /* Just a pre-stage before fade-out begins.
1366                                      Stay here only one frame! */
1367           if (frameOk) {
1368             /* change to state OK */
1369             pConcealmentInfo->concealState = ConcealState_Ok;
1370           } else {
1371             if (pConcealmentInfo->cntFadeFrames >=
1372                 pConcealCommonData->numFadeOutFrames) {
1373               /* change to state MUTE */
1374               pConcealmentInfo->concealState = ConcealState_Mute;
1375             } else {
1376               /* change to state FADE-OUT */
1377               pConcealmentInfo->concealState = ConcealState_FadeOut;
1378               /* mode 0 just updates the Fading counter */
1379               CConcealment_ApplyFadeOut(
1380                   /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo,
1381                   samplesPerFrame, pAacDecoderChannelInfo);
1382             }
1383           }
1384           break;
1385 
1386         case ConcealState_FadeOut:
1387           if (pConcealmentInfo->cntValidFrames >
1388               pConcealCommonData->numMuteReleaseFrames) {
1389             if (pConcealCommonData->numFadeInFrames > 0) {
1390               /* change to state FADE-IN */
1391               pConcealmentInfo->concealState = ConcealState_FadeIn;
1392               pConcealmentInfo->cntFadeFrames = findEquiFadeFrame(
1393                   pConcealCommonData, pConcealmentInfo->cntFadeFrames,
1394                   0 /* FadeOut -> FadeIn */);
1395             } else {
1396               /* change to state OK */
1397               pConcealmentInfo->concealState = ConcealState_Ok;
1398             }
1399           } else {
1400             if (frameOk) {
1401               /* we have good frame information but stay fully in concealment -
1402                * reset winGrpOffset/attGrpOffset */
1403               pConcealmentInfo->winGrpOffset[0] = 0;
1404               pConcealmentInfo->winGrpOffset[1] = 0;
1405               pConcealmentInfo->attGrpOffset[0] = 0;
1406               pConcealmentInfo->attGrpOffset[1] = 0;
1407             }
1408             if (pConcealmentInfo->cntFadeFrames >=
1409                 pConcealCommonData->numFadeOutFrames) {
1410               /* change to state MUTE */
1411               pConcealmentInfo->concealState = ConcealState_Mute;
1412             } else /* Stay in FADE-OUT */
1413             {
1414               /* mode 0 just updates the Fading counter */
1415               CConcealment_ApplyFadeOut(
1416                   /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo,
1417                   samplesPerFrame, pAacDecoderChannelInfo);
1418             }
1419           }
1420           break;
1421 
1422         case ConcealState_Mute:
1423           if (pConcealmentInfo->cntValidFrames >
1424               pConcealCommonData->numMuteReleaseFrames) {
1425             if (pConcealCommonData->numFadeInFrames > 0) {
1426               /* change to state FADE-IN */
1427               pConcealmentInfo->concealState = ConcealState_FadeIn;
1428               pConcealmentInfo->cntFadeFrames =
1429                   pConcealCommonData->numFadeInFrames - 1;
1430             } else {
1431               /* change to state OK */
1432               pConcealmentInfo->concealState = ConcealState_Ok;
1433             }
1434           } else {
1435             if (frameOk) {
1436               /* we have good frame information but stay fully in concealment -
1437                * reset winGrpOffset/attGrpOffset */
1438               pConcealmentInfo->winGrpOffset[0] = 0;
1439               pConcealmentInfo->winGrpOffset[1] = 0;
1440               pConcealmentInfo->attGrpOffset[0] = 0;
1441               pConcealmentInfo->attGrpOffset[1] = 0;
1442             }
1443           }
1444           break;
1445 
1446         case ConcealState_FadeIn:
1447           pConcealmentInfo->cntFadeFrames -= 1;
1448           if (frameOk) {
1449             if (pConcealmentInfo->cntFadeFrames < 0) {
1450               /* change to state OK */
1451               pConcealmentInfo->concealState = ConcealState_Ok;
1452             }
1453           } else {
1454             if (pConcealCommonData->numFadeOutFrames > 0) {
1455               /* change to state FADE-OUT */
1456               pConcealmentInfo->concealState = ConcealState_FadeOut;
1457               pConcealmentInfo->cntFadeFrames = findEquiFadeFrame(
1458                   pConcealCommonData, pConcealmentInfo->cntFadeFrames + 1,
1459                   1 /* FadeIn -> FadeOut */);
1460               pConcealmentInfo->winGrpOffset[0] = 0;
1461               pConcealmentInfo->winGrpOffset[1] = 0;
1462               pConcealmentInfo->attGrpOffset[0] = 0;
1463               pConcealmentInfo->attGrpOffset[1] = 0;
1464 
1465               pConcealmentInfo
1466                   ->cntFadeFrames--; /* decrease because
1467                                         CConcealment_ApplyFadeOut() will
1468                                         increase, accordingly */
1469               /* mode 0 just updates the Fading counter */
1470               CConcealment_ApplyFadeOut(
1471                   /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo,
1472                   samplesPerFrame, pAacDecoderChannelInfo);
1473             } else {
1474               /* change to state MUTE */
1475               pConcealmentInfo->concealState = ConcealState_Mute;
1476             }
1477           }
1478           break;
1479 
1480         default:
1481           FDK_ASSERT(0);
1482           break;
1483       }
1484     } break;
1485 
1486     case ConcealMethodInter:
1487     case ConcealMethodTonal: {
1488       if (pConcealmentInfo->concealState != ConcealState_Ok) {
1489         /* count the valid frames during concealment process */
1490         if (pConcealmentInfo->prevFrameOk[1] ||
1491             (pConcealmentInfo->prevFrameOk[0] &&
1492              !pConcealmentInfo->prevFrameOk[1] && frameOk)) {
1493           /* The frame is OK even if it can be estimated by the energy
1494            * interpolation algorithm */
1495           pConcealmentInfo->cntValidFrames += 1;
1496         } else {
1497           pConcealmentInfo->cntValidFrames = 0;
1498         }
1499       }
1500 
1501       /* -- STATE MACHINE for energy interpolation -- */
1502       switch (pConcealmentInfo->concealState) {
1503         case ConcealState_Ok:
1504           if (!(pConcealmentInfo->prevFrameOk[1] ||
1505                 (pConcealmentInfo->prevFrameOk[0] &&
1506                  !pConcealmentInfo->prevFrameOk[1] && frameOk))) {
1507             if (pConcealCommonData->numFadeOutFrames > 0) {
1508               /* Fade out only if the energy interpolation algorithm can not be
1509                * applied! */
1510               pConcealmentInfo->concealState = ConcealState_FadeOut;
1511             } else {
1512               /* change to state MUTE */
1513               pConcealmentInfo->concealState = ConcealState_Mute;
1514             }
1515             pConcealmentInfo->cntFadeFrames = 0;
1516             pConcealmentInfo->cntValidFrames = 0;
1517           }
1518           break;
1519 
1520         case ConcealState_Single:
1521           pConcealmentInfo->concealState = ConcealState_Ok;
1522           break;
1523 
1524         case ConcealState_FadeOut:
1525           pConcealmentInfo->cntFadeFrames += 1;
1526 
1527           if (pConcealmentInfo->cntValidFrames >
1528               pConcealCommonData->numMuteReleaseFrames) {
1529             if (pConcealCommonData->numFadeInFrames > 0) {
1530               /* change to state FADE-IN */
1531               pConcealmentInfo->concealState = ConcealState_FadeIn;
1532               pConcealmentInfo->cntFadeFrames = findEquiFadeFrame(
1533                   pConcealCommonData, pConcealmentInfo->cntFadeFrames - 1,
1534                   0 /* FadeOut -> FadeIn */);
1535             } else {
1536               /* change to state OK */
1537               pConcealmentInfo->concealState = ConcealState_Ok;
1538             }
1539           } else {
1540             if (pConcealmentInfo->cntFadeFrames >=
1541                 pConcealCommonData->numFadeOutFrames) {
1542               /* change to state MUTE */
1543               pConcealmentInfo->concealState = ConcealState_Mute;
1544             }
1545           }
1546           break;
1547 
1548         case ConcealState_Mute:
1549           if (pConcealmentInfo->cntValidFrames >
1550               pConcealCommonData->numMuteReleaseFrames) {
1551             if (pConcealCommonData->numFadeInFrames > 0) {
1552               /* change to state FADE-IN */
1553               pConcealmentInfo->concealState = ConcealState_FadeIn;
1554               pConcealmentInfo->cntFadeFrames =
1555                   pConcealCommonData->numFadeInFrames - 1;
1556             } else {
1557               /* change to state OK */
1558               pConcealmentInfo->concealState = ConcealState_Ok;
1559             }
1560           }
1561           break;
1562 
1563         case ConcealState_FadeIn:
1564           pConcealmentInfo->cntFadeFrames -=
1565               1; /* used to address the fade-in factors */
1566 
1567           if (frameOk || pConcealmentInfo->prevFrameOk[1]) {
1568             if (pConcealmentInfo->cntFadeFrames < 0) {
1569               /* change to state OK */
1570               pConcealmentInfo->concealState = ConcealState_Ok;
1571             }
1572           } else {
1573             if (pConcealCommonData->numFadeOutFrames > 0) {
1574               /* change to state FADE-OUT */
1575               pConcealmentInfo->concealState = ConcealState_FadeOut;
1576               pConcealmentInfo->cntFadeFrames = findEquiFadeFrame(
1577                   pConcealCommonData, pConcealmentInfo->cntFadeFrames + 1,
1578                   1 /* FadeIn -> FadeOut */);
1579             } else {
1580               /* change to state MUTE */
1581               pConcealmentInfo->concealState = ConcealState_Mute;
1582             }
1583           }
1584           break;
1585       } /* End switch(pConcealmentInfo->concealState) */
1586     } break;
1587 
1588     default:
1589       /* Don't need a state machine for other concealment methods. */
1590       break;
1591   }
1592 }
1593 
1594 /*!
1595 \brief Randomizes the sign of the spectral data
1596 
1597   The function toggles the sign of the spectral data randomly. This is
1598   useful to ensure the quality of the concealed frames.
1599  */
CConcealment_ApplyRandomSign(int randomPhase,FIXP_DBL * spec,int samplesPerFrame)1600 static void CConcealment_ApplyRandomSign(int randomPhase, FIXP_DBL *spec,
1601                                          int samplesPerFrame) {
1602   int i;
1603   USHORT packedSign = 0;
1604 
1605   /* random table 512x16bit has been reduced to 512 packed sign bits = 32x16 bit
1606    */
1607 
1608   /* read current packed sign word */
1609   packedSign = AacDec_randomSign[randomPhase >> 4];
1610   packedSign >>= (randomPhase & 0xf);
1611 
1612   for (i = 0; i < samplesPerFrame; i++) {
1613     if ((randomPhase & 0xf) == 0) {
1614       packedSign = AacDec_randomSign[randomPhase >> 4];
1615     }
1616 
1617     if (packedSign & 0x1) {
1618       spec[i] = -fMax(spec[i], (FIXP_DBL)(MINVAL_DBL + 1));
1619     }
1620     packedSign >>= 1;
1621 
1622     randomPhase = (randomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);
1623   }
1624 }
1625 
1626 /*!
1627   \brief Get fadeing factor for current concealment state.
1628 
1629   The function returns the state (ok or not) of the previous frame.
1630   If called before the function CConcealment_Apply() set the fBeforeApply
1631   flag to get the correct value.
1632 
1633   \return Frame OK flag of previous frame.
1634  */
CConcealment_GetLastFrameOk(CConcealmentInfo * hConcealmentInfo,const int fBeforeApply)1635 int CConcealment_GetLastFrameOk(CConcealmentInfo *hConcealmentInfo,
1636                                 const int fBeforeApply) {
1637   int prevFrameOk = 1;
1638 
1639   if (hConcealmentInfo != NULL) {
1640     prevFrameOk = hConcealmentInfo->prevFrameOk[fBeforeApply & 0x1];
1641   }
1642 
1643   return prevFrameOk;
1644 }
1645 
1646 /*!
1647   \brief Get the number of delay frames introduced by concealment technique.
1648 
1649   \return Number of delay frames.
1650  */
CConcealment_GetDelay(CConcealParams * pConcealCommonData)1651 UINT CConcealment_GetDelay(CConcealParams *pConcealCommonData) {
1652   UINT frameDelay = 0;
1653 
1654   if (pConcealCommonData != NULL) {
1655     switch (pConcealCommonData->method) {
1656       case ConcealMethodTonal:
1657       case ConcealMethodInter:
1658         frameDelay = 1;
1659         break;
1660       default:
1661         break;
1662     }
1663   }
1664 
1665   return frameDelay;
1666 }
1667 
CConcealment_ApplyFadeOut(int mode,CConcealmentInfo * pConcealmentInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,const int samplesPerFrame,CAacDecoderChannelInfo * pAacDecoderChannelInfo)1668 static int CConcealment_ApplyFadeOut(
1669     int mode, CConcealmentInfo *pConcealmentInfo,
1670     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
1671     const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
1672   /* mode 1 = apply RandomSign and mute spectral coefficients if necessary,  *
1673    * mode 0 = Update cntFadeFrames                                            */
1674 
1675   /* restore frequency coefficients from buffer with a specific muting */
1676   int srcWin, dstWin, numWindows = 1;
1677   int windowLen = samplesPerFrame;
1678   int srcGrpStart = 0;
1679   int winIdxStride = 1;
1680   int numWinGrpPerFac, attIdx, attIdxStride;
1681   int i;
1682   int appliedProcessing = 0;
1683 
1684   CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
1685   FIXP_DBL *pSpectralCoefficient =
1686       SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
1687   SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
1688 
1689   /* set old window parameters */
1690   if (pConcealmentInfo->lastRenderMode == AACDEC_RENDER_LPD) {
1691     switch (pAacDecoderStaticChannelInfo->last_lpd_mode) {
1692       case 1:
1693         numWindows = 4;
1694         srcGrpStart = 3;
1695         windowLen = samplesPerFrame >> 2;
1696         break;
1697       case 2:
1698         numWindows = 2;
1699         srcGrpStart = 1;
1700         windowLen = samplesPerFrame >> 1;
1701         winIdxStride = 2;
1702         break;
1703       case 3:
1704         numWindows = 1;
1705         srcGrpStart = 0;
1706         windowLen = samplesPerFrame;
1707         winIdxStride = 4;
1708         break;
1709     }
1710     pConcealmentInfo->lastWinGrpLen = 1;
1711   } else {
1712     pIcsInfo->WindowShape = pConcealmentInfo->windowShape;
1713     pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence;
1714 
1715     if (pConcealmentInfo->windowSequence == BLOCK_SHORT) {
1716       /* short block handling */
1717       numWindows = 8;
1718       windowLen = samplesPerFrame >> 3;
1719       srcGrpStart = numWindows - pConcealmentInfo->lastWinGrpLen;
1720     }
1721   }
1722 
1723   attIdxStride =
1724       fMax(1, (int)(numWindows / (pConcealmentInfo->lastWinGrpLen + 1)));
1725 
1726   /* load last state */
1727   attIdx = pConcealmentInfo->cntFadeFrames;
1728   numWinGrpPerFac = pConcealmentInfo->attGrpOffset[mode];
1729   srcWin = srcGrpStart + pConcealmentInfo->winGrpOffset[mode];
1730 
1731   FDK_ASSERT((srcGrpStart * windowLen + windowLen) <= samplesPerFrame);
1732   FDK_ASSERT((srcWin * windowLen + windowLen) <= 1024);
1733 
1734   for (dstWin = 0; dstWin < numWindows; dstWin += 1) {
1735     FIXP_CNCL *pCncl =
1736         pConcealmentInfo->spectralCoefficient + (srcWin * windowLen);
1737     FIXP_DBL *pOut = pSpectralCoefficient + (dstWin * windowLen);
1738 
1739     if (mode == 1) {
1740       /* mute if attIdx gets large enaugh */
1741       if (attIdx > pConcealmentInfo->pConcealParams->numFadeOutFrames) {
1742         FDKmemclear(pCncl, sizeof(FIXP_DBL) * windowLen);
1743       }
1744 
1745       /* restore frequency coefficients from buffer - attenuation is done later
1746        */
1747       for (i = 0; i < windowLen; i++) {
1748         pOut[i] = pCncl[i];
1749       }
1750 
1751       /* apply random change of sign for spectral coefficients */
1752       CConcealment_ApplyRandomSign(pConcealmentInfo->iRandomPhase, pOut,
1753                                    windowLen);
1754 
1755       /* Increment random phase index to avoid repetition artifacts. */
1756       pConcealmentInfo->iRandomPhase =
1757           (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);
1758 
1759       /* set old scale factors */
1760       pSpecScale[dstWin * winIdxStride] =
1761           pConcealmentInfo->specScale[srcWin * winIdxStride];
1762     }
1763 
1764     srcWin += 1;
1765 
1766     if (srcWin >= numWindows) {
1767       /* end of sequence -> rewind to first window of group */
1768       srcWin = srcGrpStart;
1769       numWinGrpPerFac += 1;
1770       if (numWinGrpPerFac >= attIdxStride) {
1771         numWinGrpPerFac = 0;
1772         attIdx += 1;
1773       }
1774     }
1775   }
1776 
1777   /* store current state */
1778 
1779   pConcealmentInfo->winGrpOffset[mode] = srcWin - srcGrpStart;
1780   FDK_ASSERT((pConcealmentInfo->winGrpOffset[mode] >= 0) &&
1781              (pConcealmentInfo->winGrpOffset[mode] < 8));
1782   pConcealmentInfo->attGrpOffset[mode] = numWinGrpPerFac;
1783   FDK_ASSERT((pConcealmentInfo->attGrpOffset[mode] >= 0) &&
1784              (pConcealmentInfo->attGrpOffset[mode] < attIdxStride));
1785 
1786   if (mode == 0) {
1787     pConcealmentInfo->cntFadeFrames = attIdx;
1788   }
1789 
1790   appliedProcessing = 1;
1791 
1792   return appliedProcessing;
1793 }
1794 
1795 /*!
1796   \brief Do Time domain fading (TDFading) in concealment case
1797 
1798   In case of concealment, this function takes care of the fading, after time
1799 domain signal has been rendered by the respective signal rendering functions.
1800   The fading out in case of ACELP decoding is not done by this function but by
1801 the ACELP decoder for the first concealed frame if CONCEAL_CORE_IGNORANT_FADE is
1802 not set.
1803 
1804   TimeDomain fading never creates jumps in energy / discontinuities, it always
1805 does a continuous fading. To achieve this, fading is always done from a starting
1806 point to a target point, while the starting point is always determined to be the
1807 last target point. By varying the target point of a fading, the fading slope can
1808 be controlled.
1809 
1810   This principle is applied to the fading within a frame and the fading from
1811 frame to frame.
1812 
1813   One frame is divided into 8 subframes to obtain 8 parts of fading slopes
1814 within a frame, each maybe with its own gradient.
1815 
1816   Workflow:
1817   1.) Determine Fading behavior and end-of-frame target fading level, based on
1818 concealmentState (determined by CConcealment_UpdateState()) and the core mode.
1819         - By _DEFAULT_,
1820           The target fading level is determined by fadeOutFactor[cntFadeFrames]
1821 in case of fadeOut, or fadeInFactor[cntFadeFrames] in case of fadeIn.
1822           --> fading type is FADE_TIMEDOMAIN in this case. Target fading level
1823 is determined by fading index cntFadeFrames.
1824 
1825         - If concealmentState is signalling a _MUTED SIGNAL_,
1826           TDFading decays to 0 within 1/8th of a frame if numFadeOutFrames == 0.
1827           --> fading type is FADE_TIMEDOMAIN_TOSPECTRALMUTE in this case.
1828 
1829         - If concealmentState is signalling the _END OF MUTING_,
1830           TDFading fades to target fading level within 1/8th of a frame if
1831 numFadeInFrames == 0.
1832           --> fading type is FADE_TIMEDOMAIN_FROMSPECTRALMUTE in this case.
1833 Target fading level is determined by fading index cntFadeFrames.
1834 
1835 #ifndef CONCEAL_CORE_IGNORANT_FADE
1836         - In case of an _ACELP FADEOUT_,
1837           TDFading leaves fading control to ACELP decoder for 1/2 frame.
1838           --> fading type is FADE_ACELPDOMAIN in this case.
1839 #endif
1840 
1841   2.) Render fading levels within current frame and do the final fading:
1842       Map Fading slopes to fading levels and apply to time domain signal.
1843 
1844 
1845 */
1846 
CConcealment_TDFading(int len,CAacDecoderStaticChannelInfo ** ppAacDecoderStaticChannelInfo,const INT aacOutDataHeadroom,PCM_DEC * pcmdata,PCM_DEC * pcmdata_1)1847 INT CConcealment_TDFading(
1848     int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo,
1849     const INT aacOutDataHeadroom, PCM_DEC *pcmdata, PCM_DEC *pcmdata_1) {
1850   /*
1851   Do the fading in Time domain based on concealment states and core mode
1852   */
1853   FIXP_DBL fadeStop, attMute = (FIXP_DBL)0;
1854   int idx = 0, ii;
1855   CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo =
1856       *ppAacDecoderStaticChannelInfo;
1857   CConcealmentInfo *pConcealmentInfo =
1858       &pAacDecoderStaticChannelInfo->concealmentInfo;
1859   CConcealParams *pConcealParams = pConcealmentInfo->pConcealParams;
1860   const CConcealmentState concealState = pConcealmentInfo->concealState;
1861   TDfadingType fadingType;
1862   FIXP_DBL fadingStations[9] = {0};
1863   int fadingSteps[8] = {0};
1864   const FIXP_DBL fadeStart =
1865       pConcealmentInfo
1866           ->fade_old; /* start fading at last end-of-frame attenuation */
1867   FIXP_SGL *fadeFactor = pConcealParams->fadeOutFactor;
1868   const INT cntFadeFrames = pConcealmentInfo->cntFadeFrames;
1869   int TDFadeOutStopBeforeMute = 1;
1870   int TDFadeInStopBeforeFullLevel = 1;
1871 
1872   /*
1873   determine Fading behaviour (end-of-frame attenuation and fading type) (1.)
1874   */
1875 
1876   switch (concealState) {
1877     case ConcealState_Single:
1878     case ConcealState_Mute:
1879     case ConcealState_FadeOut:
1880       idx = (pConcealParams->method == ConcealMethodNoise) ? cntFadeFrames - 1
1881                                                            : cntFadeFrames;
1882       fadingType = FADE_TIMEDOMAIN;
1883 
1884       if (concealState == ConcealState_Mute ||
1885           (cntFadeFrames + TDFadeOutStopBeforeMute) >
1886               pConcealmentInfo->pConcealParams->numFadeOutFrames) {
1887         fadingType = FADE_TIMEDOMAIN_TOSPECTRALMUTE;
1888       }
1889 
1890       break;
1891     case ConcealState_FadeIn:
1892       idx = cntFadeFrames;
1893       idx -= TDFadeInStopBeforeFullLevel;
1894       FDK_FALLTHROUGH;
1895     case ConcealState_Ok:
1896       fadeFactor = pConcealParams->fadeInFactor;
1897       idx = (concealState == ConcealState_Ok) ? -1 : idx;
1898       fadingType = (pConcealmentInfo->concealState_old == ConcealState_Mute)
1899                        ? FADE_TIMEDOMAIN_FROMSPECTRALMUTE
1900                        : FADE_TIMEDOMAIN;
1901       break;
1902     default:
1903       FDK_ASSERT(0);
1904       fadingType = FADE_TIMEDOMAIN_TOSPECTRALMUTE;
1905       break;
1906   }
1907 
1908   /* determine Target end-of-frame fading level and fading slope */
1909   switch (fadingType) {
1910     case FADE_TIMEDOMAIN_FROMSPECTRALMUTE:
1911       fadeStop =
1912           (idx < 0) ? (FIXP_DBL)MAXVAL_DBL : FX_SGL2FX_DBL(fadeFactor[idx]);
1913       if (pConcealmentInfo->pConcealParams->numFadeInFrames == 0) {
1914         /* do step as fast as possible */
1915         fadingSteps[0] = 1;
1916         break;
1917       }
1918       CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]);
1919       break;
1920     case FADE_TIMEDOMAIN:
1921       fadeStop =
1922           (idx < 0) ? (FIXP_DBL)MAXVAL_DBL : FX_SGL2FX_DBL(fadeFactor[idx]);
1923       CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]);
1924       break;
1925     case FADE_TIMEDOMAIN_TOSPECTRALMUTE:
1926       fadeStop = attMute;
1927       if (pConcealmentInfo->pConcealParams->numFadeOutFrames == 0) {
1928         /* do step as fast as possible */
1929         fadingSteps[0] = 1;
1930         break;
1931       }
1932       CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]);
1933       break;
1934   }
1935 
1936   /*
1937   Render fading levels within current frame and do the final fading (2.)
1938   */
1939 
1940   len >>= 3;
1941   CConcealment_TDFadeFillFadingStations(fadingStations, fadingSteps, fadeStop,
1942                                         fadeStart, fadingType);
1943 
1944   if ((fadingStations[8] != (FIXP_DBL)MAXVAL_DBL) ||
1945       (fadingStations[7] != (FIXP_DBL)MAXVAL_DBL) ||
1946       (fadingStations[6] != (FIXP_DBL)MAXVAL_DBL) ||
1947       (fadingStations[5] != (FIXP_DBL)MAXVAL_DBL) ||
1948       (fadingStations[4] != (FIXP_DBL)MAXVAL_DBL) ||
1949       (fadingStations[3] != (FIXP_DBL)MAXVAL_DBL) ||
1950       (fadingStations[2] != (FIXP_DBL)MAXVAL_DBL) ||
1951       (fadingStations[1] != (FIXP_DBL)MAXVAL_DBL) ||
1952       (fadingStations[0] !=
1953        (FIXP_DBL)MAXVAL_DBL)) /* if there's something to fade */
1954   {
1955     int start = 0;
1956     for (ii = 0; ii < 8; ii++) {
1957       CConcealment_TDFadePcmAtt(start, len, fadingStations[ii],
1958                                 fadingStations[ii + 1], pcmdata);
1959       start += len;
1960     }
1961   }
1962   CConcealment_TDNoise_Apply(pConcealmentInfo, len, aacOutDataHeadroom,
1963                              pcmdata);
1964 
1965   /* Save end-of-frame attenuation and fading type */
1966   pConcealmentInfo->lastFadingType = fadingType;
1967   pConcealmentInfo->fade_old = fadeStop;
1968   pConcealmentInfo->concealState_old = concealState;
1969 
1970   return 1;
1971 }
1972 
1973 /* attenuate pcmdata in Time Domain Fading process */
CConcealment_TDFadePcmAtt(int start,int len,FIXP_DBL fadeStart,FIXP_DBL fadeStop,PCM_DEC * pcmdata)1974 static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart,
1975                                       FIXP_DBL fadeStop, PCM_DEC *pcmdata) {
1976   int i;
1977   FIXP_DBL dStep;
1978   FIXP_DBL dGain;
1979   FIXP_DBL dGain_apply;
1980 
1981   /* set start energy */
1982   dGain = fadeStart;
1983   /* determine energy steps from sample to sample */
1984   dStep = (FIXP_DBL)((int)((fadeStart >> 1) - (fadeStop >> 1)) / len) << 1;
1985 
1986   for (i = start; i < (start + len); i++) {
1987     dGain -= dStep;
1988     /* prevent gain from getting negative due to possible fixpoint inaccuracies
1989      */
1990     dGain_apply = fMax((FIXP_DBL)0, dGain);
1991     /* finally, attenuate samples */
1992     pcmdata[i] = FIXP_DBL2PCM_DEC(fMult(pcmdata[i], dGain_apply));
1993   }
1994 }
1995 
1996 /*
1997 \brief Fill FadingStations
1998 
1999 The fadingstations are the attenuation factors, being applied to its dedicated
2000 portions of pcm data. They are calculated using the fadingsteps. One fadingstep
2001 is the weighted contribution to the fading slope within its dedicated portion of
2002 pcm data.
2003 
2004 *Fadingsteps  :      0  0  0  1  0  1  2  0
2005 
2006                   |<-  1 Frame pcm data ->|
2007       fadeStart-->|__________             |
2008                   ^  ^  ^  ^ \____        |
2009  Attenuation  :   |  |  |  |  ^  ^\__     |
2010                   |  |  |  |  |  |  ^\    |
2011                   |  |  |  |  |  |  | \___|<-- fadeStop
2012                   |  |  |  |  |  |  |  ^  ^
2013                   |  |  |  |  |  |  |  |  |
2014 Fadingstations:  [0][1][2][3][4][5][6][7][8]
2015 
2016 (Fadingstations "[0]" is "[8] from previous frame", therefore its not meaningful
2017 to be edited)
2018 
2019 */
CConcealment_TDFadeFillFadingStations(FIXP_DBL * fadingStations,int * fadingSteps,FIXP_DBL fadeStop,FIXP_DBL fadeStart,TDfadingType fadingType)2020 static void CConcealment_TDFadeFillFadingStations(FIXP_DBL *fadingStations,
2021                                                   int *fadingSteps,
2022                                                   FIXP_DBL fadeStop,
2023                                                   FIXP_DBL fadeStart,
2024                                                   TDfadingType fadingType) {
2025   int i;
2026   INT fadingSteps_sum = 0;
2027   INT fadeDiff;
2028 
2029   fadingSteps_sum = fadingSteps[0] + fadingSteps[1] + fadingSteps[2] +
2030                     fadingSteps[3] + fadingSteps[4] + fadingSteps[5] +
2031                     fadingSteps[6] + fadingSteps[7];
2032   fadeDiff = ((INT)(fadeStop - fadeStart) / fMax(fadingSteps_sum, (INT)1));
2033   fadingStations[0] = fadeStart;
2034   for (i = 1; i < 8; i++) {
2035     fadingStations[i] =
2036         fadingStations[i - 1] + (FIXP_DBL)(fadeDiff * fadingSteps[i - 1]);
2037   }
2038   fadingStations[8] = fadeStop;
2039 }
2040 
CConcealment_TDFading_doLinearFadingSteps(int * fadingSteps)2041 static void CConcealment_TDFading_doLinearFadingSteps(int *fadingSteps) {
2042   fadingSteps[0] = fadingSteps[1] = fadingSteps[2] = fadingSteps[3] =
2043       fadingSteps[4] = fadingSteps[5] = fadingSteps[6] = fadingSteps[7] = 1;
2044 }
2045 
2046 /* end of TimeDomainFading functions */
2047 
2048 /* derived from int UsacRandomSign() */
CConcealment_TDNoise_Random(ULONG * seed)2049 static int CConcealment_TDNoise_Random(ULONG *seed) {
2050   *seed = (ULONG)(((UINT64)(*seed) * 69069) + 5);
2051   return (int)(*seed);
2052 }
2053 
CConcealment_TDNoise_Apply(CConcealmentInfo * const pConcealmentInfo,const int len,const INT aacOutDataHeadroom,PCM_DEC * const pcmdata)2054 static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo,
2055                                        const int len,
2056                                        const INT aacOutDataHeadroom,
2057                                        PCM_DEC *const pcmdata) {
2058   PCM_DEC *states = pConcealmentInfo->TDNoiseStates;
2059   PCM_DEC noiseVal;
2060   FIXP_DBL noiseValLong;
2061   FIXP_SGL *coef = pConcealmentInfo->TDNoiseCoef;
2062   FIXP_DBL TDNoiseAtt;
2063   ULONG seed = pConcealmentInfo->TDNoiseSeed =
2064       (ULONG)CConcealment_TDNoise_Random(&pConcealmentInfo->TDNoiseSeed) + 1;
2065 
2066   TDNoiseAtt = pConcealmentInfo->pConcealParams->comfortNoiseLevel;
2067 
2068   int ii;
2069 
2070   if ((pConcealmentInfo->concealState != ConcealState_Ok ||
2071        pConcealmentInfo->concealState_old != ConcealState_Ok) &&
2072       TDNoiseAtt != (FIXP_DBL)0) {
2073     for (ii = 0; ii < (len << 3); ii++) {
2074       /* create filtered noise */
2075       states[2] = states[1];
2076       states[1] = states[0];
2077       states[0] =
2078           FIXP_DBL2PCM_DEC((FIXP_DBL)CConcealment_TDNoise_Random(&seed));
2079       noiseValLong = fMult(states[0], coef[0]) + fMult(states[1], coef[1]) +
2080                      fMult(states[2], coef[2]);
2081       noiseVal = FIXP_DBL2PCM_DEC(fMult(noiseValLong, TDNoiseAtt) >>
2082                                   aacOutDataHeadroom);
2083 
2084       /* add filtered noise - check for clipping, before */
2085       if (noiseVal > (PCM_DEC)0 &&
2086           pcmdata[ii] > (PCM_DEC)MAXVAL_PCM_DEC - noiseVal) {
2087         noiseVal = noiseVal * (PCM_DEC)-1;
2088       } else if (noiseVal < (PCM_DEC)0 &&
2089                  pcmdata[ii] < (PCM_DEC)MINVAL_PCM_DEC - noiseVal) {
2090         noiseVal = noiseVal * (PCM_DEC)-1;
2091       }
2092 
2093       pcmdata[ii] += noiseVal;
2094     }
2095   }
2096 }
2097