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