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