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