Coverage Report

Created: 2025-08-26 06:50

/src/aac/libSACdec/src/sac_dec_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 - 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
/*********************** MPEG surround decoder library *************************
96
97
   Author(s):   Christian Ertel, Christian Griebel
98
99
   Description: SAC Dec error concealment
100
101
*******************************************************************************/
102
103
#include "sac_dec_conceal.h"
104
105
void SpatialDecConcealment_Init(SpatialDecConcealmentInfo *info,
106
39.8k
                                const UINT resetFlags) {
107
39.8k
  FDK_ASSERT(info != NULL);
108
109
39.8k
  if (resetFlags & MPEGS_CONCEAL_RESET_STATE) {
110
39.8k
    info->concealState = SpatialDecConcealState_Init;
111
    /* Frame counters will be initialized implicitely in function
112
     * SpatialDecConcealment_UpdateState(). */
113
39.8k
  }
114
115
39.8k
  if (resetFlags & MPEGS_CONCEAL_RESET_PARAMETER) {
116
    /* Set default params */
117
24.9k
    info->concealParams.method = MPEGS_CONCEAL_DEFAULT_METHOD;
118
24.9k
    info->concealParams.numKeepFrames = MPEGS_CONCEAL_DEFAULT_NUM_KEEP_FRAMES;
119
24.9k
    info->concealParams.numFadeOutFrames =
120
24.9k
        MPEGS_CONCEAL_DEFAULT_FADE_OUT_SLOPE_LENGTH;
121
24.9k
    info->concealParams.numFadeInFrames =
122
24.9k
        MPEGS_CONCEAL_DEFAULT_FADE_IN_SLOPE_LENGTH;
123
24.9k
    info->concealParams.numReleaseFrames =
124
24.9k
        MPEGS_CONCEAL_DEFAULT_NUM_RELEASE_FRAMES;
125
24.9k
  }
126
127
39.8k
  return;
128
39.8k
}
129
130
int SpatialDecConcealment_Apply(
131
    SpatialDecConcealmentInfo *info,
132
    const SCHAR (*cmpIdxData)[MAX_PARAMETER_BANDS], SCHAR **diffIdxData,
133
    SCHAR *
134
        idxPrev, /* char
135
                    idxPrev[SPATIALDEC_MAX_NUM_OTT][SPATIALDEC_MAX_PARAMETER_BANDS],
136
                  */
137
    SCHAR *bsXXXDataMode, const int startBand, const int stopBand,
138
471k
    const SCHAR defaultValue, const int paramType, const int numParamSets) {
139
471k
  int appliedProcessing = 0;
140
471k
  int band, dataMode = -1;
141
142
471k
  FDK_ASSERT(info != NULL);
143
471k
  FDK_ASSERT(cmpIdxData != NULL);
144
471k
  FDK_ASSERT(idxPrev != NULL);
145
471k
  FDK_ASSERT(bsXXXDataMode != NULL);
146
147
  /* Processing depends only on the internal state */
148
471k
  switch (info->concealState) {
149
115k
    case SpatialDecConcealState_Init:
150
115k
      dataMode = 0; /* default */
151
115k
      break;
152
153
286k
    case SpatialDecConcealState_Ok:
154
      /* Nothing to do */
155
286k
      break;
156
157
52.3k
    case SpatialDecConcealState_Keep:
158
52.3k
      dataMode = 1; /* keep */
159
52.3k
      break;
160
161
7.08k
    case SpatialDecConcealState_FadeToDefault: {
162
      /* Start simple fade out */
163
7.08k
      FIXP_DBL fac = fDivNorm(info->cntStateFrames + 1,
164
7.08k
                              info->concealParams.numFadeOutFrames + 1);
165
166
129k
      for (band = startBand; band < stopBand; band += 1) {
167
        /*            idxPrev = fac * defaultValue + (1-fac) * idxPrev; */
168
122k
        idxPrev[band] =
169
122k
            fMultI(fac, defaultValue - idxPrev[band]) + idxPrev[band];
170
122k
      }
171
7.08k
      dataMode = 1; /* keep */
172
7.08k
      appliedProcessing = 1;
173
7.08k
    } break;
174
175
7.87k
    case SpatialDecConcealState_Default:
176
140k
      for (band = startBand; band < stopBand; band += 1) {
177
132k
        idxPrev[band] = defaultValue;
178
132k
      }
179
7.87k
      dataMode = 1; /* keep */
180
7.87k
      appliedProcessing = 1;
181
7.87k
      break;
182
183
3.12k
    case SpatialDecConcealState_FadeFromDefault: {
184
3.12k
      FIXP_DBL fac = fDivNorm(info->cntValidFrames + 1,
185
3.12k
                              info->concealParams.numFadeInFrames + 1);
186
187
60.2k
      for (band = startBand; band < stopBand; band += 1) {
188
        /*            idxPrev = fac * cmpIdxData + (1-fac) * defaultValue; */
189
57.1k
        idxPrev[band] =
190
57.1k
            fMultI(fac, cmpIdxData[numParamSets - 1][band] - defaultValue) +
191
57.1k
            defaultValue;
192
57.1k
      }
193
3.12k
      dataMode = 1; /* keep */
194
3.12k
      appliedProcessing = 1;
195
3.12k
    } break;
196
197
0
    default:
198
0
      FDK_ASSERT(0); /* All valid states shall be handled above. */
199
0
      break;
200
471k
  }
201
202
471k
  if (dataMode >= 0) {
203
185k
    int i;
204
371k
    for (i = 0; i < numParamSets; i += 1) {
205
186k
      bsXXXDataMode[i] = dataMode;
206
186k
      if (diffIdxData != NULL) {
207
794k
        for (band = startBand; band < stopBand; band += 1) {
208
727k
          diffIdxData[i][band] = 0;
209
727k
        }
210
66.6k
      }
211
186k
    }
212
185k
  }
213
214
471k
  return appliedProcessing;
215
471k
}
216
217
void SpatialDecConcealment_UpdateState(SpatialDecConcealmentInfo *info,
218
227k
                                       const int frameOk) {
219
227k
  FDK_ASSERT(info != NULL);
220
221
227k
  if (frameOk) {
222
139k
    info->cntValidFrames += 1;
223
139k
  } else {
224
88.2k
    info->cntValidFrames = 0;
225
88.2k
  }
226
227
227k
  switch (info->concealState) {
228
61.6k
    case SpatialDecConcealState_Init:
229
61.6k
      if (frameOk) {
230
        /* NEXT STATE: Ok */
231
5.30k
        info->concealState = SpatialDecConcealState_Ok;
232
5.30k
        info->cntStateFrames = 0;
233
5.30k
      }
234
61.6k
      break;
235
236
137k
    case SpatialDecConcealState_Ok:
237
137k
      if (!frameOk) {
238
        /* NEXT STATE: Keep */
239
17.0k
        info->concealState = SpatialDecConcealState_Keep;
240
17.0k
        info->cntStateFrames = 0;
241
17.0k
      }
242
137k
      break;
243
244
20.8k
    case SpatialDecConcealState_Keep:
245
20.8k
      info->cntStateFrames += 1;
246
20.8k
      if (frameOk) {
247
        /* NEXT STATE: Ok */
248
12.4k
        info->concealState = SpatialDecConcealState_Ok;
249
12.4k
      } else {
250
8.36k
        if (info->cntStateFrames >= info->concealParams.numKeepFrames) {
251
573
          if (info->concealParams.numFadeOutFrames == 0) {
252
            /* NEXT STATE: Default */
253
0
            info->concealState = SpatialDecConcealState_Default;
254
573
          } else {
255
            /* NEXT STATE: Fade to default */
256
573
            info->concealState = SpatialDecConcealState_FadeToDefault;
257
573
            info->cntStateFrames = 0;
258
573
          }
259
573
        }
260
8.36k
      }
261
20.8k
      break;
262
263
3.26k
    case SpatialDecConcealState_FadeToDefault:
264
3.26k
      info->cntStateFrames += 1;
265
3.26k
      if (info->cntValidFrames > 0) {
266
        /* NEXT STATE: Fade in from default */
267
394
        info->concealState = SpatialDecConcealState_FadeFromDefault;
268
394
        info->cntStateFrames = 0;
269
2.86k
      } else {
270
2.86k
        if (info->cntStateFrames >= info->concealParams.numFadeOutFrames) {
271
          /* NEXT STATE: Default */
272
457
          info->concealState = SpatialDecConcealState_Default;
273
457
        }
274
2.86k
      }
275
3.26k
      break;
276
277
3.62k
    case SpatialDecConcealState_Default:
278
3.62k
      if (info->cntValidFrames > 0) {
279
339
        if (info->concealParams.numFadeInFrames == 0) {
280
          /* NEXT STATE: Ok */
281
0
          info->concealState = SpatialDecConcealState_Ok;
282
339
        } else {
283
          /* NEXT STATE: Fade in from default */
284
339
          info->concealState = SpatialDecConcealState_FadeFromDefault;
285
339
          info->cntValidFrames = 0;
286
339
        }
287
339
      }
288
3.62k
      break;
289
290
1.49k
    case SpatialDecConcealState_FadeFromDefault:
291
1.49k
      info->cntValidFrames += 1;
292
1.49k
      if (frameOk) {
293
1.13k
        if (info->cntValidFrames >= info->concealParams.numFadeInFrames) {
294
          /* NEXT STATE: Ok */
295
365
          info->concealState = SpatialDecConcealState_Ok;
296
365
        }
297
1.13k
      } else {
298
        /* NEXT STATE: Fade to default */
299
355
        info->concealState = SpatialDecConcealState_FadeToDefault;
300
355
        info->cntStateFrames = 0;
301
355
      }
302
1.49k
      break;
303
304
0
    default:
305
0
      FDK_ASSERT(0); /* All valid states should be handled above! */
306
0
      break;
307
227k
  }
308
227k
}
309
310
SACDEC_ERROR SpatialDecConcealment_SetParam(SpatialDecConcealmentInfo *self,
311
                                            const SAC_DEC_CONCEAL_PARAM param,
312
74.3k
                                            const INT value) {
313
74.3k
  SACDEC_ERROR err = MPS_OK;
314
315
74.3k
  switch (param) {
316
14.8k
    case SAC_DEC_CONCEAL_METHOD:
317
14.8k
      switch ((SpatialDecConcealmentMethod)value) {
318
0
        case SAC_DEC_CONCEAL_WITH_ZERO_VALUED_OUTPUT:
319
14.8k
        case SAC_DEC_CONCEAL_BY_FADING_PARAMETERS:
320
14.8k
          break;
321
0
        default:
322
0
          err = MPS_INVALID_PARAMETER;
323
0
          goto bail;
324
14.8k
      }
325
14.8k
      if (self != NULL) {
326
        /* store parameter value */
327
14.8k
        self->concealParams.method = (SpatialDecConcealmentMethod)value;
328
14.8k
      } else {
329
0
        err = MPS_INVALID_HANDLE;
330
0
        goto bail;
331
0
      }
332
14.8k
      break;
333
14.8k
    case SAC_DEC_CONCEAL_NUM_KEEP_FRAMES:
334
14.8k
      if (value < 0) {
335
0
        err = MPS_INVALID_PARAMETER;
336
0
        goto bail;
337
0
      }
338
14.8k
      if (self != NULL) {
339
        /* store parameter value */
340
14.8k
        self->concealParams.numKeepFrames = (UINT)value;
341
14.8k
      } else {
342
0
        err = MPS_INVALID_HANDLE;
343
0
        goto bail;
344
0
      }
345
14.8k
      break;
346
14.8k
    case SAC_DEC_CONCEAL_FADE_OUT_SLOPE_LENGTH:
347
14.8k
      if (value < 0) {
348
0
        err = MPS_INVALID_PARAMETER;
349
0
        goto bail;
350
0
      }
351
14.8k
      if (self != NULL) {
352
        /* store parameter value */
353
14.8k
        self->concealParams.numFadeOutFrames = (UINT)value;
354
14.8k
      } else {
355
0
        err = MPS_INVALID_HANDLE;
356
0
        goto bail;
357
0
      }
358
14.8k
      break;
359
14.8k
    case SAC_DEC_CONCEAL_FADE_IN_SLOPE_LENGTH:
360
14.8k
      if (value < 0) {
361
0
        err = MPS_INVALID_PARAMETER;
362
0
        goto bail;
363
0
      }
364
14.8k
      if (self != NULL) {
365
        /* store parameter value */
366
14.8k
        self->concealParams.numFadeInFrames = (UINT)value;
367
14.8k
      } else {
368
0
        err = MPS_INVALID_HANDLE;
369
0
        goto bail;
370
0
      }
371
14.8k
      break;
372
14.8k
    case SAC_DEC_CONCEAL_NUM_RELEASE_FRAMES:
373
14.8k
      if (value < 0) {
374
0
        err = MPS_INVALID_PARAMETER;
375
0
        goto bail;
376
0
      }
377
14.8k
      if (self != NULL) {
378
        /* store parameter value */
379
14.8k
        self->concealParams.numReleaseFrames = (UINT)value;
380
14.8k
      } else {
381
0
        err = MPS_INVALID_HANDLE;
382
0
        goto bail;
383
0
      }
384
14.8k
      break;
385
14.8k
    default:
386
0
      err = MPS_INVALID_PARAMETER;
387
0
      goto bail;
388
74.3k
  }
389
390
74.3k
bail:
391
74.3k
  return err;
392
74.3k
}