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