2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
5 © Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16 of the MPEG specifications.
18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27 applications information and documentation.
31 Redistribution and use in source and binary forms, with or without modification, are permitted without
32 payment of copyright license fees provided that you satisfy the following conditions:
34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35 your modifications thereto in source code form.
37 You must retain the complete text of this software license in the documentation and/or other materials
38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40 modifications thereto to recipients of copies in binary form.
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46 software or your modifications thereto.
48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49 and the date of any change. For modified versions of the FDK AAC Codec, the term
50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57 respect to this software.
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69 or business interruption, however caused and on any theory of liability, whether in contract, strict
70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
71 advised of the possibility of such damage.
73 5. CONTACT INFORMATION
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
78 91058 Erlangen, Germany
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
84 /***************************** MPEG-4 AAC Decoder **************************
86 Author(s): Josef Hoepfl
87 Description: independent channel concealment
89 ******************************************************************************/
92 \page concealment AAC core concealment
94 This AAC core implementation includes a concealment function, which can be enabled
95 using the several defines during compilation.
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.
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.
105 There are three concealment-modes:
107 1) Muting: The spectral data is simply set to zero in case of an detected error.
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.
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.
124 <h2>How concealment can be used with errors on the transport layer</h2>
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.
134 #include "genericStds.h"
138 #include "aacdec_pns.h"
141 #include "FDK_tools_rom.h"
143 #define CONCEAL_DFLT_COMF_NOISE_LEVEL ( 46 ) /* ~= -70 dB */
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 )
151 #define CONCEAL_DFLT_FADE_FACTOR ( 0.707106781186548f ) /* 1/sqrt(2) */
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)
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)
167 CConcealment_NoExpand
,
169 CConcealment_Compress
171 CConcealmentExpandType
;
173 static const FIXP_SGL facMod4Table
[4] = {
174 FL2FXCONST_SGL(0.500000000f
), /* FIXP_SGL(0x4000), 2^-(1-0,00) */
175 FL2FXCONST_SGL(0.594603558f
), /* FIXP_SGL(0x4c1b), 2^-(1-0,25) */
176 FL2FXCONST_SGL(0.707106781f
), /* FIXP_SGL(0x5a82), 2^-(1-0,50) */
177 FL2FXCONST_SGL(0.840896415f
) /* FIXP_SGL(0x6ba2) 2^-(1-0,75) */
184 CConcealment_CalcBandEnergy (
186 const SamplingRateInfo
*pSamplingRateInfo
,
188 CConcealmentExpandType ex
,
193 CConcealment_InterpolateBuffer (
195 SHORT
*pSpecScalePrev
,
196 SHORT
*pSpecScaleAct
,
197 SHORT
*pSpecScaleOut
,
201 const SHORT
*pSfbOffset
205 CConcealment_ApplyInter (
206 CConcealmentInfo
*pConcealmentInfo
,
207 CAacDecoderChannelInfo
*pAacDecoderChannelInfo
,
208 const SamplingRateInfo
*pSamplingRateInfo
,
209 const int samplesPerFrame
,
210 const int improveTonal
,
217 CConcealment_ApplyNoise (
218 CConcealmentInfo
*pConcealmentInfo
,
219 CAacDecoderChannelInfo
*pAacDecoderChannelInfo
,
220 CAacDecoderStaticChannelInfo
*pAacDecoderStaticChannelInfo
,
221 const SamplingRateInfo
*pSamplingRateInfo
,
222 const int samplesPerFrame
,
227 CConcealment_UpdateState (
228 CConcealmentInfo
*pConcealmentInfo
,
233 CConcealment_ApplyRandomSign (
240 static int CConcealment_GetWinSeq(int prevWinSeq
)
242 int newWinSeq
= OnlyLongSequence
;
244 /* Try to have only long blocks */
245 if ( prevWinSeq
== LongStartSequence
246 || prevWinSeq
== EightShortSequence
)
248 newWinSeq
= LongStopSequence
;
256 \brief Init common concealment information data
258 \pConcealCommonData Pointer to the concealment common data structure.
263 CConcealment_InitCommonData (CConcealParams
*pConcealCommonData
)
265 if (pConcealCommonData
!= NULL
)
269 /* Set default error concealment technique */
270 pConcealCommonData
->method
= ConcealMethodInter
;
272 pConcealCommonData
->numFadeOutFrames
= CONCEAL_DFLT_FADEOUT_FRAMES
;
273 pConcealCommonData
->numFadeInFrames
= CONCEAL_DFLT_FADEIN_FRAMES
;
274 pConcealCommonData
->numMuteReleaseFrames
= CONCEAL_DFLT_MUTE_RELEASE_FRAMES
;
276 pConcealCommonData
->comfortNoiseLevel
= CONCEAL_DFLT_COMF_NOISE_LEVEL
;
278 /* Init fade factors (symetric) */
279 pConcealCommonData
->fadeOutFactor
[0] = FL2FXCONST_SGL( CONCEAL_DFLT_FADE_FACTOR
);
280 pConcealCommonData
->fadeInFactor
[0] = pConcealCommonData
->fadeOutFactor
[0];
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
];
292 \brief Get current concealment method.
294 \pConcealCommonData Pointer to common concealment data (for all channels)
296 \return Concealment method.
299 CConcealment_GetMethod( CConcealParams
*pConcealCommonData
)
301 CConcealmentMethod method
= ConcealMethodNone
;
303 if (pConcealCommonData
!= NULL
) {
304 method
= pConcealCommonData
->method
;
312 \brief Init concealment information for each channel
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)
321 CConcealment_InitChannelData (
322 CConcealmentInfo
*pConcealChannelInfo
,
323 CConcealParams
*pConcealCommonData
,
324 int samplesPerFrame
)
328 pConcealChannelInfo
->pConcealParams
= pConcealCommonData
;
330 FDKmemclear(pConcealChannelInfo
->spectralCoefficient
, 1024 * sizeof(FIXP_CNCL
));
332 for (i
= 0; i
< 8; i
++) {
333 pConcealChannelInfo
->specScale
[i
] = 0;
336 pConcealChannelInfo
->iRandomPhase
= 0;
338 pConcealChannelInfo
->windowSequence
= 0;
339 pConcealChannelInfo
->windowShape
= 0;
341 pConcealChannelInfo
->prevFrameOk
[0] = 1;
342 pConcealChannelInfo
->prevFrameOk
[1] = 1;
344 pConcealChannelInfo
->cntFadeFrames
= 0;
345 pConcealChannelInfo
->cntValidFrames
= 0;
347 pConcealChannelInfo
->concealState
= ConcealState_Ok
;
353 \brief Set error concealment parameters
365 CConcealment_SetParams (
366 CConcealParams
*concealParams
,
373 /* set concealment technique */
374 if (method
!= AACDEC_CONCEAL_PARAM_NOT_SPECIFIED
) {
375 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
;
385 concealParams
->method
= (CConcealmentMethod
)method
;
390 return AAC_DEC_SET_PARAM_FAIL
;
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) )
399 if (concealParams
== NULL
) {
400 return AAC_DEC_INVALID_HANDLE
;
403 concealParams
->numFadeOutFrames
= fadeOutSlope
;
406 return AAC_DEC_SET_PARAM_FAIL
;
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) )
415 if (concealParams
== NULL
) {
416 return AAC_DEC_INVALID_HANDLE
;
419 concealParams
->numFadeInFrames
= fadeInSlope
;
422 return AAC_DEC_SET_PARAM_FAIL
;
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) )
431 if (concealParams
== NULL
) {
432 return AAC_DEC_INVALID_HANDLE
;
435 concealParams
->numMuteReleaseFrames
= muteRelease
;
438 return AAC_DEC_SET_PARAM_FAIL
;
442 /* set confort noise level which will be inserted while in state 'muting' */
443 if (comfNoiseLevel
!= AACDEC_CONCEAL_PARAM_NOT_SPECIFIED
) {
444 if ( (comfNoiseLevel
< -1)
445 || (comfNoiseLevel
> 127) ) {
446 return AAC_DEC_SET_PARAM_FAIL
;
448 if (concealParams
== NULL
) {
449 return AAC_DEC_INVALID_HANDLE
;
451 concealParams
->comfortNoiseLevel
= comfNoiseLevel
;
460 \brief Set fade-out/in attenuation factor vectors
463 \fadeOutAttenuationVector
464 \fadeInAttenuationVector
466 \return 0 if OK all other values indicate errors
469 CConcealment_SetAttenuation (
470 CConcealParams
*concealParams
,
471 SHORT
*fadeOutAttenuationVector
,
472 SHORT
*fadeInAttenuationVector
)
474 if ( (fadeOutAttenuationVector
== NULL
)
475 && (fadeInAttenuationVector
== NULL
) ) {
476 return AAC_DEC_SET_PARAM_FAIL
;
479 /* Fade-out factors */
480 if (fadeOutAttenuationVector
!= NULL
)
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
;
490 if (concealParams
== NULL
) {
491 return AAC_DEC_INVALID_HANDLE
;
494 /* now dequantize factors */
495 for (i
= 0; i
< CONCEAL_MAX_NUM_FADE_FACTORS
; i
++)
497 concealParams
->fadeOutFactor
[i
] =
498 FX_DBL2FX_SGL( fLdPow( CONCEAL_MIN_ATTENUATION_FACTOR_025_LD
,
500 (FIXP_DBL
)((INT
)(FL2FXCONST_DBL(1.0/2.0)>>(CONCEAL_PARAMETER_BITS
-1)) * (INT
)fadeOutAttenuationVector
[i
]),
501 CONCEAL_PARAMETER_BITS
507 /* Fade-in factors */
508 if (fadeInAttenuationVector
!= NULL
)
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
;
518 if (concealParams
== NULL
) {
519 return AAC_DEC_INVALID_HANDLE
;
522 /* now dequantize factors */
523 for (i
= 0; i
< CONCEAL_MAX_NUM_FADE_FACTORS
; i
++)
525 concealParams
->fadeInFactor
[i
] =
526 FX_DBL2FX_SGL( fLdPow( CONCEAL_MIN_ATTENUATION_FACTOR_025_LD
,
528 (FIXP_DBL
)((INT
)(FIXP_ONE
>>CONCEAL_PARAMETER_BITS
) * (INT
)fadeInAttenuationVector
[i
]),
529 CONCEAL_PARAMETER_BITS
540 \brief Get state of concealment module.
544 \return Concealment state.
547 CConcealment_GetState (
548 CConcealmentInfo
*pConcealChannelInfo
551 CConcealmentState state
= ConcealState_Ok
;
553 if (pConcealChannelInfo
!= NULL
) {
554 state
= pConcealChannelInfo
->concealState
;
561 static void CConcealment_fakePnsData (
564 const SamplingRateInfo
*pSamplingRateInfo
,
569 CPnsInterChannelData
*pInterChannelData
= pPnsData
->pPnsInterChannelData
;
571 int pnsBand
, band
, group
, win
;
573 int windowsPerFrame
= GetWindowsPerFrame(pIcsInfo
);
574 int refLevel
= (windowsPerFrame
> 1) ? 82 : 91;
576 FDK_ASSERT(level
>= 0 && level
<= 127);
578 for (win
= 0; win
< windowsPerFrame
; win
++) {
579 pSpecScale
[win
] = 31;
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;
590 pIcsInfo
->TotalSfBands
= pSamplingRateInfo
->NumberOfScaleFactorBands_Short
;
591 pIcsInfo
->WindowGroupLength
[0] = 8;
593 pIcsInfo
->MaxSfBands
= pIcsInfo
->TotalSfBands
;
596 /* global activate PNS */
597 pPnsData
->PnsActive
= 1;
598 /* set energy level */
599 pPnsData
->CurrentEnergy
= fixMax( 0, refLevel
- level
);
602 value: | Avg. RMS power | Avg. RMS power |
603 | specScale = 22 | specScale = 31 |
604 -------+----------------+----------------+
610 45 | -69.9 dB | -70.0 dB
612 55 | -55.6 dB | -54.6 dB
614 65 | -39.5 dB | -39.5 dB
616 75 | -24.4 dB | -24.4 dB
618 85 | -9.4 dB (c) | -9.4 dB
625 for (group
=0; group
< GetWindowGroups(pIcsInfo
); group
++)
627 for (band
=0; band
< GetScaleFactorBandsTransmitted(pIcsInfo
); band
++)
629 pnsBand
= group
* 16 + band
;
631 if (pnsBand
>= NO_OFBANDS
) {
634 //pPnsData->CurrentEnergy += delta ;
635 pScaleFactor
[pnsBand
] = pPnsData
->CurrentEnergy
;
636 pInterChannelData
->correlated
[pnsBand
] = 0;
637 pPnsData
->pnsUsed
[pnsBand
] = 1;
644 \brief Store data for concealment techniques applied later
646 Interface function to store data for different concealment strategies
652 CConcealmentInfo
*hConcealmentInfo
,
653 CAacDecoderChannelInfo
*pAacDecoderChannelInfo
,
654 CAacDecoderStaticChannelInfo
*pAacDecoderStaticChannelInfo
)
656 if ( !(pAacDecoderChannelInfo
->renderMode
== AACDEC_RENDER_LPD
659 FIXP_DBL
*pSpectralCoefficient
= SPEC_LONG(pAacDecoderChannelInfo
->pSpectralCoefficient
);
660 SHORT
*pSpecScale
= pAacDecoderChannelInfo
->specScale
;
661 CIcsInfo
*pIcsInfo
= &pAacDecoderChannelInfo
->icsInfo
;
664 UCHAR tWindowShape
, tWindowSequence
;
666 /* store old window infos for swapping */
667 tWindowSequence
= hConcealmentInfo
->windowSequence
;
668 tWindowShape
= hConcealmentInfo
->windowShape
;
670 /* store old scale factors for swapping */
671 FDKmemcpy(tSpecScale
, hConcealmentInfo
->specScale
, 8*sizeof(SHORT
));
673 /* store new window infos */
674 hConcealmentInfo
->windowSequence
= GetWindowSequence(pIcsInfo
);
675 hConcealmentInfo
->windowShape
= GetWindowShape(pIcsInfo
);
676 hConcealmentInfo
->lastWinGrpLen
= *(GetWindowGroupLengthTable(pIcsInfo
)+GetWindowGroups(pIcsInfo
)-1);
678 /* store new scale factors */
679 FDKmemcpy(hConcealmentInfo
->specScale
, pSpecScale
, 8*sizeof(SHORT
));
681 if (CConcealment_GetDelay(hConcealmentInfo
->pConcealParams
) == 0)
683 /* store new spectral bins */
684 #if (CNCL_FRACT_BITS == DFRACT_BITS)
685 FDKmemcpy(hConcealmentInfo
->spectralCoefficient
, pSpectralCoefficient
, 1024 * sizeof(FIXP_CNCL
));
687 FIXP_CNCL
*RESTRICT pCncl
= &hConcealmentInfo
->spectralCoefficient
[1024-1];
688 FIXP_DBL
*RESTRICT pSpec
= &pSpectralCoefficient
[1024-1];
691 for (i
= 1024; i
!= 0; i
--) {
692 *pCncl
-- = FX_DBL2FX_CNCL(*pSpec
--);
698 FIXP_CNCL
*RESTRICT pCncl
= &hConcealmentInfo
->spectralCoefficient
[1024-1];
699 FIXP_DBL
*RESTRICT pSpec
= &pSpectralCoefficient
[1024-1];
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
);
709 /* complete swapping of window infos */
710 pIcsInfo
->WindowSequence
= tWindowSequence
;
711 pIcsInfo
->WindowShape
= tWindowShape
;
713 /* complete swapping of scale factors */
714 FDKmemcpy(pSpecScale
, tSpecScale
, 8*sizeof(SHORT
));
722 \brief Apply concealment
724 Interface function to different concealment strategies
730 CConcealmentInfo
*hConcealmentInfo
,
731 CAacDecoderChannelInfo
*pAacDecoderChannelInfo
,
732 CAacDecoderStaticChannelInfo
*pAacDecoderStaticChannelInfo
,
733 const SamplingRateInfo
*pSamplingRateInfo
,
734 const int samplesPerFrame
,
735 const UCHAR lastLpdMode
,
739 int appliedProcessing
= 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
;
746 /* otherwise store the current mode */
747 hConcealmentInfo
->lastRenderMode
= (SCHAR
)pAacDecoderChannelInfo
->renderMode
;
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;
761 /* hand current frame status to the state machine */
762 CConcealment_UpdateState( hConcealmentInfo
,
767 /* Create data for signal rendering according to the selected concealment method and decoder operating mode. */
770 if ( !(pAacDecoderChannelInfo
->renderMode
== AACDEC_RENDER_LPD
774 switch (hConcealmentInfo
->pConcealParams
->method
)
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;
785 case ConcealMethodNoise
:
786 /* Noise substitution error concealment technique */
788 CConcealment_ApplyNoise (hConcealmentInfo
,
789 pAacDecoderChannelInfo
,
790 pAacDecoderStaticChannelInfo
,
796 case ConcealMethodInter
:
797 /* Energy interpolation concealment based on 3GPP */
799 CConcealment_ApplyInter (hConcealmentInfo
,
800 pAacDecoderChannelInfo
,
803 0, /* don't use tonal improvement */
811 hConcealmentInfo
->prevFrameOk
[0] = hConcealmentInfo
->prevFrameOk
[1];
812 hConcealmentInfo
->prevFrameOk
[1] = frameOk
;
814 return appliedProcessing
;
818 \brief Apply concealment noise substitution
820 In case of frame lost this function produces a noisy frame with respect to the
821 energies values of past frame.
826 CConcealment_ApplyNoise (CConcealmentInfo
*pConcealmentInfo
,
827 CAacDecoderChannelInfo
*pAacDecoderChannelInfo
,
828 CAacDecoderStaticChannelInfo
*pAacDecoderStaticChannelInfo
,
829 const SamplingRateInfo
*pSamplingRateInfo
,
830 const int samplesPerFrame
,
833 CConcealParams
*pConcealCommonData
= pConcealmentInfo
->pConcealParams
;
835 FIXP_DBL
*pSpectralCoefficient
= SPEC_LONG(pAacDecoderChannelInfo
->pSpectralCoefficient
);
836 SHORT
*pSpecScale
= pAacDecoderChannelInfo
->specScale
;
837 CIcsInfo
*pIcsInfo
= &pAacDecoderChannelInfo
->icsInfo
;
839 int appliedProcessing
= 0;
841 FDK_ASSERT((samplesPerFrame
>=480) && (samplesPerFrame
<=1024));
842 FDK_ASSERT((samplesPerFrame
&0x1F) == 0);
844 switch (pConcealmentInfo
->concealState
)
846 case ConcealState_Ok
:
847 /* Nothing to do here! */
850 case ConcealState_Single
:
851 case ConcealState_FadeOut
:
853 /* restore frequency coefficients from buffer with a specific muting */
855 int win
, numWindows
= 1;
856 int windowLen
= samplesPerFrame
;
857 int tFadeFrames
, lastWindow
= 0;
858 int win_idx_stride
= 1;
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
);
865 /* get attenuation factor */
866 tFadeFrames
= pConcealmentInfo
->cntFadeFrames
;
867 fac
= pConcealCommonData
->fadeOutFactor
[tFadeFrames
];
869 /* set old window parameters */
871 pIcsInfo
->WindowShape
= pConcealmentInfo
->windowShape
;
872 pIcsInfo
->WindowSequence
= pConcealmentInfo
->windowSequence
;
874 if (pConcealmentInfo
->windowSequence
== 2) {
875 /* short block handling */
877 windowLen
= samplesPerFrame
>> 3;
878 lastWindow
= numWindows
- pConcealmentInfo
->lastWinGrpLen
;
882 for (win
= 0; win
< numWindows
; win
++) {
883 FIXP_CNCL
*pCncl
= pConcealmentInfo
->spectralCoefficient
+ (lastWindow
* windowLen
);
884 FIXP_DBL
*pOut
= pSpectralCoefficient
+ (win
* windowLen
);
887 FDK_ASSERT((lastWindow
* windowLen
+ windowLen
) <= samplesPerFrame
);
889 /* restore frequency coefficients from buffer with a specific attenuation */
890 for (i
= 0; i
< windowLen
; i
++) {
891 pOut
[i
] = fMult(pCncl
[i
], fac
);
894 /* apply random change of sign for spectral coefficients */
895 CConcealment_ApplyRandomSign(pConcealmentInfo
->iRandomPhase
,
899 /* Increment random phase index to avoid repetition artifacts. */
900 pConcealmentInfo
->iRandomPhase
= (pConcealmentInfo
->iRandomPhase
+ 1) & (AAC_NF_NO_RANDOM_VAL
- 1);
902 /* set old scale factors */
903 pSpecScale
[win
*win_idx_stride
] = pConcealmentInfo
->specScale
[win_idx_stride
*lastWindow
++];
905 if ( (lastWindow
>= numWindows
)
906 && (numWindows
> 1) )
908 /* end of sequence -> rewind */
909 lastWindow
= numWindows
- pConcealmentInfo
->lastWinGrpLen
;
910 /* update the attenuation factor to get a faster fade-out */
912 if (tFadeFrames
< pConcealCommonData
->numFadeOutFrames
) {
913 fac
= pConcealCommonData
->fadeOutFactor
[tFadeFrames
];
920 /* store temp vars */
921 pConcealmentInfo
->cntFadeFrames
= tFadeFrames
;
922 appliedProcessing
= 1;
926 case ConcealState_Mute
:
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) */
934 /* mute spectral data */
935 FDKmemclear(pSpectralCoefficient
, samplesPerFrame
* sizeof(FIXP_DBL
));
937 if ( !(flags
& (AC_USAC
|AC_RSVD50
))
938 && pConcealCommonData
->comfortNoiseLevel
>= 0
939 && pConcealCommonData
->comfortNoiseLevel
<= 61 /* -90dB */)
941 /* insert comfort noise using PNS */
942 CConcealment_fakePnsData (
943 &pAacDecoderChannelInfo
->data
.aac
.PnsData
,
946 pAacDecoderChannelInfo
->pDynData
->aSfbScale
,
947 pAacDecoderChannelInfo
->pDynData
->aScaleFactor
,
948 pConcealCommonData
->comfortNoiseLevel
952 &pAacDecoderChannelInfo
->data
.aac
.PnsData
,
954 pAacDecoderChannelInfo
->pSpectralCoefficient
,
955 pAacDecoderChannelInfo
->specScale
,
956 pAacDecoderChannelInfo
->pDynData
->aScaleFactor
,
958 pAacDecoderChannelInfo
->granuleLength
,
959 0 /* always apply to first channel */
962 appliedProcessing
= 1;
966 case ConcealState_FadeIn
:
968 FDK_ASSERT(pConcealmentInfo
->cntFadeFrames
>= 0);
969 FDK_ASSERT(pConcealmentInfo
->cntFadeFrames
< CONCEAL_MAX_NUM_FADE_FACTORS
);
970 FDK_ASSERT(pConcealmentInfo
->cntFadeFrames
< pConcealCommonData
->numFadeInFrames
);
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
];
977 for (i
= samplesPerFrame
; i
!= 0; i
--) {
978 *pOut
= fMult(*pOut
, fac
);
981 appliedProcessing
= 1;
986 /* we shouldn't come here anyway */
991 return appliedProcessing
;
996 \brief Apply concealment interpolation
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.
1005 CConcealment_ApplyInter (
1006 CConcealmentInfo
*pConcealmentInfo
,
1007 CAacDecoderChannelInfo
*pAacDecoderChannelInfo
,
1008 const SamplingRateInfo
*pSamplingRateInfo
,
1009 const int samplesPerFrame
,
1010 const int improveTonal
,
1013 CConcealParams
*pConcealCommonData
= pConcealmentInfo
->pConcealParams
;
1015 FIXP_DBL
*pSpectralCoefficient
= SPEC_LONG(pAacDecoderChannelInfo
->pSpectralCoefficient
);
1016 CIcsInfo
*pIcsInfo
= &pAacDecoderChannelInfo
->icsInfo
;
1017 SHORT
*pSpecScale
= pAacDecoderChannelInfo
->specScale
;
1020 int sfbEnergyPrev
[64];
1021 int sfbEnergyAct
[64];
1023 int i
, appliedProcessing
= 0;
1026 FDKmemclear(sfbEnergyPrev
, 64 * sizeof(int));
1027 FDKmemclear(sfbEnergyAct
, 64 * sizeof(int));
1032 /* Restore last frame from concealment buffer */
1033 pIcsInfo
->WindowShape
= pConcealmentInfo
->windowShape
;
1034 pIcsInfo
->WindowSequence
= pConcealmentInfo
->windowSequence
;
1036 /* Restore spectral data */
1037 for (i
= 0; i
< samplesPerFrame
; i
++) {
1038 pSpectralCoefficient
[i
] = FX_CNCL2FX_DBL(pConcealmentInfo
->spectralCoefficient
[i
]);
1041 /* Restore scale factors */
1042 FDKmemcpy(pSpecScale
, pConcealmentInfo
->specScale
, 8*sizeof(SHORT
));
1045 /* if previous frame was not ok */
1046 if (!pConcealmentInfo
->prevFrameOk
[1]) {
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])
1054 appliedProcessing
= 1;
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 */
1065 if (pConcealmentInfo
->windowSequence
== EightShortSequence
) { /* f_n == EightShortSequence */
1066 /* short--short---short interpolation */
1068 int scaleFactorBandsTotal
= pSamplingRateInfo
->NumberOfScaleFactorBands_Short
;
1069 const SHORT
*pSfbOffset
= pSamplingRateInfo
->ScaleFactorBands_Short
;
1070 pIcsInfo
->WindowShape
= 1;
1071 pIcsInfo
->WindowSequence
= EightShortSequence
;
1073 for (wnd
= 0; wnd
< 8; wnd
++)
1075 CConcealment_CalcBandEnergy(
1076 &pSpectralCoefficient
[wnd
* (samplesPerFrame
/ 8)], /* spec_(n-2) */
1079 CConcealment_NoExpand
,
1082 CConcealment_CalcBandEnergy(
1083 &pConcealmentInfo
->spectralCoefficient
[wnd
* (samplesPerFrame
/ 8)], /* spec_n */
1086 CConcealment_NoExpand
,
1089 CConcealment_InterpolateBuffer(
1090 &pSpectralCoefficient
[wnd
* (samplesPerFrame
/ 8)], /* spec_(n-1) */
1092 &pConcealmentInfo
->specScale
[wnd
],
1096 scaleFactorBandsTotal
,
1100 } else { /* f_n != EightShortSequence */
1101 /* short---long---long interpolation */
1103 int scaleFactorBandsTotal
= pSamplingRateInfo
->NumberOfScaleFactorBands_Long
;
1104 const SHORT
*pSfbOffset
= pSamplingRateInfo
->ScaleFactorBands_Long
;
1107 CConcealment_CalcBandEnergy(&pSpectralCoefficient
[samplesPerFrame
- (samplesPerFrame
/ 8)], /* [wnd] spec_(n-2) */
1110 CConcealment_Expand
,
1113 CConcealment_CalcBandEnergy(pConcealmentInfo
->spectralCoefficient
, /* spec_n */
1116 CConcealment_NoExpand
,
1119 pIcsInfo
->WindowShape
= 0;
1120 pIcsInfo
->WindowSequence
= LongStopSequence
;
1122 for (i
= 0; i
< samplesPerFrame
; i
++) {
1123 pSpectralCoefficient
[i
] = pConcealmentInfo
->spectralCoefficient
[i
]; /* spec_n */
1126 for (i
= 0; i
< 8; i
++) { /* search for max(specScale) */
1127 if (pSpecScale
[i
] > pSpecScale
[0]) {
1128 pSpecScale
[0] = pSpecScale
[i
];
1132 CConcealment_InterpolateBuffer(
1133 pSpectralCoefficient
, /* spec_(n-1) */
1134 &pConcealmentInfo
->specScale
[0],
1139 scaleFactorBandsTotal
,
1142 pSpecScale
[0] = specScaleOut
;
1145 /* long--??????--short, long--??????--long interpolation */
1146 /* long---long---short, long---long---long interpolation */
1148 int scaleFactorBandsTotal
= pSamplingRateInfo
->NumberOfScaleFactorBands_Long
;
1149 const SHORT
*pSfbOffset
= pSamplingRateInfo
->ScaleFactorBands_Long
;
1150 SHORT specScaleAct
= pConcealmentInfo
->specScale
[0];
1152 CConcealment_CalcBandEnergy(pSpectralCoefficient
, /* spec_(n-2) */
1155 CConcealment_NoExpand
,
1158 if (pConcealmentInfo
->windowSequence
== EightShortSequence
) { /* f_n == EightShortSequence */
1159 /* long---long---short interpolation */
1161 pIcsInfo
->WindowShape
= 1;
1162 pIcsInfo
->WindowSequence
= LongStartSequence
;
1164 for (i
= 1; i
< 8; i
++) { /* search for max(specScale) */
1165 if (pConcealmentInfo
->specScale
[i
] > specScaleAct
) {
1166 specScaleAct
= pConcealmentInfo
->specScale
[i
];
1170 /* Expand first short spectrum */
1171 CConcealment_CalcBandEnergy(pConcealmentInfo
->spectralCoefficient
, /* spec_n */
1174 CConcealment_Expand
, /* !!! */
1177 /* long---long---long interpolation */
1179 pIcsInfo
->WindowShape
= 0;
1180 pIcsInfo
->WindowSequence
= OnlyLongSequence
;
1182 CConcealment_CalcBandEnergy(pConcealmentInfo
->spectralCoefficient
, /* spec_n */
1185 CConcealment_NoExpand
,
1189 CConcealment_InterpolateBuffer(
1190 pSpectralCoefficient
, /* spec_(n-1) */
1196 scaleFactorBandsTotal
,
1202 /* Noise substitution of sign of the output spectral coefficients */
1203 CConcealment_ApplyRandomSign (pConcealmentInfo
->iRandomPhase
,
1204 pSpectralCoefficient
,
1206 /* Increment random phase index to avoid repetition artifacts. */
1207 pConcealmentInfo
->iRandomPhase
= (pConcealmentInfo
->iRandomPhase
+ 1) & (AAC_NF_NO_RANDOM_VAL
- 1);
1210 /* scale spectrum according to concealment state */
1211 switch (pConcealmentInfo
->concealState
)
1213 case ConcealState_Single
:
1214 appliedProcessing
= 1;
1217 case ConcealState_FadeOut
:
1219 FDK_ASSERT(pConcealmentInfo
->cntFadeFrames
>= 0);
1220 FDK_ASSERT(pConcealmentInfo
->cntFadeFrames
< CONCEAL_MAX_NUM_FADE_FACTORS
);
1221 FDK_ASSERT(pConcealmentInfo
->cntFadeFrames
< pConcealCommonData
->numFadeOutFrames
);
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
];
1227 for (i
= samplesPerFrame
; i
!= 0; i
--) {
1228 *pOut
= fMult(*pOut
, fac
);
1231 appliedProcessing
= 1;
1235 case ConcealState_FadeIn
:
1237 FDK_ASSERT(pConcealmentInfo
->cntFadeFrames
>= 0);
1238 FDK_ASSERT(pConcealmentInfo
->cntFadeFrames
< CONCEAL_MAX_NUM_FADE_FACTORS
);
1239 FDK_ASSERT(pConcealmentInfo
->cntFadeFrames
< pConcealCommonData
->numFadeInFrames
);
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
];
1245 for (i
= samplesPerFrame
; i
!= 0; i
--) {
1246 *pOut
= fMult(*pOut
, fac
);
1249 appliedProcessing
= 1;
1253 case ConcealState_Mute
:
1255 int fac
= pConcealCommonData
->comfortNoiseLevel
;
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) */
1263 /* mute spectral data */
1264 FDKmemclear(pSpectralCoefficient
, samplesPerFrame
* sizeof(FIXP_DBL
));
1266 if (fac
>= 0 && fac
<= 61) {
1267 /* insert comfort noise using PNS */
1268 CConcealment_fakePnsData (
1269 &pAacDecoderChannelInfo
->data
.aac
.PnsData
,
1272 pAacDecoderChannelInfo
->specScale
,
1273 pAacDecoderChannelInfo
->pDynData
->aScaleFactor
,
1278 &pAacDecoderChannelInfo
->data
.aac
.PnsData
,
1280 pAacDecoderChannelInfo
->pSpectralCoefficient
,
1281 pAacDecoderChannelInfo
->specScale
,
1282 pAacDecoderChannelInfo
->pDynData
->aScaleFactor
,
1284 pAacDecoderChannelInfo
->granuleLength
,
1285 0 /* always apply to first channel */
1288 appliedProcessing
= 1;
1293 /* nothing to do here */
1297 return appliedProcessing
;
1302 \brief Calculate the spectral energy
1304 The function calculates band-wise the spectral energy. This is used for
1305 frame interpolation.
1310 CConcealment_CalcBandEnergy (
1312 const SamplingRateInfo
*pSamplingRateInfo
,
1313 const int blockType
,
1314 CConcealmentExpandType expandType
,
1317 const SHORT
*pSfbOffset
;
1318 int line
, sfb
, scaleFactorBandsTotal
= 0;
1320 /* In the following calculations, enAccu is initialized with LSB-value in order to avoid zero energy-level */
1326 case OnlyLongSequence
:
1327 case LongStartSequence
:
1328 case LongStopSequence
:
1330 if (expandType
== CConcealment_NoExpand
) {
1331 /* standard long calculation */
1332 scaleFactorBandsTotal
= pSamplingRateInfo
->NumberOfScaleFactorBands_Long
;
1333 pSfbOffset
= pSamplingRateInfo
->ScaleFactorBands_Long
;
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
;
1342 *(sfbEnergy
+ sfb
) = CntLeadingZeros(enAccu
) - 1;
1346 /* compress long to short */
1347 scaleFactorBandsTotal
= pSamplingRateInfo
->NumberOfScaleFactorBands_Short
;
1348 pSfbOffset
= pSamplingRateInfo
->ScaleFactorBands_Short
;
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;
1357 *(sfbEnergy
+ sfb
) = CntLeadingZeros(enAccu
) - 1;
1362 case EightShortSequence
:
1364 if (expandType
== CConcealment_NoExpand
) {
1365 /* standard short calculation */
1366 scaleFactorBandsTotal
= pSamplingRateInfo
->NumberOfScaleFactorBands_Short
;
1367 pSfbOffset
= pSamplingRateInfo
->ScaleFactorBands_Short
;
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
;
1376 *(sfbEnergy
+ sfb
) = CntLeadingZeros(enAccu
) - 1;
1380 /* expand short to long spectrum */
1381 scaleFactorBandsTotal
= pSamplingRateInfo
->NumberOfScaleFactorBands_Long
;
1382 pSfbOffset
= pSamplingRateInfo
->ScaleFactorBands_Long
;
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
;
1391 *(sfbEnergy
+ sfb
) = CntLeadingZeros(enAccu
) - 1;
1400 \brief Interpolate buffer
1402 The function creates the interpolated spectral data according to the
1403 energy of the last good frame and the current (good) frame.
1408 CConcealment_InterpolateBuffer (
1410 SHORT
*pSpecScalePrv
,
1411 SHORT
*pSpecScaleAct
,
1412 SHORT
*pSpecScaleOut
,
1416 const SHORT
*pSfbOffset
)
1423 for (sfb
= 0; sfb
< sfbCnt
; sfb
++) {
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
);
1430 for (; line
< pSfbOffset
[sfb
+1]; line
++) {
1431 accu
= fMult(*(spectrum
+line
), facMod4Table
[fac_mod
]);
1432 if (fac_shift
< 0) {
1433 accu
>>= -fac_shift
;
1437 *(spectrum
+line
) = accu
;
1440 *pSpecScaleOut
= fixMax(*pSpecScalePrv
, *pSpecScaleAct
);
1446 static INT
findEquiFadeFrame (
1447 CConcealParams
*pConcealCommonData
,
1452 FIXP_SGL referenceVal
;
1453 FIXP_SGL minDiff
= (FIXP_SGL
)MAXVAL_SGL
;
1456 INT nextFadeIndex
= 0;
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
;
1466 else { /* FADE-IN => FADE-OUT */
1467 numFrames
= pConcealCommonData
->numFadeOutFrames
;
1468 referenceVal
= pConcealCommonData
->fadeInFactor
[actFadeIndex
] >> 1;
1469 pFactor
= pConcealCommonData
->fadeOutFactor
;
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
) {
1481 /* check and adjust depending on direction */
1482 if (direction
== 0) { /* FADE-OUT => FADE-IN */
1483 if (((pFactor
[nextFadeIndex
]>>1) <= referenceVal
) && (nextFadeIndex
> 0)) {
1487 else { /* FADE-IN => FADE-OUT */
1488 if (((pFactor
[nextFadeIndex
]>>1) >= referenceVal
) && (nextFadeIndex
< numFrames
-1)) {
1493 return (nextFadeIndex
);
1498 \brief Update the concealment state
1500 The function updates the state of the concealment state-machine. The
1501 states are: mute, fade-in, fade-out, interpolate and frame-ok.
1506 CConcealment_UpdateState (
1507 CConcealmentInfo
*pConcealmentInfo
,
1510 CConcealParams
*pConcealCommonData
= pConcealmentInfo
->pConcealParams
;
1512 switch (pConcealCommonData
->method
)
1514 case ConcealMethodNoise
:
1516 if (pConcealmentInfo
->concealState
!= ConcealState_Ok
) {
1517 /* count the valid frames during concealment process */
1519 pConcealmentInfo
->cntValidFrames
+= 1;
1521 pConcealmentInfo
->cntValidFrames
= 0;
1525 /* -- STATE MACHINE for Noise Substitution -- */
1526 switch (pConcealmentInfo
->concealState
)
1528 case ConcealState_Ok
:
1530 if (pConcealCommonData
->numFadeOutFrames
> 0) {
1531 /* change to state SINGLE-FRAME-LOSS */
1532 pConcealmentInfo
->concealState
= ConcealState_Single
;
1534 /* change to state MUTE */
1535 pConcealmentInfo
->concealState
= ConcealState_Mute
;
1537 pConcealmentInfo
->cntFadeFrames
= 0;
1538 pConcealmentInfo
->cntValidFrames
= 0;
1542 case ConcealState_Single
: /* Just a pre-stage before fade-out begins. Stay here only one frame! */
1543 pConcealmentInfo
->cntFadeFrames
+= 1;
1545 if (pConcealmentInfo
->cntValidFrames
> pConcealCommonData
->numMuteReleaseFrames
) {
1546 /* change to state FADE-IN */
1547 pConcealmentInfo
->concealState
= ConcealState_FadeIn
;
1548 pConcealmentInfo
->cntFadeFrames
= findEquiFadeFrame( pConcealCommonData
,
1549 pConcealmentInfo
->cntFadeFrames
-1,
1550 0 /* FadeOut -> FadeIn */);
1552 /* change to state OK */
1553 pConcealmentInfo
->concealState
= ConcealState_Ok
;
1556 if (pConcealmentInfo
->cntFadeFrames
>= pConcealCommonData
->numFadeOutFrames
) {
1557 /* change to state MUTE */
1558 pConcealmentInfo
->concealState
= ConcealState_Mute
;
1560 /* change to state FADE-OUT */
1561 pConcealmentInfo
->concealState
= ConcealState_FadeOut
;
1566 case ConcealState_FadeOut
:
1567 pConcealmentInfo
->cntFadeFrames
+= 1; /* used to address the fade-out factors */
1568 if (pConcealmentInfo
->cntValidFrames
> pConcealCommonData
->numMuteReleaseFrames
) {
1569 if (pConcealCommonData
->numFadeInFrames
> 0) {
1570 /* change to state FADE-IN */
1571 pConcealmentInfo
->concealState
= ConcealState_FadeIn
;
1572 pConcealmentInfo
->cntFadeFrames
= findEquiFadeFrame( pConcealCommonData
,
1573 pConcealmentInfo
->cntFadeFrames
-1,
1574 0 /* FadeOut -> FadeIn */);
1576 /* change to state OK */
1577 pConcealmentInfo
->concealState
= ConcealState_Ok
;
1580 if (pConcealmentInfo
->cntFadeFrames
>= pConcealCommonData
->numFadeOutFrames
) {
1581 /* change to state MUTE */
1582 pConcealmentInfo
->concealState
= ConcealState_Mute
;
1587 case ConcealState_Mute
:
1588 if (pConcealmentInfo
->cntValidFrames
> pConcealCommonData
->numMuteReleaseFrames
) {
1589 if (pConcealCommonData
->numFadeInFrames
> 0) {
1590 /* change to state FADE-IN */
1591 pConcealmentInfo
->concealState
= ConcealState_FadeIn
;
1592 pConcealmentInfo
->cntFadeFrames
= pConcealCommonData
->numFadeInFrames
- 1;
1594 /* change to state OK */
1595 pConcealmentInfo
->concealState
= ConcealState_Ok
;
1600 case ConcealState_FadeIn
:
1601 pConcealmentInfo
->cntFadeFrames
-= 1; /* used to address the fade-in factors */
1603 if (pConcealmentInfo
->cntFadeFrames
< 0) {
1604 /* change to state OK */
1605 pConcealmentInfo
->concealState
= ConcealState_Ok
;
1608 if (pConcealCommonData
->numFadeOutFrames
> 0) {
1609 /* change to state FADE-OUT */
1610 pConcealmentInfo
->concealState
= ConcealState_FadeOut
;
1611 pConcealmentInfo
->cntFadeFrames
= findEquiFadeFrame( pConcealCommonData
,
1612 pConcealmentInfo
->cntFadeFrames
+1,
1613 1 /* FadeIn -> FadeOut */);
1615 /* change to state MUTE */
1616 pConcealmentInfo
->concealState
= ConcealState_Mute
;
1628 case ConcealMethodInter
:
1629 case ConcealMethodTonal
:
1631 if (pConcealmentInfo
->concealState
!= ConcealState_Ok
) {
1632 /* count the valid frames during concealment process */
1633 if ( pConcealmentInfo
->prevFrameOk
[1] ||
1634 (pConcealmentInfo
->prevFrameOk
[0] && !pConcealmentInfo
->prevFrameOk
[1] && frameOk
) ) {
1635 /* The frame is OK even if it can be estimated by the energy interpolation algorithm */
1636 pConcealmentInfo
->cntValidFrames
+= 1;
1638 pConcealmentInfo
->cntValidFrames
= 0;
1642 /* -- STATE MACHINE for energy interpolation -- */
1643 switch (pConcealmentInfo
->concealState
)
1645 case ConcealState_Ok
:
1646 if (!(pConcealmentInfo
->prevFrameOk
[1] ||
1647 (pConcealmentInfo
->prevFrameOk
[0] && !pConcealmentInfo
->prevFrameOk
[1] && frameOk
))) {
1648 if (pConcealCommonData
->numFadeOutFrames
> 0) {
1649 /* Fade out only if the energy interpolation algorithm can not be applied! */
1650 pConcealmentInfo
->concealState
= ConcealState_FadeOut
;
1652 /* change to state MUTE */
1653 pConcealmentInfo
->concealState
= ConcealState_Mute
;
1655 pConcealmentInfo
->cntFadeFrames
= 0;
1656 pConcealmentInfo
->cntValidFrames
= 0;
1660 case ConcealState_Single
:
1661 pConcealmentInfo
->concealState
= ConcealState_Ok
;
1664 case ConcealState_FadeOut
:
1665 pConcealmentInfo
->cntFadeFrames
+= 1;
1667 if (pConcealmentInfo
->cntValidFrames
> pConcealCommonData
->numMuteReleaseFrames
) {
1668 if (pConcealCommonData
->numFadeInFrames
> 0) {
1669 /* change to state FADE-IN */
1670 pConcealmentInfo
->concealState
= ConcealState_FadeIn
;
1671 pConcealmentInfo
->cntFadeFrames
= findEquiFadeFrame( pConcealCommonData
,
1672 pConcealmentInfo
->cntFadeFrames
-1,
1673 0 /* FadeOut -> FadeIn */);
1675 /* change to state OK */
1676 pConcealmentInfo
->concealState
= ConcealState_Ok
;
1679 if (pConcealmentInfo
->cntFadeFrames
>= pConcealCommonData
->numFadeOutFrames
) {
1680 /* change to state MUTE */
1681 pConcealmentInfo
->concealState
= ConcealState_Mute
;
1686 case ConcealState_Mute
:
1687 if (pConcealmentInfo
->cntValidFrames
> pConcealCommonData
->numMuteReleaseFrames
) {
1688 if (pConcealCommonData
->numFadeInFrames
> 0) {
1689 /* change to state FADE-IN */
1690 pConcealmentInfo
->concealState
= ConcealState_FadeIn
;
1691 pConcealmentInfo
->cntFadeFrames
= pConcealCommonData
->numFadeInFrames
- 1;
1693 /* change to state OK */
1694 pConcealmentInfo
->concealState
= ConcealState_Ok
;
1699 case ConcealState_FadeIn
:
1700 pConcealmentInfo
->cntFadeFrames
-= 1; /* used to address the fade-in factors */
1702 if (frameOk
|| pConcealmentInfo
->prevFrameOk
[1]) {
1703 if (pConcealmentInfo
->cntFadeFrames
< 0) {
1704 /* change to state OK */
1705 pConcealmentInfo
->concealState
= ConcealState_Ok
;
1708 if (pConcealCommonData
->numFadeOutFrames
> 0) {
1709 /* change to state FADE-OUT */
1710 pConcealmentInfo
->concealState
= ConcealState_FadeOut
;
1711 pConcealmentInfo
->cntFadeFrames
= findEquiFadeFrame( pConcealCommonData
,
1712 pConcealmentInfo
->cntFadeFrames
+1,
1713 1 /* FadeIn -> FadeOut */);
1715 /* change to state MUTE */
1716 pConcealmentInfo
->concealState
= ConcealState_Mute
;
1720 } /* End switch(pConcealmentInfo->concealState) */
1725 /* Don't need a state machine for other concealment methods. */
1733 \brief Randomizes the sign of the spectral data
1735 The function toggles the sign of the spectral data randomly. This is
1736 useful to ensure the quality of the concealed frames.
1741 void CConcealment_ApplyRandomSign (int randomPhase
,
1747 USHORT packedSign
=0;
1749 /* random table 512x16bit has been reduced to 512 packed sign bits = 32x16 bit */
1751 /* read current packed sign word */
1752 packedSign
= randomSign
[randomPhase
>>4];
1753 packedSign
>>= (randomPhase
&0xf);
1755 for (i
= 0; i
< samplesPerFrame
; i
++) {
1756 if ((randomPhase
& 0xf) == 0) {
1757 packedSign
= randomSign
[randomPhase
>>4];
1760 if (packedSign
& 0x1) {
1765 randomPhase
= (randomPhase
+ 1) & (AAC_NF_NO_RANDOM_VAL
- 1);
1771 \brief Get fadeing factor for current concealment state.
1773 The function returns the factor used for fading that belongs to the current internal state.
1778 CConcealment_GetFadeFactor (
1779 CConcealmentInfo
*hConcealmentInfo
,
1780 const int fPreviousFactor
1783 FIXP_DBL fac
= (FIXP_DBL
)0;
1785 CConcealParams
*pConcealCommonData
= hConcealmentInfo
->pConcealParams
;
1787 if (hConcealmentInfo
->pConcealParams
->method
> ConcealMethodMute
) {
1788 switch (hConcealmentInfo
->concealState
) {
1790 case ConcealState_Mute
:
1791 /* Nothing to do here */
1793 case ConcealState_Ok
:
1794 fac
= (FIXP_DBL
)MAXVAL_DBL
;
1796 case ConcealState_Single
:
1797 case ConcealState_FadeOut
:
1799 int idx
= hConcealmentInfo
->cntFadeFrames
- ((fPreviousFactor
!= 0) ? 1 : 0);
1800 fac
= (idx
< 0) ? (FIXP_DBL
)MAXVAL_DBL
: FX_SGL2FX_DBL(pConcealCommonData
->fadeOutFactor
[idx
]);
1803 case ConcealState_FadeIn
:
1805 int idx
= hConcealmentInfo
->cntFadeFrames
+ ((fPreviousFactor
!= 0) ? 1 : 0);
1806 fac
= (idx
>= hConcealmentInfo
->pConcealParams
->numFadeInFrames
) ? (FIXP_DBL
)0 : FX_SGL2FX_DBL(pConcealCommonData
->fadeInFactor
[idx
]);
1817 \brief Get fadeing factor for current concealment state.
1819 The function returns the state (ok or not) of the previous frame.
1820 If called before the function CConcealment_Apply() set the fBeforeApply
1821 flag to get the correct value.
1823 \return Frame OK flag of previous frame.
1826 CConcealment_GetLastFrameOk (
1827 CConcealmentInfo
*hConcealmentInfo
,
1828 const int fBeforeApply
1831 int prevFrameOk
= 1;
1833 if (hConcealmentInfo
!= NULL
) {
1834 prevFrameOk
= hConcealmentInfo
->prevFrameOk
[fBeforeApply
& 0x1];
1841 \brief Get the number of delay frames introduced by concealment technique.
1843 \return Number of delay frames.
1846 CConcealment_GetDelay (
1847 CConcealParams
*pConcealCommonData
1850 UINT frameDelay
= 0;
1852 if (pConcealCommonData
!= NULL
) {
1853 switch (pConcealCommonData
->method
) {
1854 case ConcealMethodTonal
:
1855 case ConcealMethodInter
: