/src/aac/libAACdec/src/conceal.cpp
Line | Count | Source (jump to first uncovered line) |
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 | 7.43k | #define CONCEAL_DFLT_COMF_NOISE_LEVEL (0x100000) |
157 | | |
158 | 5.79k | #define CONCEAL_NOT_DEFINED ((UCHAR)-1) |
159 | | |
160 | | /* default settings */ |
161 | 7.43k | #define CONCEAL_DFLT_FADEOUT_FRAMES (6) |
162 | 7.43k | #define CONCEAL_DFLT_FADEIN_FRAMES (5) |
163 | 7.43k | #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 | 0 | #define CONCEAL_PARAMETER_BITS (8) |
174 | 0 | #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 | | |
249 | 0 | static BLOCK_TYPE CConcealment_GetWinSeq(int prevWinSeq) { |
250 | 0 | BLOCK_TYPE newWinSeq = BLOCK_LONG; |
251 | | |
252 | | /* Try to have only long blocks */ |
253 | 0 | if (prevWinSeq == BLOCK_START || prevWinSeq == BLOCK_SHORT) { |
254 | 0 | newWinSeq = BLOCK_STOP; |
255 | 0 | } |
256 | |
|
257 | 0 | return (newWinSeq); |
258 | 0 | } |
259 | | |
260 | | /*! |
261 | | \brief Init common concealment information data |
262 | | |
263 | | \param pConcealCommonData Pointer to the concealment common data structure. |
264 | | */ |
265 | 7.43k | void CConcealment_InitCommonData(CConcealParams *pConcealCommonData) { |
266 | 7.43k | if (pConcealCommonData != NULL) { |
267 | 7.43k | int i; |
268 | | |
269 | | /* Set default error concealment technique */ |
270 | 7.43k | pConcealCommonData->method = ConcealMethodInter; |
271 | | |
272 | 7.43k | pConcealCommonData->numFadeOutFrames = CONCEAL_DFLT_FADEOUT_FRAMES; |
273 | 7.43k | pConcealCommonData->numFadeInFrames = CONCEAL_DFLT_FADEIN_FRAMES; |
274 | 7.43k | pConcealCommonData->numMuteReleaseFrames = CONCEAL_DFLT_MUTE_RELEASE_FRAMES; |
275 | | |
276 | 7.43k | pConcealCommonData->comfortNoiseLevel = |
277 | 7.43k | (FIXP_DBL)CONCEAL_DFLT_COMF_NOISE_LEVEL; |
278 | | |
279 | | /* Init fade factors (symetric) */ |
280 | 7.43k | pConcealCommonData->fadeOutFactor[0] = |
281 | 7.43k | FL2FXCONST_SGL(CONCEAL_DFLT_FADE_FACTOR); |
282 | 7.43k | pConcealCommonData->fadeInFactor[0] = pConcealCommonData->fadeOutFactor[0]; |
283 | | |
284 | 237k | for (i = 1; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) { |
285 | 230k | pConcealCommonData->fadeOutFactor[i] = |
286 | 230k | FX_DBL2FX_SGL(fMult(pConcealCommonData->fadeOutFactor[i - 1], |
287 | 230k | FL2FXCONST_SGL(CONCEAL_DFLT_FADE_FACTOR))); |
288 | 230k | pConcealCommonData->fadeInFactor[i] = |
289 | 230k | pConcealCommonData->fadeOutFactor[i]; |
290 | 230k | } |
291 | 7.43k | } |
292 | 7.43k | } |
293 | | |
294 | | /*! |
295 | | \brief Get current concealment method. |
296 | | |
297 | | \param pConcealCommonData Pointer to common concealment data (for all |
298 | | channels) |
299 | | */ |
300 | 17.3k | CConcealmentMethod CConcealment_GetMethod(CConcealParams *pConcealCommonData) { |
301 | 17.3k | CConcealmentMethod method = ConcealMethodNone; |
302 | | |
303 | 17.3k | if (pConcealCommonData != NULL) { |
304 | 17.3k | method = pConcealCommonData->method; |
305 | 17.3k | } |
306 | | |
307 | 17.3k | return (method); |
308 | 17.3k | } |
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 | | */ |
319 | | void CConcealment_InitChannelData(CConcealmentInfo *pConcealChannelInfo, |
320 | | CConcealParams *pConcealCommonData, |
321 | | AACDEC_RENDER_MODE initRenderMode, |
322 | 5.79k | int samplesPerFrame) { |
323 | 5.79k | int i; |
324 | 5.79k | pConcealChannelInfo->TDNoiseSeed = 0; |
325 | 5.79k | FDKmemclear(pConcealChannelInfo->TDNoiseStates, |
326 | 5.79k | sizeof(pConcealChannelInfo->TDNoiseStates)); |
327 | 5.79k | pConcealChannelInfo->TDNoiseCoef[0] = FL2FXCONST_SGL(0.05f); |
328 | 5.79k | pConcealChannelInfo->TDNoiseCoef[1] = FL2FXCONST_SGL(0.5f); |
329 | 5.79k | pConcealChannelInfo->TDNoiseCoef[2] = FL2FXCONST_SGL(0.45f); |
330 | | |
331 | 5.79k | pConcealChannelInfo->pConcealParams = pConcealCommonData; |
332 | | |
333 | 5.79k | pConcealChannelInfo->lastRenderMode = initRenderMode; |
334 | | |
335 | 5.79k | pConcealChannelInfo->windowShape = CONCEAL_NOT_DEFINED; |
336 | 5.79k | pConcealChannelInfo->windowSequence = BLOCK_LONG; /* default type */ |
337 | 5.79k | pConcealChannelInfo->lastWinGrpLen = 1; |
338 | | |
339 | 5.79k | pConcealChannelInfo->concealState = ConcealState_Ok; |
340 | | |
341 | 5.79k | FDKmemclear(pConcealChannelInfo->spectralCoefficient, |
342 | 5.79k | 1024 * sizeof(FIXP_CNCL)); |
343 | | |
344 | 52.1k | for (i = 0; i < 8; i++) { |
345 | 46.3k | pConcealChannelInfo->specScale[i] = 0; |
346 | 46.3k | } |
347 | | |
348 | 5.79k | pConcealChannelInfo->iRandomPhase = 0; |
349 | | |
350 | 5.79k | pConcealChannelInfo->prevFrameOk[0] = 1; |
351 | 5.79k | pConcealChannelInfo->prevFrameOk[1] = 1; |
352 | | |
353 | 5.79k | pConcealChannelInfo->cntFadeFrames = 0; |
354 | 5.79k | pConcealChannelInfo->cntValidFrames = 0; |
355 | 5.79k | pConcealChannelInfo->fade_old = (FIXP_DBL)MAXVAL_DBL; |
356 | 5.79k | pConcealChannelInfo->winGrpOffset[0] = 0; |
357 | 5.79k | pConcealChannelInfo->winGrpOffset[1] = 0; |
358 | 5.79k | pConcealChannelInfo->attGrpOffset[0] = 0; |
359 | 5.79k | pConcealChannelInfo->attGrpOffset[1] = 0; |
360 | 5.79k | } |
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 |
373 | | CConcealment_SetParams(CConcealParams *concealParams, int method, |
374 | | int fadeOutSlope, int fadeInSlope, int muteRelease, |
375 | 9.94k | FIXP_DBL comfNoiseLevel) { |
376 | | /* set concealment technique */ |
377 | 9.94k | if (method != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) { |
378 | 9.94k | switch ((CConcealmentMethod)method) { |
379 | 0 | case ConcealMethodMute: |
380 | 2.51k | case ConcealMethodNoise: |
381 | 9.94k | case ConcealMethodInter: |
382 | | /* Be sure to enable delay adjustment of SBR decoder! */ |
383 | 9.94k | if (concealParams == NULL) { |
384 | 0 | return AAC_DEC_INVALID_HANDLE; |
385 | 9.94k | } else { |
386 | | /* set param */ |
387 | 9.94k | concealParams->method = (CConcealmentMethod)method; |
388 | 9.94k | } |
389 | 9.94k | break; |
390 | | |
391 | 9.94k | default: |
392 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
393 | 9.94k | } |
394 | 9.94k | } |
395 | | |
396 | | /* set number of frames for fade-out slope */ |
397 | 9.94k | if (fadeOutSlope != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) { |
398 | 0 | if ((fadeOutSlope < CONCEAL_MAX_NUM_FADE_FACTORS) && (fadeOutSlope >= 0)) { |
399 | 0 | if (concealParams == NULL) { |
400 | 0 | return AAC_DEC_INVALID_HANDLE; |
401 | 0 | } else { |
402 | | /* set param */ |
403 | 0 | concealParams->numFadeOutFrames = fadeOutSlope; |
404 | 0 | } |
405 | 0 | } else { |
406 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
407 | 0 | } |
408 | 0 | } |
409 | | |
410 | | /* set number of frames for fade-in slope */ |
411 | 9.94k | if (fadeInSlope != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) { |
412 | 0 | if ((fadeInSlope < CONCEAL_MAX_NUM_FADE_FACTORS) && (fadeInSlope >= 0)) { |
413 | 0 | if (concealParams == NULL) { |
414 | 0 | return AAC_DEC_INVALID_HANDLE; |
415 | 0 | } else { |
416 | | /* set param */ |
417 | 0 | concealParams->numFadeInFrames = fadeInSlope; |
418 | 0 | } |
419 | 0 | } else { |
420 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
421 | 0 | } |
422 | 0 | } |
423 | | |
424 | | /* set number of error-free frames after which the muting will be released */ |
425 | 9.94k | if (muteRelease != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) { |
426 | 0 | if ((muteRelease < (CONCEAL_MAX_NUM_FADE_FACTORS << 1)) && |
427 | 0 | (muteRelease >= 0)) { |
428 | 0 | if (concealParams == NULL) { |
429 | 0 | return AAC_DEC_INVALID_HANDLE; |
430 | 0 | } else { |
431 | | /* set param */ |
432 | 0 | concealParams->numMuteReleaseFrames = muteRelease; |
433 | 0 | } |
434 | 0 | } else { |
435 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
436 | 0 | } |
437 | 0 | } |
438 | | |
439 | | /* set confort noise level which will be inserted while in state 'muting' */ |
440 | 9.94k | if (comfNoiseLevel != (FIXP_DBL)AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) { |
441 | 0 | if ((comfNoiseLevel < (FIXP_DBL)0) || |
442 | 0 | (comfNoiseLevel > (FIXP_DBL)MAXVAL_DBL)) { |
443 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
444 | 0 | } |
445 | 0 | if (concealParams == NULL) { |
446 | 0 | return AAC_DEC_INVALID_HANDLE; |
447 | 0 | } else { |
448 | 0 | concealParams->comfortNoiseLevel = (FIXP_DBL)comfNoiseLevel; |
449 | 0 | } |
450 | 0 | } |
451 | | |
452 | 9.94k | return (AAC_DEC_OK); |
453 | 9.94k | } |
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 |
465 | | CConcealment_SetAttenuation(CConcealParams *concealParams, |
466 | | const SHORT *fadeOutAttenuationVector, |
467 | 0 | const SHORT *fadeInAttenuationVector) { |
468 | 0 | if ((fadeOutAttenuationVector == NULL) && (fadeInAttenuationVector == NULL)) { |
469 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
470 | 0 | } |
471 | | |
472 | | /* Fade-out factors */ |
473 | 0 | if (fadeOutAttenuationVector != NULL) { |
474 | 0 | int i; |
475 | | |
476 | | /* check quantized factors first */ |
477 | 0 | for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) { |
478 | 0 | if ((fadeOutAttenuationVector[i] < 0) || |
479 | 0 | (fadeOutAttenuationVector[i] > CONCEAL_MAX_QUANT_FACTOR)) { |
480 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
481 | 0 | } |
482 | 0 | } |
483 | 0 | if (concealParams == NULL) { |
484 | 0 | return AAC_DEC_INVALID_HANDLE; |
485 | 0 | } |
486 | | |
487 | | /* now dequantize factors */ |
488 | 0 | for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) { |
489 | 0 | concealParams->fadeOutFactor[i] = |
490 | 0 | FX_DBL2FX_SGL(fLdPow(CONCEAL_MIN_ATTENUATION_FACTOR_025_LD, 0, |
491 | 0 | (FIXP_DBL)((INT)(FL2FXCONST_DBL(1.0 / 2.0) >> |
492 | 0 | (CONCEAL_PARAMETER_BITS - 1)) * |
493 | 0 | (INT)fadeOutAttenuationVector[i]), |
494 | 0 | CONCEAL_PARAMETER_BITS)); |
495 | 0 | } |
496 | 0 | } |
497 | | |
498 | | /* Fade-in factors */ |
499 | 0 | if (fadeInAttenuationVector != NULL) { |
500 | 0 | int i; |
501 | | |
502 | | /* check quantized factors first */ |
503 | 0 | for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) { |
504 | 0 | if ((fadeInAttenuationVector[i] < 0) || |
505 | 0 | (fadeInAttenuationVector[i] > CONCEAL_MAX_QUANT_FACTOR)) { |
506 | 0 | return AAC_DEC_SET_PARAM_FAIL; |
507 | 0 | } |
508 | 0 | } |
509 | 0 | if (concealParams == NULL) { |
510 | 0 | return AAC_DEC_INVALID_HANDLE; |
511 | 0 | } |
512 | | |
513 | | /* now dequantize factors */ |
514 | 0 | for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) { |
515 | 0 | concealParams->fadeInFactor[i] = FX_DBL2FX_SGL( |
516 | 0 | fLdPow(CONCEAL_MIN_ATTENUATION_FACTOR_025_LD, 0, |
517 | 0 | (FIXP_DBL)((INT)(FIXP_ONE >> CONCEAL_PARAMETER_BITS) * |
518 | 0 | (INT)fadeInAttenuationVector[i]), |
519 | 0 | CONCEAL_PARAMETER_BITS)); |
520 | 0 | } |
521 | 0 | } |
522 | | |
523 | 0 | return (AAC_DEC_OK); |
524 | 0 | } |
525 | | |
526 | | /*! |
527 | | \brief Get state of concealment module. |
528 | | |
529 | | \param pConcealChannelInfo |
530 | | |
531 | | \return Concealment state. |
532 | | */ |
533 | 0 | CConcealmentState CConcealment_GetState(CConcealmentInfo *pConcealChannelInfo) { |
534 | 0 | CConcealmentState state = ConcealState_Ok; |
535 | |
|
536 | 0 | if (pConcealChannelInfo != NULL) { |
537 | 0 | state = pConcealChannelInfo->concealState; |
538 | 0 | } |
539 | |
|
540 | 0 | return (state); |
541 | 0 | } |
542 | | |
543 | | /*! |
544 | | \brief Store data for concealment techniques applied later |
545 | | |
546 | | Interface function to store data for different concealment strategies |
547 | | */ |
548 | | void CConcealment_Store( |
549 | | CConcealmentInfo *hConcealmentInfo, |
550 | | CAacDecoderChannelInfo *pAacDecoderChannelInfo, |
551 | 0 | CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) { |
552 | 0 | UCHAR nbDiv = NB_DIV; |
553 | |
|
554 | 0 | if (!(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD && |
555 | 0 | pAacDecoderChannelInfo->data.usac.mod[nbDiv - 1] == 0)) |
556 | | |
557 | 0 | { |
558 | 0 | FIXP_DBL *pSpectralCoefficient = |
559 | 0 | SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); |
560 | 0 | SHORT *pSpecScale = pAacDecoderChannelInfo->specScale; |
561 | 0 | CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; |
562 | |
|
563 | 0 | SHORT tSpecScale[8]; |
564 | 0 | UCHAR tWindowShape; |
565 | 0 | BLOCK_TYPE tWindowSequence; |
566 | | |
567 | | /* store old window infos for swapping */ |
568 | 0 | tWindowSequence = hConcealmentInfo->windowSequence; |
569 | 0 | tWindowShape = hConcealmentInfo->windowShape; |
570 | | |
571 | | /* store old scale factors for swapping */ |
572 | 0 | FDKmemcpy(tSpecScale, hConcealmentInfo->specScale, 8 * sizeof(SHORT)); |
573 | | |
574 | | /* store new window infos */ |
575 | 0 | hConcealmentInfo->windowSequence = GetWindowSequence(pIcsInfo); |
576 | 0 | hConcealmentInfo->windowShape = GetWindowShape(pIcsInfo); |
577 | 0 | hConcealmentInfo->lastWinGrpLen = |
578 | 0 | *(GetWindowGroupLengthTable(pIcsInfo) + GetWindowGroups(pIcsInfo) - 1); |
579 | | |
580 | | /* store new scale factors */ |
581 | 0 | FDKmemcpy(hConcealmentInfo->specScale, pSpecScale, 8 * sizeof(SHORT)); |
582 | |
|
583 | 0 | if (hConcealmentInfo->pConcealParams->method < ConcealMethodInter) { |
584 | | /* store new spectral bins */ |
585 | 0 | #if (CNCL_FRACT_BITS == DFRACT_BITS) |
586 | 0 | FDKmemcpy(hConcealmentInfo->spectralCoefficient, pSpectralCoefficient, |
587 | 0 | 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 | 0 | } else { |
598 | | /* swap spectral data */ |
599 | 0 | #if (FIXP_CNCL == FIXP_DBL) |
600 | 0 | C_ALLOC_SCRATCH_START(pSpecTmp, FIXP_DBL, 1024); |
601 | 0 | FDKmemcpy(pSpecTmp, pSpectralCoefficient, 1024 * sizeof(FIXP_DBL)); |
602 | 0 | FDKmemcpy(pSpectralCoefficient, hConcealmentInfo->spectralCoefficient, |
603 | 0 | 1024 * sizeof(FIXP_DBL)); |
604 | 0 | FDKmemcpy(hConcealmentInfo->spectralCoefficient, pSpecTmp, |
605 | 0 | 1024 * sizeof(FIXP_DBL)); |
606 | 0 | 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 | 0 | pIcsInfo->WindowSequence = tWindowSequence; |
622 | 0 | pIcsInfo->WindowShape = tWindowShape; |
623 | | |
624 | | /* complete swapping of scale factors */ |
625 | 0 | FDKmemcpy(pSpecScale, tSpecScale, 8 * sizeof(SHORT)); |
626 | 0 | } |
627 | 0 | } |
628 | |
|
629 | 0 | if (pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD) { |
630 | | /* Store LSF4 */ |
631 | 0 | FDKmemcpy(hConcealmentInfo->lsf4, pAacDecoderStaticChannelInfo->lpc4_lsf, |
632 | 0 | sizeof(hConcealmentInfo->lsf4)); |
633 | | /* Store TCX gain */ |
634 | 0 | hConcealmentInfo->last_tcx_gain = |
635 | 0 | pAacDecoderStaticChannelInfo->last_tcx_gain; |
636 | 0 | hConcealmentInfo->last_tcx_gain_e = |
637 | 0 | pAacDecoderStaticChannelInfo->last_tcx_gain_e; |
638 | 0 | } |
639 | 0 | } |
640 | | |
641 | | /*! |
642 | | \brief Apply concealment |
643 | | |
644 | | Interface function to different concealment strategies |
645 | | */ |
646 | | int CConcealment_Apply( |
647 | | CConcealmentInfo *hConcealmentInfo, |
648 | | CAacDecoderChannelInfo *pAacDecoderChannelInfo, |
649 | | CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, |
650 | | const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame, |
651 | 0 | const UCHAR lastLpdMode, const int frameOk, const UINT flags) { |
652 | 0 | int appliedProcessing = 0; |
653 | 0 | const int mute_release_active = |
654 | 0 | frameOk && (hConcealmentInfo->concealState >= ConcealState_Mute) && |
655 | 0 | (hConcealmentInfo->cntValidFrames + 1 <= |
656 | 0 | hConcealmentInfo->pConcealParams->numMuteReleaseFrames); |
657 | |
|
658 | 0 | 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 | 0 | hConcealmentInfo->windowShape = pAacDecoderChannelInfo->icsInfo.WindowShape; |
664 | 0 | } |
665 | |
|
666 | 0 | if (frameOk && !mute_release_active) { |
667 | | /* Update render mode if frameOk except for ongoing mute release state. */ |
668 | 0 | hConcealmentInfo->lastRenderMode = |
669 | 0 | (SCHAR)pAacDecoderChannelInfo->renderMode; |
670 | | |
671 | | /* Rescue current data for concealment in future frames */ |
672 | 0 | CConcealment_Store(hConcealmentInfo, pAacDecoderChannelInfo, |
673 | 0 | 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 | 0 | hConcealmentInfo->iRandomPhase = 0; |
677 | 0 | } else { |
678 | 0 | if (hConcealmentInfo->lastRenderMode == AACDEC_RENDER_INVALID) { |
679 | 0 | hConcealmentInfo->lastRenderMode = AACDEC_RENDER_IMDCT; |
680 | 0 | } |
681 | 0 | pAacDecoderChannelInfo->renderMode = |
682 | 0 | (AACDEC_RENDER_MODE)hConcealmentInfo->lastRenderMode; |
683 | 0 | } |
684 | | |
685 | | /* hand current frame status to the state machine */ |
686 | 0 | CConcealment_UpdateState(hConcealmentInfo, frameOk, |
687 | 0 | pAacDecoderStaticChannelInfo, samplesPerFrame, |
688 | 0 | pAacDecoderChannelInfo); |
689 | |
|
690 | 0 | { |
691 | 0 | if (!frameOk && pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_IMDCT) { |
692 | | /* LPC extrapolation */ |
693 | 0 | CLpc_Conceal(pAacDecoderChannelInfo->data.usac.lsp_coeff, |
694 | 0 | pAacDecoderStaticChannelInfo->lpc4_lsf, |
695 | 0 | pAacDecoderStaticChannelInfo->lsf_adaptive_mean, |
696 | 0 | hConcealmentInfo->lastRenderMode == AACDEC_RENDER_IMDCT); |
697 | 0 | FDKmemcpy(hConcealmentInfo->lsf4, pAacDecoderStaticChannelInfo->lpc4_lsf, |
698 | 0 | sizeof(pAacDecoderStaticChannelInfo->lpc4_lsf)); |
699 | 0 | } |
700 | | |
701 | | /* Create data for signal rendering according to the selected concealment |
702 | | * method and decoder operating mode. */ |
703 | |
|
704 | 0 | if ((!frameOk || mute_release_active) && |
705 | 0 | (pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD)) { |
706 | | /* Restore old LSF4 */ |
707 | 0 | FDKmemcpy(pAacDecoderStaticChannelInfo->lpc4_lsf, hConcealmentInfo->lsf4, |
708 | 0 | sizeof(pAacDecoderStaticChannelInfo->lpc4_lsf)); |
709 | | /* Restore old TCX gain */ |
710 | 0 | pAacDecoderStaticChannelInfo->last_tcx_gain = |
711 | 0 | hConcealmentInfo->last_tcx_gain; |
712 | 0 | pAacDecoderStaticChannelInfo->last_tcx_gain_e = |
713 | 0 | hConcealmentInfo->last_tcx_gain_e; |
714 | 0 | } |
715 | |
|
716 | 0 | if (!(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD && |
717 | 0 | pAacDecoderStaticChannelInfo->last_lpd_mode == 0)) { |
718 | 0 | switch (hConcealmentInfo->pConcealParams->method) { |
719 | 0 | default: |
720 | 0 | case ConcealMethodMute: |
721 | 0 | if (!frameOk) { |
722 | | /* Mute spectral data in case of errors */ |
723 | 0 | FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient, |
724 | 0 | samplesPerFrame * sizeof(FIXP_DBL)); |
725 | | /* Set last window shape */ |
726 | 0 | pAacDecoderChannelInfo->icsInfo.WindowShape = |
727 | 0 | hConcealmentInfo->windowShape; |
728 | 0 | appliedProcessing = 1; |
729 | 0 | } |
730 | 0 | break; |
731 | | |
732 | 0 | case ConcealMethodNoise: |
733 | | /* Noise substitution error concealment technique */ |
734 | 0 | appliedProcessing = CConcealment_ApplyNoise( |
735 | 0 | hConcealmentInfo, pAacDecoderChannelInfo, |
736 | 0 | pAacDecoderStaticChannelInfo, pSamplingRateInfo, samplesPerFrame, |
737 | 0 | flags); |
738 | 0 | break; |
739 | | |
740 | 0 | case ConcealMethodInter: |
741 | | /* Energy interpolation concealment based on 3GPP */ |
742 | 0 | appliedProcessing = CConcealment_ApplyInter( |
743 | 0 | hConcealmentInfo, pAacDecoderChannelInfo, pSamplingRateInfo, |
744 | 0 | samplesPerFrame, 0, /* don't use tonal improvement */ |
745 | 0 | frameOk, mute_release_active); |
746 | 0 | break; |
747 | 0 | } |
748 | 0 | } else if (!frameOk || mute_release_active) { |
749 | | /* simply restore the buffer */ |
750 | 0 | FIXP_DBL *pSpectralCoefficient = |
751 | 0 | SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); |
752 | 0 | SHORT *pSpecScale = pAacDecoderChannelInfo->specScale; |
753 | 0 | 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 | 0 | pIcsInfo->WindowSequence = hConcealmentInfo->windowSequence; |
763 | 0 | pIcsInfo->WindowShape = hConcealmentInfo->windowShape; |
764 | |
|
765 | 0 | if (hConcealmentInfo->concealState != ConcealState_Mute) { |
766 | | /* restore scale factors */ |
767 | 0 | FDKmemcpy(pSpecScale, hConcealmentInfo->specScale, 8 * sizeof(SHORT)); |
768 | | |
769 | | /* restore spectral bins */ |
770 | 0 | #if (CNCL_FRACT_BITS == DFRACT_BITS) |
771 | 0 | FDKmemcpy(pSpectralCoefficient, hConcealmentInfo->spectralCoefficient, |
772 | 0 | 1024 * sizeof(FIXP_DBL)); |
773 | | #else |
774 | | for (i = 1024; i != 0; i--) { |
775 | | *pSpec-- = FX_CNCL2FX_DBL(*pCncl--); |
776 | | } |
777 | | #endif |
778 | 0 | } else { |
779 | | /* clear scale factors */ |
780 | 0 | FDKmemclear(pSpecScale, 8 * sizeof(SHORT)); |
781 | | |
782 | | /* clear buffer */ |
783 | 0 | FDKmemclear(pSpectralCoefficient, 1024 * sizeof(FIXP_CNCL)); |
784 | 0 | } |
785 | 0 | } |
786 | 0 | } |
787 | | /* update history */ |
788 | 0 | hConcealmentInfo->prevFrameOk[0] = hConcealmentInfo->prevFrameOk[1]; |
789 | 0 | hConcealmentInfo->prevFrameOk[1] = frameOk; |
790 | |
|
791 | 0 | return mute_release_active ? -1 : appliedProcessing; |
792 | 0 | } |
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 | | */ |
800 | | static int CConcealment_ApplyNoise( |
801 | | CConcealmentInfo *pConcealmentInfo, |
802 | | CAacDecoderChannelInfo *pAacDecoderChannelInfo, |
803 | | CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, |
804 | | const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame, |
805 | 0 | const UINT flags) { |
806 | 0 | FIXP_DBL *pSpectralCoefficient = |
807 | 0 | SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); |
808 | 0 | CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; |
809 | |
|
810 | 0 | int appliedProcessing = 0; |
811 | |
|
812 | 0 | FDK_ASSERT(pConcealmentInfo != NULL); |
813 | 0 | FDK_ASSERT((samplesPerFrame >= 120) && (samplesPerFrame <= 1024)); |
814 | | |
815 | 0 | switch (pConcealmentInfo->concealState) { |
816 | 0 | case ConcealState_Ok: |
817 | | /* Nothing to do here! */ |
818 | 0 | break; |
819 | | |
820 | 0 | case ConcealState_Single: |
821 | 0 | case ConcealState_FadeOut: |
822 | 0 | appliedProcessing = CConcealment_ApplyFadeOut( |
823 | 0 | /*mode =*/1, pConcealmentInfo, pAacDecoderStaticChannelInfo, |
824 | 0 | samplesPerFrame, pAacDecoderChannelInfo); |
825 | 0 | break; |
826 | | |
827 | 0 | case ConcealState_Mute: { |
828 | | /* set dummy window parameters */ |
829 | 0 | pIcsInfo->Valid = 0; /* Trigger the generation of a consitent IcsInfo */ |
830 | 0 | pIcsInfo->WindowShape = |
831 | 0 | pConcealmentInfo->windowShape; /* Prevent an invalid WindowShape |
832 | | (required for F/T transform) */ |
833 | 0 | pIcsInfo->WindowSequence = |
834 | 0 | CConcealment_GetWinSeq(pConcealmentInfo->windowSequence); |
835 | 0 | pConcealmentInfo->windowSequence = |
836 | 0 | 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 | 0 | FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL)); |
843 | 0 | FDKmemclear(pConcealmentInfo->spectralCoefficient, |
844 | 0 | samplesPerFrame * sizeof(FIXP_DBL)); |
845 | |
|
846 | 0 | appliedProcessing = 1; |
847 | 0 | } break; |
848 | | |
849 | 0 | case ConcealState_FadeIn: { |
850 | | /* TimeDomainFading: */ |
851 | | /* Attenuation of signal is done in CConcealment_TDFading() */ |
852 | |
|
853 | 0 | appliedProcessing = 1; |
854 | 0 | } break; |
855 | | |
856 | 0 | default: |
857 | | /* we shouldn't come here anyway */ |
858 | 0 | FDK_ASSERT(0); |
859 | 0 | break; |
860 | 0 | } |
861 | | |
862 | 0 | return appliedProcessing; |
863 | 0 | } |
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 | | */ |
872 | | static int CConcealment_ApplyInter( |
873 | | CConcealmentInfo *pConcealmentInfo, |
874 | | CAacDecoderChannelInfo *pAacDecoderChannelInfo, |
875 | | const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame, |
876 | 0 | const int improveTonal, const int frameOk, const int mute_release_active) { |
877 | 0 | #if defined(FDK_ASSERT_ENABLE) |
878 | 0 | CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams; |
879 | 0 | #endif |
880 | |
|
881 | 0 | FIXP_DBL *pSpectralCoefficient = |
882 | 0 | SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); |
883 | 0 | CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; |
884 | 0 | SHORT *pSpecScale = pAacDecoderChannelInfo->specScale; |
885 | |
|
886 | 0 | int sfbEnergyPrev[64]; |
887 | 0 | int sfbEnergyAct[64]; |
888 | |
|
889 | 0 | int i, appliedProcessing = 0; |
890 | | |
891 | | /* clear/init */ |
892 | 0 | FDKmemclear(sfbEnergyPrev, 64 * sizeof(int)); |
893 | 0 | FDKmemclear(sfbEnergyAct, 64 * sizeof(int)); |
894 | |
|
895 | 0 | if (!frameOk || mute_release_active) { |
896 | | /* Restore last frame from concealment buffer */ |
897 | 0 | pIcsInfo->WindowShape = pConcealmentInfo->windowShape; |
898 | 0 | pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence; |
899 | | |
900 | | /* Restore spectral data */ |
901 | 0 | for (i = 0; i < samplesPerFrame; i++) { |
902 | 0 | pSpectralCoefficient[i] = |
903 | 0 | FX_CNCL2FX_DBL(pConcealmentInfo->spectralCoefficient[i]); |
904 | 0 | } |
905 | | |
906 | | /* Restore scale factors */ |
907 | 0 | FDKmemcpy(pSpecScale, pConcealmentInfo->specScale, 8 * sizeof(SHORT)); |
908 | 0 | } |
909 | | |
910 | | /* if previous frame was not ok */ |
911 | 0 | 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 | 0 | if (frameOk && pConcealmentInfo->prevFrameOk[0] && !mute_release_active) { |
917 | 0 | appliedProcessing = 1; |
918 | | |
919 | | /* Interpolate both frames in order to generate the current output frame |
920 | | * (f_(n-1)). */ |
921 | 0 | 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 | 0 | int wnd; |
927 | |
|
928 | 0 | if (pConcealmentInfo->windowSequence == |
929 | 0 | BLOCK_SHORT) { /* f_n == BLOCK_SHORT */ |
930 | | /* short--short---short interpolation */ |
931 | |
|
932 | 0 | int scaleFactorBandsTotal = |
933 | 0 | pSamplingRateInfo->NumberOfScaleFactorBands_Short; |
934 | 0 | const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short; |
935 | 0 | pIcsInfo->WindowShape = (samplesPerFrame <= 512) ? 2 : 1; |
936 | 0 | pIcsInfo->WindowSequence = BLOCK_SHORT; |
937 | |
|
938 | 0 | for (wnd = 0; wnd < 8; wnd++) { |
939 | 0 | CConcealment_CalcBandEnergy( |
940 | 0 | &pSpectralCoefficient[wnd * |
941 | 0 | (samplesPerFrame / 8)], /* spec_(n-2) */ |
942 | 0 | pSamplingRateInfo, BLOCK_SHORT, CConcealment_NoExpand, |
943 | 0 | sfbEnergyPrev); |
944 | |
|
945 | 0 | CConcealment_CalcBandEnergy( |
946 | 0 | &pConcealmentInfo->spectralCoefficient[wnd * (samplesPerFrame / |
947 | 0 | 8)], /* spec_n */ |
948 | 0 | pSamplingRateInfo, BLOCK_SHORT, CConcealment_NoExpand, |
949 | 0 | sfbEnergyAct); |
950 | |
|
951 | 0 | CConcealment_InterpolateBuffer( |
952 | 0 | &pSpectralCoefficient[wnd * |
953 | 0 | (samplesPerFrame / 8)], /* spec_(n-1) */ |
954 | 0 | &pSpecScale[wnd], &pConcealmentInfo->specScale[wnd], |
955 | 0 | &pSpecScale[wnd], sfbEnergyPrev, sfbEnergyAct, |
956 | 0 | scaleFactorBandsTotal, pSfbOffset); |
957 | 0 | } |
958 | 0 | } else { /* f_n != BLOCK_SHORT */ |
959 | | /* short---long---long interpolation */ |
960 | |
|
961 | 0 | int scaleFactorBandsTotal = |
962 | 0 | pSamplingRateInfo->NumberOfScaleFactorBands_Long; |
963 | 0 | const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long; |
964 | 0 | SHORT specScaleOut; |
965 | |
|
966 | 0 | CConcealment_CalcBandEnergy( |
967 | 0 | &pSpectralCoefficient[samplesPerFrame - |
968 | 0 | (samplesPerFrame / |
969 | 0 | 8)], /* [wnd] spec_(n-2) */ |
970 | 0 | pSamplingRateInfo, BLOCK_SHORT, CConcealment_Expand, |
971 | 0 | sfbEnergyAct); |
972 | |
|
973 | 0 | CConcealment_CalcBandEnergy( |
974 | 0 | pConcealmentInfo->spectralCoefficient, /* spec_n */ |
975 | 0 | pSamplingRateInfo, BLOCK_LONG, CConcealment_NoExpand, |
976 | 0 | sfbEnergyPrev); |
977 | |
|
978 | 0 | pIcsInfo->WindowShape = 0; |
979 | 0 | pIcsInfo->WindowSequence = BLOCK_STOP; |
980 | |
|
981 | 0 | for (i = 0; i < samplesPerFrame; i++) { |
982 | 0 | pSpectralCoefficient[i] = |
983 | 0 | pConcealmentInfo->spectralCoefficient[i]; /* spec_n */ |
984 | 0 | } |
985 | |
|
986 | 0 | for (i = 0; i < 8; i++) { /* search for max(specScale) */ |
987 | 0 | if (pSpecScale[i] > pSpecScale[0]) { |
988 | 0 | pSpecScale[0] = pSpecScale[i]; |
989 | 0 | } |
990 | 0 | } |
991 | |
|
992 | 0 | CConcealment_InterpolateBuffer( |
993 | 0 | pSpectralCoefficient, /* spec_(n-1) */ |
994 | 0 | &pConcealmentInfo->specScale[0], &pSpecScale[0], &specScaleOut, |
995 | 0 | sfbEnergyPrev, sfbEnergyAct, scaleFactorBandsTotal, pSfbOffset); |
996 | |
|
997 | 0 | pSpecScale[0] = specScaleOut; |
998 | 0 | } |
999 | 0 | } else { |
1000 | | /* long--??????--short, long--??????--long interpolation */ |
1001 | | /* long---long---short, long---long---long interpolation */ |
1002 | |
|
1003 | 0 | int scaleFactorBandsTotal = |
1004 | 0 | pSamplingRateInfo->NumberOfScaleFactorBands_Long; |
1005 | 0 | const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long; |
1006 | 0 | SHORT specScaleAct = pConcealmentInfo->specScale[0]; |
1007 | |
|
1008 | 0 | CConcealment_CalcBandEnergy(pSpectralCoefficient, /* spec_(n-2) */ |
1009 | 0 | pSamplingRateInfo, BLOCK_LONG, |
1010 | 0 | CConcealment_NoExpand, sfbEnergyPrev); |
1011 | |
|
1012 | 0 | if (pConcealmentInfo->windowSequence == |
1013 | 0 | BLOCK_SHORT) { /* f_n == BLOCK_SHORT */ |
1014 | | /* long---long---short interpolation */ |
1015 | |
|
1016 | 0 | pIcsInfo->WindowShape = (samplesPerFrame <= 512) ? 2 : 1; |
1017 | 0 | pIcsInfo->WindowSequence = BLOCK_START; |
1018 | |
|
1019 | 0 | for (i = 1; i < 8; i++) { /* search for max(specScale) */ |
1020 | 0 | if (pConcealmentInfo->specScale[i] > specScaleAct) { |
1021 | 0 | specScaleAct = pConcealmentInfo->specScale[i]; |
1022 | 0 | } |
1023 | 0 | } |
1024 | | |
1025 | | /* Expand first short spectrum */ |
1026 | 0 | CConcealment_CalcBandEnergy( |
1027 | 0 | pConcealmentInfo->spectralCoefficient, /* spec_n */ |
1028 | 0 | pSamplingRateInfo, BLOCK_SHORT, CConcealment_Expand, /* !!! */ |
1029 | 0 | sfbEnergyAct); |
1030 | 0 | } else { |
1031 | | /* long---long---long interpolation */ |
1032 | |
|
1033 | 0 | pIcsInfo->WindowShape = 0; |
1034 | 0 | pIcsInfo->WindowSequence = BLOCK_LONG; |
1035 | |
|
1036 | 0 | CConcealment_CalcBandEnergy( |
1037 | 0 | pConcealmentInfo->spectralCoefficient, /* spec_n */ |
1038 | 0 | pSamplingRateInfo, BLOCK_LONG, CConcealment_NoExpand, |
1039 | 0 | sfbEnergyAct); |
1040 | 0 | } |
1041 | |
|
1042 | 0 | CConcealment_InterpolateBuffer( |
1043 | 0 | pSpectralCoefficient, /* spec_(n-1) */ |
1044 | 0 | &pSpecScale[0], &specScaleAct, &pSpecScale[0], sfbEnergyPrev, |
1045 | 0 | sfbEnergyAct, scaleFactorBandsTotal, pSfbOffset); |
1046 | 0 | } |
1047 | 0 | } |
1048 | | |
1049 | | /* Noise substitution of sign of the output spectral coefficients */ |
1050 | 0 | CConcealment_ApplyRandomSign(pConcealmentInfo->iRandomPhase, |
1051 | 0 | pSpectralCoefficient, samplesPerFrame); |
1052 | | /* Increment random phase index to avoid repetition artifacts. */ |
1053 | 0 | pConcealmentInfo->iRandomPhase = |
1054 | 0 | (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1); |
1055 | 0 | } |
1056 | | |
1057 | | /* scale spectrum according to concealment state */ |
1058 | 0 | switch (pConcealmentInfo->concealState) { |
1059 | 0 | case ConcealState_Single: |
1060 | 0 | appliedProcessing = 1; |
1061 | 0 | break; |
1062 | | |
1063 | 0 | case ConcealState_FadeOut: { |
1064 | 0 | FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0); |
1065 | 0 | FDK_ASSERT(pConcealmentInfo->cntFadeFrames < |
1066 | 0 | CONCEAL_MAX_NUM_FADE_FACTORS); |
1067 | 0 | FDK_ASSERT(pConcealmentInfo->cntFadeFrames < |
1068 | 0 | pConcealCommonData->numFadeOutFrames); |
1069 | | |
1070 | | /* TimeDomainFading: */ |
1071 | | /* Attenuation of signal is done in CConcealment_TDFading() */ |
1072 | | |
1073 | 0 | appliedProcessing = 1; |
1074 | 0 | } break; |
1075 | | |
1076 | 0 | case ConcealState_FadeIn: { |
1077 | 0 | FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0); |
1078 | 0 | FDK_ASSERT(pConcealmentInfo->cntFadeFrames < |
1079 | 0 | CONCEAL_MAX_NUM_FADE_FACTORS); |
1080 | 0 | FDK_ASSERT(pConcealmentInfo->cntFadeFrames < |
1081 | 0 | pConcealCommonData->numFadeInFrames); |
1082 | | |
1083 | | /* TimeDomainFading: */ |
1084 | | /* Attenuation of signal is done in CConcealment_TDFading() */ |
1085 | | |
1086 | 0 | appliedProcessing = 1; |
1087 | 0 | } break; |
1088 | | |
1089 | 0 | case ConcealState_Mute: { |
1090 | | /* set dummy window parameters */ |
1091 | 0 | pIcsInfo->Valid = 0; /* Trigger the generation of a consitent IcsInfo */ |
1092 | 0 | pIcsInfo->WindowShape = |
1093 | 0 | pConcealmentInfo->windowShape; /* Prevent an invalid WindowShape |
1094 | | (required for F/T transform) */ |
1095 | 0 | pIcsInfo->WindowSequence = |
1096 | 0 | CConcealment_GetWinSeq(pConcealmentInfo->windowSequence); |
1097 | 0 | pConcealmentInfo->windowSequence = |
1098 | 0 | 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 | 0 | FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL)); |
1105 | |
|
1106 | 0 | appliedProcessing = 1; |
1107 | 0 | } break; |
1108 | | |
1109 | 0 | default: |
1110 | | /* nothing to do here */ |
1111 | 0 | break; |
1112 | 0 | } |
1113 | | |
1114 | 0 | return appliedProcessing; |
1115 | 0 | } |
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 | | */ |
1123 | | static void CConcealment_CalcBandEnergy( |
1124 | | FIXP_DBL *spectrum, const SamplingRateInfo *pSamplingRateInfo, |
1125 | 0 | const int blockType, CConcealmentExpandType expandType, int *sfbEnergy) { |
1126 | 0 | const SHORT *pSfbOffset; |
1127 | 0 | 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 | 0 | line = 0; |
1133 | |
|
1134 | 0 | switch (blockType) { |
1135 | 0 | case BLOCK_LONG: |
1136 | 0 | case BLOCK_START: |
1137 | 0 | case BLOCK_STOP: |
1138 | |
|
1139 | 0 | if (expandType == CConcealment_NoExpand) { |
1140 | | /* standard long calculation */ |
1141 | 0 | scaleFactorBandsTotal = |
1142 | 0 | pSamplingRateInfo->NumberOfScaleFactorBands_Long; |
1143 | 0 | pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long; |
1144 | |
|
1145 | 0 | for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) { |
1146 | 0 | FIXP_DBL enAccu = (FIXP_DBL)(LONG)1; |
1147 | 0 | int sfbScale = |
1148 | 0 | (sizeof(LONG) << 3) - |
1149 | 0 | CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1; |
1150 | | /* scaling depends on sfb width. */ |
1151 | 0 | for (; line < pSfbOffset[sfb + 1]; line++) { |
1152 | 0 | enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale; |
1153 | 0 | } |
1154 | 0 | *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1; |
1155 | 0 | } |
1156 | 0 | } else { |
1157 | | /* compress long to short */ |
1158 | 0 | scaleFactorBandsTotal = |
1159 | 0 | pSamplingRateInfo->NumberOfScaleFactorBands_Short; |
1160 | 0 | pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short; |
1161 | |
|
1162 | 0 | for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) { |
1163 | 0 | FIXP_DBL enAccu = (FIXP_DBL)(LONG)1; |
1164 | 0 | int sfbScale = |
1165 | 0 | (sizeof(LONG) << 3) - |
1166 | 0 | CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1; |
1167 | | /* scaling depends on sfb width. */ |
1168 | 0 | for (; line < pSfbOffset[sfb + 1] << 3; line++) { |
1169 | 0 | enAccu += |
1170 | 0 | (enAccu + (fPow2Div2(*(spectrum + line)) >> sfbScale)) >> 3; |
1171 | 0 | } |
1172 | 0 | *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1; |
1173 | 0 | } |
1174 | 0 | } |
1175 | 0 | break; |
1176 | | |
1177 | 0 | case BLOCK_SHORT: |
1178 | |
|
1179 | 0 | if (expandType == CConcealment_NoExpand) { |
1180 | | /* standard short calculation */ |
1181 | 0 | scaleFactorBandsTotal = |
1182 | 0 | pSamplingRateInfo->NumberOfScaleFactorBands_Short; |
1183 | 0 | pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short; |
1184 | |
|
1185 | 0 | for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) { |
1186 | 0 | FIXP_DBL enAccu = (FIXP_DBL)(LONG)1; |
1187 | 0 | int sfbScale = |
1188 | 0 | (sizeof(LONG) << 3) - |
1189 | 0 | CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1; |
1190 | | /* scaling depends on sfb width. */ |
1191 | 0 | for (; line < pSfbOffset[sfb + 1]; line++) { |
1192 | 0 | enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale; |
1193 | 0 | } |
1194 | 0 | *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1; |
1195 | 0 | } |
1196 | 0 | } else { |
1197 | | /* expand short to long spectrum */ |
1198 | 0 | scaleFactorBandsTotal = |
1199 | 0 | pSamplingRateInfo->NumberOfScaleFactorBands_Long; |
1200 | 0 | pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long; |
1201 | |
|
1202 | 0 | for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) { |
1203 | 0 | FIXP_DBL enAccu = (FIXP_DBL)(LONG)1; |
1204 | 0 | int sfbScale = |
1205 | 0 | (sizeof(LONG) << 3) - |
1206 | 0 | CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1; |
1207 | | /* scaling depends on sfb width. */ |
1208 | 0 | for (; line < pSfbOffset[sfb + 1]; line++) { |
1209 | 0 | enAccu += fPow2Div2(*(spectrum + (line >> 3))) >> sfbScale; |
1210 | 0 | } |
1211 | 0 | *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1; |
1212 | 0 | } |
1213 | 0 | } |
1214 | 0 | break; |
1215 | 0 | } |
1216 | 0 | } |
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 | | */ |
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 | 0 | const SHORT *pSfbOffset) { |
1230 | 0 | int sfb, line = 0; |
1231 | 0 | int fac_shift; |
1232 | 0 | int fac_mod; |
1233 | |
|
1234 | 0 | for (sfb = 0; sfb < sfbCnt; sfb++) { |
1235 | 0 | fac_shift = |
1236 | 0 | enPrv[sfb] - enAct[sfb] + ((*pSpecScaleAct - *pSpecScalePrv) << 1); |
1237 | 0 | fac_mod = fac_shift & 3; |
1238 | 0 | fac_shift = (fac_shift >> 2) + 1; |
1239 | 0 | fac_shift += *pSpecScalePrv - fixMax(*pSpecScalePrv, *pSpecScaleAct); |
1240 | 0 | fac_shift = fMax(fMin(fac_shift, DFRACT_BITS - 1), -(DFRACT_BITS - 1)); |
1241 | |
|
1242 | 0 | for (; line < pSfbOffset[sfb + 1]; line++) { |
1243 | 0 | FIXP_DBL accu = fMult(*(spectrum + line), facMod4Table[fac_mod]); |
1244 | 0 | *(spectrum + line) = scaleValue(accu, fac_shift); |
1245 | 0 | } |
1246 | 0 | } |
1247 | 0 | *pSpecScaleOut = fixMax(*pSpecScalePrv, *pSpecScaleAct); |
1248 | 0 | } |
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 | | |
1262 | | static INT findEquiFadeFrame(CConcealParams *pConcealCommonData, |
1263 | 0 | INT actFadeIndex, int direction) { |
1264 | 0 | FIXP_SGL *pFactor; |
1265 | 0 | FIXP_SGL referenceVal; |
1266 | 0 | FIXP_SGL minDiff = (FIXP_SGL)MAXVAL_SGL; |
1267 | |
|
1268 | 0 | INT nextFadeIndex = 0; |
1269 | |
|
1270 | 0 | int i; |
1271 | | |
1272 | | /* init depending on direction */ |
1273 | 0 | if (direction == 0) { /* FADE-OUT => FADE-IN */ |
1274 | 0 | if (actFadeIndex < 0) { |
1275 | 0 | referenceVal = (FIXP_SGL)MAXVAL_SGL; |
1276 | 0 | } else { |
1277 | 0 | referenceVal = pConcealCommonData->fadeOutFactor[actFadeIndex] >> 1; |
1278 | 0 | } |
1279 | 0 | pFactor = pConcealCommonData->fadeInFactor; |
1280 | 0 | } else { /* FADE-IN => FADE-OUT */ |
1281 | 0 | if (actFadeIndex < 0) { |
1282 | 0 | referenceVal = (FIXP_SGL)MAXVAL_SGL; |
1283 | 0 | } else { |
1284 | 0 | referenceVal = pConcealCommonData->fadeInFactor[actFadeIndex] >> 1; |
1285 | 0 | } |
1286 | 0 | pFactor = pConcealCommonData->fadeOutFactor; |
1287 | 0 | } |
1288 | | |
1289 | | /* search for minimum difference */ |
1290 | 0 | for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) { |
1291 | 0 | FIXP_SGL diff = fixp_abs((pFactor[i] >> 1) - referenceVal); |
1292 | 0 | if (diff < minDiff) { |
1293 | 0 | minDiff = diff; |
1294 | 0 | nextFadeIndex = i; |
1295 | 0 | } |
1296 | 0 | } |
1297 | | |
1298 | | /* check and adjust depending on direction */ |
1299 | 0 | if (direction == 0) { /* FADE-OUT => FADE-IN */ |
1300 | 0 | if (nextFadeIndex > pConcealCommonData->numFadeInFrames) { |
1301 | 0 | nextFadeIndex = fMax(pConcealCommonData->numFadeInFrames - 1, 0); |
1302 | 0 | } |
1303 | 0 | if (((pFactor[nextFadeIndex] >> 1) <= referenceVal) && |
1304 | 0 | (nextFadeIndex > 0)) { |
1305 | 0 | nextFadeIndex -= 1; |
1306 | 0 | } |
1307 | 0 | } else { /* FADE-IN => FADE-OUT */ |
1308 | 0 | if (((pFactor[nextFadeIndex] >> 1) >= referenceVal) && |
1309 | 0 | (nextFadeIndex < CONCEAL_MAX_NUM_FADE_FACTORS - 1)) { |
1310 | 0 | nextFadeIndex += 1; |
1311 | 0 | } |
1312 | 0 | } |
1313 | |
|
1314 | 0 | return (nextFadeIndex); |
1315 | 0 | } |
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 | | */ |
1323 | | static void CConcealment_UpdateState( |
1324 | | CConcealmentInfo *pConcealmentInfo, int frameOk, |
1325 | | CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, |
1326 | 0 | const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo) { |
1327 | 0 | CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams; |
1328 | |
|
1329 | 0 | switch (pConcealCommonData->method) { |
1330 | 0 | case ConcealMethodNoise: { |
1331 | 0 | if (pConcealmentInfo->concealState != ConcealState_Ok) { |
1332 | | /* count the valid frames during concealment process */ |
1333 | 0 | if (frameOk) { |
1334 | 0 | pConcealmentInfo->cntValidFrames += 1; |
1335 | 0 | } else { |
1336 | 0 | pConcealmentInfo->cntValidFrames = 0; |
1337 | 0 | } |
1338 | 0 | } |
1339 | | |
1340 | | /* -- STATE MACHINE for Noise Substitution -- */ |
1341 | 0 | switch (pConcealmentInfo->concealState) { |
1342 | 0 | case ConcealState_Ok: |
1343 | 0 | if (!frameOk) { |
1344 | 0 | pConcealmentInfo->cntFadeFrames = 0; |
1345 | 0 | pConcealmentInfo->cntValidFrames = 0; |
1346 | 0 | pConcealmentInfo->attGrpOffset[0] = 0; |
1347 | 0 | pConcealmentInfo->attGrpOffset[1] = 0; |
1348 | 0 | pConcealmentInfo->winGrpOffset[0] = 0; |
1349 | 0 | pConcealmentInfo->winGrpOffset[1] = 0; |
1350 | 0 | if (pConcealCommonData->numFadeOutFrames > 0) { |
1351 | | /* change to state SINGLE-FRAME-LOSS */ |
1352 | 0 | pConcealmentInfo->concealState = ConcealState_Single; |
1353 | | /* mode 0 just updates the Fading counter */ |
1354 | 0 | CConcealment_ApplyFadeOut( |
1355 | 0 | /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo, |
1356 | 0 | samplesPerFrame, pAacDecoderChannelInfo); |
1357 | |
|
1358 | 0 | } else { |
1359 | | /* change to state MUTE */ |
1360 | 0 | pConcealmentInfo->concealState = ConcealState_Mute; |
1361 | 0 | } |
1362 | 0 | } |
1363 | 0 | break; |
1364 | | |
1365 | 0 | case ConcealState_Single: /* Just a pre-stage before fade-out begins. |
1366 | | Stay here only one frame! */ |
1367 | 0 | if (frameOk) { |
1368 | | /* change to state OK */ |
1369 | 0 | pConcealmentInfo->concealState = ConcealState_Ok; |
1370 | 0 | } else { |
1371 | 0 | if (pConcealmentInfo->cntFadeFrames >= |
1372 | 0 | pConcealCommonData->numFadeOutFrames) { |
1373 | | /* change to state MUTE */ |
1374 | 0 | pConcealmentInfo->concealState = ConcealState_Mute; |
1375 | 0 | } else { |
1376 | | /* change to state FADE-OUT */ |
1377 | 0 | pConcealmentInfo->concealState = ConcealState_FadeOut; |
1378 | | /* mode 0 just updates the Fading counter */ |
1379 | 0 | CConcealment_ApplyFadeOut( |
1380 | 0 | /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo, |
1381 | 0 | samplesPerFrame, pAacDecoderChannelInfo); |
1382 | 0 | } |
1383 | 0 | } |
1384 | 0 | break; |
1385 | | |
1386 | 0 | case ConcealState_FadeOut: |
1387 | 0 | if (pConcealmentInfo->cntValidFrames > |
1388 | 0 | pConcealCommonData->numMuteReleaseFrames) { |
1389 | 0 | if (pConcealCommonData->numFadeInFrames > 0) { |
1390 | | /* change to state FADE-IN */ |
1391 | 0 | pConcealmentInfo->concealState = ConcealState_FadeIn; |
1392 | 0 | pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( |
1393 | 0 | pConcealCommonData, pConcealmentInfo->cntFadeFrames, |
1394 | 0 | 0 /* FadeOut -> FadeIn */); |
1395 | 0 | } else { |
1396 | | /* change to state OK */ |
1397 | 0 | pConcealmentInfo->concealState = ConcealState_Ok; |
1398 | 0 | } |
1399 | 0 | } else { |
1400 | 0 | if (frameOk) { |
1401 | | /* we have good frame information but stay fully in concealment - |
1402 | | * reset winGrpOffset/attGrpOffset */ |
1403 | 0 | pConcealmentInfo->winGrpOffset[0] = 0; |
1404 | 0 | pConcealmentInfo->winGrpOffset[1] = 0; |
1405 | 0 | pConcealmentInfo->attGrpOffset[0] = 0; |
1406 | 0 | pConcealmentInfo->attGrpOffset[1] = 0; |
1407 | 0 | } |
1408 | 0 | if (pConcealmentInfo->cntFadeFrames >= |
1409 | 0 | pConcealCommonData->numFadeOutFrames) { |
1410 | | /* change to state MUTE */ |
1411 | 0 | pConcealmentInfo->concealState = ConcealState_Mute; |
1412 | 0 | } else /* Stay in FADE-OUT */ |
1413 | 0 | { |
1414 | | /* mode 0 just updates the Fading counter */ |
1415 | 0 | CConcealment_ApplyFadeOut( |
1416 | 0 | /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo, |
1417 | 0 | samplesPerFrame, pAacDecoderChannelInfo); |
1418 | 0 | } |
1419 | 0 | } |
1420 | 0 | break; |
1421 | | |
1422 | 0 | case ConcealState_Mute: |
1423 | 0 | if (pConcealmentInfo->cntValidFrames > |
1424 | 0 | pConcealCommonData->numMuteReleaseFrames) { |
1425 | 0 | if (pConcealCommonData->numFadeInFrames > 0) { |
1426 | | /* change to state FADE-IN */ |
1427 | 0 | pConcealmentInfo->concealState = ConcealState_FadeIn; |
1428 | 0 | pConcealmentInfo->cntFadeFrames = |
1429 | 0 | pConcealCommonData->numFadeInFrames - 1; |
1430 | 0 | } else { |
1431 | | /* change to state OK */ |
1432 | 0 | pConcealmentInfo->concealState = ConcealState_Ok; |
1433 | 0 | } |
1434 | 0 | } else { |
1435 | 0 | if (frameOk) { |
1436 | | /* we have good frame information but stay fully in concealment - |
1437 | | * reset winGrpOffset/attGrpOffset */ |
1438 | 0 | pConcealmentInfo->winGrpOffset[0] = 0; |
1439 | 0 | pConcealmentInfo->winGrpOffset[1] = 0; |
1440 | 0 | pConcealmentInfo->attGrpOffset[0] = 0; |
1441 | 0 | pConcealmentInfo->attGrpOffset[1] = 0; |
1442 | 0 | } |
1443 | 0 | } |
1444 | 0 | break; |
1445 | | |
1446 | 0 | case ConcealState_FadeIn: |
1447 | 0 | pConcealmentInfo->cntFadeFrames -= 1; |
1448 | 0 | if (frameOk) { |
1449 | 0 | if (pConcealmentInfo->cntFadeFrames < 0) { |
1450 | | /* change to state OK */ |
1451 | 0 | pConcealmentInfo->concealState = ConcealState_Ok; |
1452 | 0 | } |
1453 | 0 | } else { |
1454 | 0 | if (pConcealCommonData->numFadeOutFrames > 0) { |
1455 | | /* change to state FADE-OUT */ |
1456 | 0 | pConcealmentInfo->concealState = ConcealState_FadeOut; |
1457 | 0 | pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( |
1458 | 0 | pConcealCommonData, pConcealmentInfo->cntFadeFrames + 1, |
1459 | 0 | 1 /* FadeIn -> FadeOut */); |
1460 | 0 | pConcealmentInfo->winGrpOffset[0] = 0; |
1461 | 0 | pConcealmentInfo->winGrpOffset[1] = 0; |
1462 | 0 | pConcealmentInfo->attGrpOffset[0] = 0; |
1463 | 0 | pConcealmentInfo->attGrpOffset[1] = 0; |
1464 | |
|
1465 | 0 | pConcealmentInfo |
1466 | 0 | ->cntFadeFrames--; /* decrease because |
1467 | | CConcealment_ApplyFadeOut() will |
1468 | | increase, accordingly */ |
1469 | | /* mode 0 just updates the Fading counter */ |
1470 | 0 | CConcealment_ApplyFadeOut( |
1471 | 0 | /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo, |
1472 | 0 | samplesPerFrame, pAacDecoderChannelInfo); |
1473 | 0 | } else { |
1474 | | /* change to state MUTE */ |
1475 | 0 | pConcealmentInfo->concealState = ConcealState_Mute; |
1476 | 0 | } |
1477 | 0 | } |
1478 | 0 | break; |
1479 | | |
1480 | 0 | default: |
1481 | 0 | FDK_ASSERT(0); |
1482 | 0 | break; |
1483 | 0 | } |
1484 | 0 | } break; |
1485 | | |
1486 | 0 | case ConcealMethodInter: |
1487 | 0 | case ConcealMethodTonal: { |
1488 | 0 | if (pConcealmentInfo->concealState != ConcealState_Ok) { |
1489 | | /* count the valid frames during concealment process */ |
1490 | 0 | if (pConcealmentInfo->prevFrameOk[1] || |
1491 | 0 | (pConcealmentInfo->prevFrameOk[0] && |
1492 | 0 | !pConcealmentInfo->prevFrameOk[1] && frameOk)) { |
1493 | | /* The frame is OK even if it can be estimated by the energy |
1494 | | * interpolation algorithm */ |
1495 | 0 | pConcealmentInfo->cntValidFrames += 1; |
1496 | 0 | } else { |
1497 | 0 | pConcealmentInfo->cntValidFrames = 0; |
1498 | 0 | } |
1499 | 0 | } |
1500 | | |
1501 | | /* -- STATE MACHINE for energy interpolation -- */ |
1502 | 0 | switch (pConcealmentInfo->concealState) { |
1503 | 0 | case ConcealState_Ok: |
1504 | 0 | if (!(pConcealmentInfo->prevFrameOk[1] || |
1505 | 0 | (pConcealmentInfo->prevFrameOk[0] && |
1506 | 0 | !pConcealmentInfo->prevFrameOk[1] && frameOk))) { |
1507 | 0 | if (pConcealCommonData->numFadeOutFrames > 0) { |
1508 | | /* Fade out only if the energy interpolation algorithm can not be |
1509 | | * applied! */ |
1510 | 0 | pConcealmentInfo->concealState = ConcealState_FadeOut; |
1511 | 0 | } else { |
1512 | | /* change to state MUTE */ |
1513 | 0 | pConcealmentInfo->concealState = ConcealState_Mute; |
1514 | 0 | } |
1515 | 0 | pConcealmentInfo->cntFadeFrames = 0; |
1516 | 0 | pConcealmentInfo->cntValidFrames = 0; |
1517 | 0 | } |
1518 | 0 | break; |
1519 | | |
1520 | 0 | case ConcealState_Single: |
1521 | 0 | pConcealmentInfo->concealState = ConcealState_Ok; |
1522 | 0 | break; |
1523 | | |
1524 | 0 | case ConcealState_FadeOut: |
1525 | 0 | pConcealmentInfo->cntFadeFrames += 1; |
1526 | |
|
1527 | 0 | if (pConcealmentInfo->cntValidFrames > |
1528 | 0 | pConcealCommonData->numMuteReleaseFrames) { |
1529 | 0 | if (pConcealCommonData->numFadeInFrames > 0) { |
1530 | | /* change to state FADE-IN */ |
1531 | 0 | pConcealmentInfo->concealState = ConcealState_FadeIn; |
1532 | 0 | pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( |
1533 | 0 | pConcealCommonData, pConcealmentInfo->cntFadeFrames - 1, |
1534 | 0 | 0 /* FadeOut -> FadeIn */); |
1535 | 0 | } else { |
1536 | | /* change to state OK */ |
1537 | 0 | pConcealmentInfo->concealState = ConcealState_Ok; |
1538 | 0 | } |
1539 | 0 | } else { |
1540 | 0 | if (pConcealmentInfo->cntFadeFrames >= |
1541 | 0 | pConcealCommonData->numFadeOutFrames) { |
1542 | | /* change to state MUTE */ |
1543 | 0 | pConcealmentInfo->concealState = ConcealState_Mute; |
1544 | 0 | } |
1545 | 0 | } |
1546 | 0 | break; |
1547 | | |
1548 | 0 | case ConcealState_Mute: |
1549 | 0 | if (pConcealmentInfo->cntValidFrames > |
1550 | 0 | pConcealCommonData->numMuteReleaseFrames) { |
1551 | 0 | if (pConcealCommonData->numFadeInFrames > 0) { |
1552 | | /* change to state FADE-IN */ |
1553 | 0 | pConcealmentInfo->concealState = ConcealState_FadeIn; |
1554 | 0 | pConcealmentInfo->cntFadeFrames = |
1555 | 0 | pConcealCommonData->numFadeInFrames - 1; |
1556 | 0 | } else { |
1557 | | /* change to state OK */ |
1558 | 0 | pConcealmentInfo->concealState = ConcealState_Ok; |
1559 | 0 | } |
1560 | 0 | } |
1561 | 0 | break; |
1562 | | |
1563 | 0 | case ConcealState_FadeIn: |
1564 | 0 | pConcealmentInfo->cntFadeFrames -= |
1565 | 0 | 1; /* used to address the fade-in factors */ |
1566 | |
|
1567 | 0 | if (frameOk || pConcealmentInfo->prevFrameOk[1]) { |
1568 | 0 | if (pConcealmentInfo->cntFadeFrames < 0) { |
1569 | | /* change to state OK */ |
1570 | 0 | pConcealmentInfo->concealState = ConcealState_Ok; |
1571 | 0 | } |
1572 | 0 | } else { |
1573 | 0 | if (pConcealCommonData->numFadeOutFrames > 0) { |
1574 | | /* change to state FADE-OUT */ |
1575 | 0 | pConcealmentInfo->concealState = ConcealState_FadeOut; |
1576 | 0 | pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( |
1577 | 0 | pConcealCommonData, pConcealmentInfo->cntFadeFrames + 1, |
1578 | 0 | 1 /* FadeIn -> FadeOut */); |
1579 | 0 | } else { |
1580 | | /* change to state MUTE */ |
1581 | 0 | pConcealmentInfo->concealState = ConcealState_Mute; |
1582 | 0 | } |
1583 | 0 | } |
1584 | 0 | break; |
1585 | 0 | } /* End switch(pConcealmentInfo->concealState) */ |
1586 | 0 | } break; |
1587 | | |
1588 | 0 | default: |
1589 | | /* Don't need a state machine for other concealment methods. */ |
1590 | 0 | break; |
1591 | 0 | } |
1592 | 0 | } |
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 | | */ |
1600 | | static void CConcealment_ApplyRandomSign(int randomPhase, FIXP_DBL *spec, |
1601 | 0 | int samplesPerFrame) { |
1602 | 0 | int i; |
1603 | 0 | 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 | 0 | packedSign = AacDec_randomSign[randomPhase >> 4]; |
1610 | 0 | packedSign >>= (randomPhase & 0xf); |
1611 | |
|
1612 | 0 | for (i = 0; i < samplesPerFrame; i++) { |
1613 | 0 | if ((randomPhase & 0xf) == 0) { |
1614 | 0 | packedSign = AacDec_randomSign[randomPhase >> 4]; |
1615 | 0 | } |
1616 | |
|
1617 | 0 | if (packedSign & 0x1) { |
1618 | 0 | spec[i] = -fMax(spec[i], (FIXP_DBL)(MINVAL_DBL + 1)); |
1619 | 0 | } |
1620 | 0 | packedSign >>= 1; |
1621 | |
|
1622 | 0 | randomPhase = (randomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1); |
1623 | 0 | } |
1624 | 0 | } |
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 | | */ |
1635 | | int CConcealment_GetLastFrameOk(CConcealmentInfo *hConcealmentInfo, |
1636 | 0 | const int fBeforeApply) { |
1637 | 0 | int prevFrameOk = 1; |
1638 | |
|
1639 | 0 | if (hConcealmentInfo != NULL) { |
1640 | 0 | prevFrameOk = hConcealmentInfo->prevFrameOk[fBeforeApply & 0x1]; |
1641 | 0 | } |
1642 | |
|
1643 | 0 | return prevFrameOk; |
1644 | 0 | } |
1645 | | |
1646 | | /*! |
1647 | | \brief Get the number of delay frames introduced by concealment technique. |
1648 | | |
1649 | | \return Number of delay frames. |
1650 | | */ |
1651 | 32.1k | UINT CConcealment_GetDelay(CConcealParams *pConcealCommonData) { |
1652 | 32.1k | UINT frameDelay = 0; |
1653 | | |
1654 | 32.1k | if (pConcealCommonData != NULL) { |
1655 | 32.1k | switch (pConcealCommonData->method) { |
1656 | 0 | case ConcealMethodTonal: |
1657 | 27.3k | case ConcealMethodInter: |
1658 | 27.3k | frameDelay = 1; |
1659 | 27.3k | break; |
1660 | 4.81k | default: |
1661 | 4.81k | break; |
1662 | 32.1k | } |
1663 | 32.1k | } |
1664 | | |
1665 | 32.1k | return frameDelay; |
1666 | 32.1k | } |
1667 | | |
1668 | | static int CConcealment_ApplyFadeOut( |
1669 | | int mode, CConcealmentInfo *pConcealmentInfo, |
1670 | | CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, |
1671 | 0 | 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 | 0 | int srcWin, dstWin, numWindows = 1; |
1677 | 0 | int windowLen = samplesPerFrame; |
1678 | 0 | int srcGrpStart = 0; |
1679 | 0 | int winIdxStride = 1; |
1680 | 0 | int numWinGrpPerFac, attIdx, attIdxStride; |
1681 | 0 | int i; |
1682 | 0 | int appliedProcessing = 0; |
1683 | |
|
1684 | 0 | CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; |
1685 | 0 | FIXP_DBL *pSpectralCoefficient = |
1686 | 0 | SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); |
1687 | 0 | SHORT *pSpecScale = pAacDecoderChannelInfo->specScale; |
1688 | | |
1689 | | /* set old window parameters */ |
1690 | 0 | if (pConcealmentInfo->lastRenderMode == AACDEC_RENDER_LPD) { |
1691 | 0 | switch (pAacDecoderStaticChannelInfo->last_lpd_mode) { |
1692 | 0 | case 1: |
1693 | 0 | numWindows = 4; |
1694 | 0 | srcGrpStart = 3; |
1695 | 0 | windowLen = samplesPerFrame >> 2; |
1696 | 0 | break; |
1697 | 0 | case 2: |
1698 | 0 | numWindows = 2; |
1699 | 0 | srcGrpStart = 1; |
1700 | 0 | windowLen = samplesPerFrame >> 1; |
1701 | 0 | winIdxStride = 2; |
1702 | 0 | break; |
1703 | 0 | case 3: |
1704 | 0 | numWindows = 1; |
1705 | 0 | srcGrpStart = 0; |
1706 | 0 | windowLen = samplesPerFrame; |
1707 | 0 | winIdxStride = 4; |
1708 | 0 | break; |
1709 | 0 | } |
1710 | 0 | pConcealmentInfo->lastWinGrpLen = 1; |
1711 | 0 | } else { |
1712 | 0 | pIcsInfo->WindowShape = pConcealmentInfo->windowShape; |
1713 | 0 | pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence; |
1714 | |
|
1715 | 0 | if (pConcealmentInfo->windowSequence == BLOCK_SHORT) { |
1716 | | /* short block handling */ |
1717 | 0 | numWindows = 8; |
1718 | 0 | windowLen = samplesPerFrame >> 3; |
1719 | 0 | srcGrpStart = numWindows - pConcealmentInfo->lastWinGrpLen; |
1720 | 0 | } |
1721 | 0 | } |
1722 | | |
1723 | 0 | attIdxStride = |
1724 | 0 | fMax(1, (int)(numWindows / (pConcealmentInfo->lastWinGrpLen + 1))); |
1725 | | |
1726 | | /* load last state */ |
1727 | 0 | attIdx = pConcealmentInfo->cntFadeFrames; |
1728 | 0 | numWinGrpPerFac = pConcealmentInfo->attGrpOffset[mode]; |
1729 | 0 | srcWin = srcGrpStart + pConcealmentInfo->winGrpOffset[mode]; |
1730 | |
|
1731 | 0 | FDK_ASSERT((srcGrpStart * windowLen + windowLen) <= samplesPerFrame); |
1732 | 0 | FDK_ASSERT((srcWin * windowLen + windowLen) <= 1024); |
1733 | | |
1734 | 0 | for (dstWin = 0; dstWin < numWindows; dstWin += 1) { |
1735 | 0 | FIXP_CNCL *pCncl = |
1736 | 0 | pConcealmentInfo->spectralCoefficient + (srcWin * windowLen); |
1737 | 0 | FIXP_DBL *pOut = pSpectralCoefficient + (dstWin * windowLen); |
1738 | |
|
1739 | 0 | if (mode == 1) { |
1740 | | /* mute if attIdx gets large enaugh */ |
1741 | 0 | if (attIdx > pConcealmentInfo->pConcealParams->numFadeOutFrames) { |
1742 | 0 | FDKmemclear(pCncl, sizeof(FIXP_DBL) * windowLen); |
1743 | 0 | } |
1744 | | |
1745 | | /* restore frequency coefficients from buffer - attenuation is done later |
1746 | | */ |
1747 | 0 | for (i = 0; i < windowLen; i++) { |
1748 | 0 | pOut[i] = pCncl[i]; |
1749 | 0 | } |
1750 | | |
1751 | | /* apply random change of sign for spectral coefficients */ |
1752 | 0 | CConcealment_ApplyRandomSign(pConcealmentInfo->iRandomPhase, pOut, |
1753 | 0 | windowLen); |
1754 | | |
1755 | | /* Increment random phase index to avoid repetition artifacts. */ |
1756 | 0 | pConcealmentInfo->iRandomPhase = |
1757 | 0 | (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1); |
1758 | | |
1759 | | /* set old scale factors */ |
1760 | 0 | pSpecScale[dstWin * winIdxStride] = |
1761 | 0 | pConcealmentInfo->specScale[srcWin * winIdxStride]; |
1762 | 0 | } |
1763 | |
|
1764 | 0 | srcWin += 1; |
1765 | |
|
1766 | 0 | if (srcWin >= numWindows) { |
1767 | | /* end of sequence -> rewind to first window of group */ |
1768 | 0 | srcWin = srcGrpStart; |
1769 | 0 | numWinGrpPerFac += 1; |
1770 | 0 | if (numWinGrpPerFac >= attIdxStride) { |
1771 | 0 | numWinGrpPerFac = 0; |
1772 | 0 | attIdx += 1; |
1773 | 0 | } |
1774 | 0 | } |
1775 | 0 | } |
1776 | | |
1777 | | /* store current state */ |
1778 | |
|
1779 | 0 | pConcealmentInfo->winGrpOffset[mode] = srcWin - srcGrpStart; |
1780 | 0 | FDK_ASSERT((pConcealmentInfo->winGrpOffset[mode] >= 0) && |
1781 | 0 | (pConcealmentInfo->winGrpOffset[mode] < 8)); |
1782 | 0 | pConcealmentInfo->attGrpOffset[mode] = numWinGrpPerFac; |
1783 | 0 | FDK_ASSERT((pConcealmentInfo->attGrpOffset[mode] >= 0) && |
1784 | 0 | (pConcealmentInfo->attGrpOffset[mode] < attIdxStride)); |
1785 | | |
1786 | 0 | if (mode == 0) { |
1787 | 0 | pConcealmentInfo->cntFadeFrames = attIdx; |
1788 | 0 | } |
1789 | |
|
1790 | 0 | appliedProcessing = 1; |
1791 | |
|
1792 | 0 | return appliedProcessing; |
1793 | 0 | } |
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 | | |
1847 | | INT CConcealment_TDFading( |
1848 | | int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo, |
1849 | 0 | 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 | 0 | FIXP_DBL fadeStop, attMute = (FIXP_DBL)0; |
1854 | 0 | int idx = 0, ii; |
1855 | 0 | CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo = |
1856 | 0 | *ppAacDecoderStaticChannelInfo; |
1857 | 0 | CConcealmentInfo *pConcealmentInfo = |
1858 | 0 | &pAacDecoderStaticChannelInfo->concealmentInfo; |
1859 | 0 | CConcealParams *pConcealParams = pConcealmentInfo->pConcealParams; |
1860 | 0 | const CConcealmentState concealState = pConcealmentInfo->concealState; |
1861 | 0 | TDfadingType fadingType; |
1862 | 0 | FIXP_DBL fadingStations[9] = {0}; |
1863 | 0 | int fadingSteps[8] = {0}; |
1864 | 0 | const FIXP_DBL fadeStart = |
1865 | 0 | pConcealmentInfo |
1866 | 0 | ->fade_old; /* start fading at last end-of-frame attenuation */ |
1867 | 0 | FIXP_SGL *fadeFactor = pConcealParams->fadeOutFactor; |
1868 | 0 | const INT cntFadeFrames = pConcealmentInfo->cntFadeFrames; |
1869 | 0 | int TDFadeOutStopBeforeMute = 1; |
1870 | 0 | int TDFadeInStopBeforeFullLevel = 1; |
1871 | | |
1872 | | /* |
1873 | | determine Fading behaviour (end-of-frame attenuation and fading type) (1.) |
1874 | | */ |
1875 | |
|
1876 | 0 | switch (concealState) { |
1877 | 0 | case ConcealState_Single: |
1878 | 0 | case ConcealState_Mute: |
1879 | 0 | case ConcealState_FadeOut: |
1880 | 0 | idx = (pConcealParams->method == ConcealMethodNoise) ? cntFadeFrames - 1 |
1881 | 0 | : cntFadeFrames; |
1882 | 0 | fadingType = FADE_TIMEDOMAIN; |
1883 | |
|
1884 | 0 | if (concealState == ConcealState_Mute || |
1885 | 0 | (cntFadeFrames + TDFadeOutStopBeforeMute) > |
1886 | 0 | pConcealmentInfo->pConcealParams->numFadeOutFrames) { |
1887 | 0 | fadingType = FADE_TIMEDOMAIN_TOSPECTRALMUTE; |
1888 | 0 | } |
1889 | |
|
1890 | 0 | break; |
1891 | 0 | case ConcealState_FadeIn: |
1892 | 0 | idx = cntFadeFrames; |
1893 | 0 | idx -= TDFadeInStopBeforeFullLevel; |
1894 | 0 | FDK_FALLTHROUGH; |
1895 | 0 | case ConcealState_Ok: |
1896 | 0 | fadeFactor = pConcealParams->fadeInFactor; |
1897 | 0 | idx = (concealState == ConcealState_Ok) ? -1 : idx; |
1898 | 0 | fadingType = (pConcealmentInfo->concealState_old == ConcealState_Mute) |
1899 | 0 | ? FADE_TIMEDOMAIN_FROMSPECTRALMUTE |
1900 | 0 | : FADE_TIMEDOMAIN; |
1901 | 0 | break; |
1902 | 0 | default: |
1903 | 0 | FDK_ASSERT(0); |
1904 | 0 | fadingType = FADE_TIMEDOMAIN_TOSPECTRALMUTE; |
1905 | 0 | break; |
1906 | 0 | } |
1907 | | |
1908 | | /* determine Target end-of-frame fading level and fading slope */ |
1909 | 0 | switch (fadingType) { |
1910 | 0 | case FADE_TIMEDOMAIN_FROMSPECTRALMUTE: |
1911 | 0 | fadeStop = |
1912 | 0 | (idx < 0) ? (FIXP_DBL)MAXVAL_DBL : FX_SGL2FX_DBL(fadeFactor[idx]); |
1913 | 0 | if (pConcealmentInfo->pConcealParams->numFadeInFrames == 0) { |
1914 | | /* do step as fast as possible */ |
1915 | 0 | fadingSteps[0] = 1; |
1916 | 0 | break; |
1917 | 0 | } |
1918 | 0 | CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]); |
1919 | 0 | break; |
1920 | 0 | case FADE_TIMEDOMAIN: |
1921 | 0 | fadeStop = |
1922 | 0 | (idx < 0) ? (FIXP_DBL)MAXVAL_DBL : FX_SGL2FX_DBL(fadeFactor[idx]); |
1923 | 0 | CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]); |
1924 | 0 | break; |
1925 | 0 | case FADE_TIMEDOMAIN_TOSPECTRALMUTE: |
1926 | 0 | fadeStop = attMute; |
1927 | 0 | if (pConcealmentInfo->pConcealParams->numFadeOutFrames == 0) { |
1928 | | /* do step as fast as possible */ |
1929 | 0 | fadingSteps[0] = 1; |
1930 | 0 | break; |
1931 | 0 | } |
1932 | 0 | CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]); |
1933 | 0 | break; |
1934 | 0 | } |
1935 | | |
1936 | | /* |
1937 | | Render fading levels within current frame and do the final fading (2.) |
1938 | | */ |
1939 | | |
1940 | 0 | len >>= 3; |
1941 | 0 | CConcealment_TDFadeFillFadingStations(fadingStations, fadingSteps, fadeStop, |
1942 | 0 | fadeStart, fadingType); |
1943 | |
|
1944 | 0 | if ((fadingStations[8] != (FIXP_DBL)MAXVAL_DBL) || |
1945 | 0 | (fadingStations[7] != (FIXP_DBL)MAXVAL_DBL) || |
1946 | 0 | (fadingStations[6] != (FIXP_DBL)MAXVAL_DBL) || |
1947 | 0 | (fadingStations[5] != (FIXP_DBL)MAXVAL_DBL) || |
1948 | 0 | (fadingStations[4] != (FIXP_DBL)MAXVAL_DBL) || |
1949 | 0 | (fadingStations[3] != (FIXP_DBL)MAXVAL_DBL) || |
1950 | 0 | (fadingStations[2] != (FIXP_DBL)MAXVAL_DBL) || |
1951 | 0 | (fadingStations[1] != (FIXP_DBL)MAXVAL_DBL) || |
1952 | 0 | (fadingStations[0] != |
1953 | 0 | (FIXP_DBL)MAXVAL_DBL)) /* if there's something to fade */ |
1954 | 0 | { |
1955 | 0 | int start = 0; |
1956 | 0 | for (ii = 0; ii < 8; ii++) { |
1957 | 0 | CConcealment_TDFadePcmAtt(start, len, fadingStations[ii], |
1958 | 0 | fadingStations[ii + 1], pcmdata); |
1959 | 0 | start += len; |
1960 | 0 | } |
1961 | 0 | } |
1962 | 0 | CConcealment_TDNoise_Apply(pConcealmentInfo, len, aacOutDataHeadroom, |
1963 | 0 | pcmdata); |
1964 | | |
1965 | | /* Save end-of-frame attenuation and fading type */ |
1966 | 0 | pConcealmentInfo->lastFadingType = fadingType; |
1967 | 0 | pConcealmentInfo->fade_old = fadeStop; |
1968 | 0 | pConcealmentInfo->concealState_old = concealState; |
1969 | |
|
1970 | 0 | return 1; |
1971 | 0 | } |
1972 | | |
1973 | | /* attenuate pcmdata in Time Domain Fading process */ |
1974 | | static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart, |
1975 | 0 | FIXP_DBL fadeStop, PCM_DEC *pcmdata) { |
1976 | 0 | int i; |
1977 | 0 | FIXP_DBL dStep; |
1978 | 0 | FIXP_DBL dGain; |
1979 | 0 | FIXP_DBL dGain_apply; |
1980 | | |
1981 | | /* set start energy */ |
1982 | 0 | dGain = fadeStart; |
1983 | | /* determine energy steps from sample to sample */ |
1984 | 0 | dStep = (FIXP_DBL)((int)((fadeStart >> 1) - (fadeStop >> 1)) / len) << 1; |
1985 | |
|
1986 | 0 | for (i = start; i < (start + len); i++) { |
1987 | 0 | dGain -= dStep; |
1988 | | /* prevent gain from getting negative due to possible fixpoint inaccuracies |
1989 | | */ |
1990 | 0 | dGain_apply = fMax((FIXP_DBL)0, dGain); |
1991 | | /* finally, attenuate samples */ |
1992 | 0 | pcmdata[i] = FIXP_DBL2PCM_DEC(fMult(pcmdata[i], dGain_apply)); |
1993 | 0 | } |
1994 | 0 | } |
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 | | */ |
2020 | | static void CConcealment_TDFadeFillFadingStations(FIXP_DBL *fadingStations, |
2021 | | int *fadingSteps, |
2022 | | FIXP_DBL fadeStop, |
2023 | | FIXP_DBL fadeStart, |
2024 | 0 | TDfadingType fadingType) { |
2025 | 0 | int i; |
2026 | 0 | INT fadingSteps_sum = 0; |
2027 | 0 | INT fadeDiff; |
2028 | |
|
2029 | 0 | fadingSteps_sum = fadingSteps[0] + fadingSteps[1] + fadingSteps[2] + |
2030 | 0 | fadingSteps[3] + fadingSteps[4] + fadingSteps[5] + |
2031 | 0 | fadingSteps[6] + fadingSteps[7]; |
2032 | 0 | fadeDiff = ((INT)(fadeStop - fadeStart) / fMax(fadingSteps_sum, (INT)1)); |
2033 | 0 | fadingStations[0] = fadeStart; |
2034 | 0 | for (i = 1; i < 8; i++) { |
2035 | 0 | fadingStations[i] = |
2036 | 0 | fadingStations[i - 1] + (FIXP_DBL)(fadeDiff * fadingSteps[i - 1]); |
2037 | 0 | } |
2038 | 0 | fadingStations[8] = fadeStop; |
2039 | 0 | } |
2040 | | |
2041 | 0 | static void CConcealment_TDFading_doLinearFadingSteps(int *fadingSteps) { |
2042 | 0 | fadingSteps[0] = fadingSteps[1] = fadingSteps[2] = fadingSteps[3] = |
2043 | 0 | fadingSteps[4] = fadingSteps[5] = fadingSteps[6] = fadingSteps[7] = 1; |
2044 | 0 | } |
2045 | | |
2046 | | /* end of TimeDomainFading functions */ |
2047 | | |
2048 | | /* derived from int UsacRandomSign() */ |
2049 | 0 | static int CConcealment_TDNoise_Random(ULONG *seed) { |
2050 | 0 | *seed = (ULONG)(((UINT64)(*seed) * 69069) + 5); |
2051 | 0 | return (int)(*seed); |
2052 | 0 | } |
2053 | | |
2054 | | static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo, |
2055 | | const int len, |
2056 | | const INT aacOutDataHeadroom, |
2057 | 0 | PCM_DEC *const pcmdata) { |
2058 | 0 | PCM_DEC *states = pConcealmentInfo->TDNoiseStates; |
2059 | 0 | PCM_DEC noiseVal; |
2060 | 0 | FIXP_DBL noiseValLong; |
2061 | 0 | FIXP_SGL *coef = pConcealmentInfo->TDNoiseCoef; |
2062 | 0 | FIXP_DBL TDNoiseAtt; |
2063 | 0 | ULONG seed = pConcealmentInfo->TDNoiseSeed = |
2064 | 0 | (ULONG)CConcealment_TDNoise_Random(&pConcealmentInfo->TDNoiseSeed) + 1; |
2065 | |
|
2066 | 0 | TDNoiseAtt = pConcealmentInfo->pConcealParams->comfortNoiseLevel; |
2067 | |
|
2068 | 0 | int ii; |
2069 | |
|
2070 | 0 | if ((pConcealmentInfo->concealState != ConcealState_Ok || |
2071 | 0 | pConcealmentInfo->concealState_old != ConcealState_Ok) && |
2072 | 0 | TDNoiseAtt != (FIXP_DBL)0) { |
2073 | 0 | for (ii = 0; ii < (len << 3); ii++) { |
2074 | | /* create filtered noise */ |
2075 | 0 | states[2] = states[1]; |
2076 | 0 | states[1] = states[0]; |
2077 | 0 | states[0] = |
2078 | 0 | FIXP_DBL2PCM_DEC((FIXP_DBL)CConcealment_TDNoise_Random(&seed)); |
2079 | 0 | noiseValLong = fMult(states[0], coef[0]) + fMult(states[1], coef[1]) + |
2080 | 0 | fMult(states[2], coef[2]); |
2081 | 0 | noiseVal = FIXP_DBL2PCM_DEC(fMult(noiseValLong, TDNoiseAtt) >> |
2082 | 0 | aacOutDataHeadroom); |
2083 | | |
2084 | | /* add filtered noise - check for clipping, before */ |
2085 | 0 | if (noiseVal > (PCM_DEC)0 && |
2086 | 0 | pcmdata[ii] > (PCM_DEC)MAXVAL_PCM_DEC - noiseVal) { |
2087 | 0 | noiseVal = noiseVal * (PCM_DEC)-1; |
2088 | 0 | } else if (noiseVal < (PCM_DEC)0 && |
2089 | 0 | pcmdata[ii] < (PCM_DEC)MINVAL_PCM_DEC - noiseVal) { |
2090 | 0 | noiseVal = noiseVal * (PCM_DEC)-1; |
2091 | 0 | } |
2092 | |
|
2093 | 0 | pcmdata[ii] += noiseVal; |
2094 | 0 | } |
2095 | 0 | } |
2096 | 0 | } |