Coverage Report

Created: 2026-06-10 06:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/aac/libAACdec/src/usacdec_acelp.cpp
Line
Count
Source
1
/* -----------------------------------------------------------------------------
2
Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4
© Copyright  1995 - 2020 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):   Matthias Hildenbrand
98
99
   Description: USAC ACELP frame decoder
100
101
*******************************************************************************/
102
103
#include "usacdec_acelp.h"
104
105
#include "usacdec_ace_d4t64.h"
106
#include "usacdec_ace_ltp.h"
107
#include "usacdec_rom.h"
108
#include "usacdec_lpc.h"
109
#include "genericStds.h"
110
111
102k
#define PIT_FR2_12k8 128 /* Minimum pitch lag with resolution 1/2      */
112
102k
#define PIT_FR1_12k8 160 /* Minimum pitch lag with resolution 1        */
113
#define TILT_CODE2 \
114
22.5M
  FL2FXCONST_SGL(0.3f * 2.0f) /* ACELP code pre-emphasis factor ( *2 )      */
115
#define PIT_SHARP \
116
2.07M
  FL2FXCONST_SGL(0.85f) /* pitch sharpening factor                    */
117
#define PREEMPH_FAC \
118
49.1M
  FL2FXCONST_SGL(0.68f) /* ACELP synth pre-emphasis factor            */
119
120
241k
#define ACELP_HEADROOM 1
121
241k
#define ACELP_OUTSCALE (MDCT_OUT_HEADROOM - ACELP_HEADROOM)
122
123
/**
124
 * \brief Calculate pre-emphasis (1 - mu z^-1) on input signal.
125
 * \param[in] in pointer to input signal; in[-1] is also needed.
126
 * \param[out] out pointer to output signal.
127
 * \param[in] L length of filtering.
128
 */
129
/* static */
130
54.1k
void E_UTIL_preemph(const FIXP_DBL *in, FIXP_DBL *out, INT L) {
131
54.1k
  int i;
132
133
22.0M
  for (i = 0; i < L; i++) {
134
22.0M
    out[i] = fAddSaturate(in[i], -fMult(PREEMPH_FAC, in[i - 1]));
135
22.0M
  }
136
137
54.1k
  return;
138
54.1k
}
139
140
/**
141
 * \brief Calculate de-emphasis 1/(1 - TILT_CODE z^-1) on innovative codebook
142
 * vector.
143
 * \param[in,out] x innovative codebook vector.
144
 */
145
static void Preemph_code(
146
    FIXP_COD x[] /* (i/o)   : input signal overwritten by the output */
147
357k
) {
148
357k
  int i;
149
357k
  FIXP_DBL L_tmp;
150
151
  /* ARM926: 12 cycles per sample */
152
22.8M
  for (i = L_SUBFR - 1; i > 0; i--) {
153
22.5M
    L_tmp = FX_COD2FX_DBL(x[i]);
154
22.5M
    L_tmp -= fMultDiv2(x[i - 1], TILT_CODE2);
155
22.5M
    x[i] = FX_DBL2FX_COD(L_tmp);
156
22.5M
  }
157
357k
}
158
159
/**
160
 * \brief Apply pitch sharpener to the innovative codebook vector.
161
 * \param[in,out] x innovative codebook vector.
162
 * \param[in] pit_lag decoded pitch lag.
163
 */
164
static void Pit_shrp(
165
    FIXP_COD x[], /* in/out: impulse response (or algebraic code) */
166
    int pit_lag   /* input : pitch lag                            */
167
357k
) {
168
357k
  int i;
169
357k
  FIXP_DBL L_tmp;
170
171
2.43M
  for (i = pit_lag; i < L_SUBFR; i++) {
172
2.07M
    L_tmp = FX_COD2FX_DBL(x[i]);
173
2.07M
    L_tmp += fMult(x[i - pit_lag], PIT_SHARP);
174
2.07M
    x[i] = FX_DBL2FX_COD(L_tmp);
175
2.07M
  }
176
177
357k
  return;
178
357k
}
179
180
  /**
181
   * \brief Calculate Quantized codebook gain, Quantized pitch gain and unbiased
182
   *        Innovative code vector energy.
183
   * \param[in] index index of quantizer.
184
   * \param[in] code innovative code vector with exponent = SF_CODE.
185
   * \param[out] gain_pit Quantized pitch gain g_p with exponent = SF_GAIN_P.
186
   * \param[out] gain_code Quantized codebook gain g_c.
187
   * \param[in] mean_ener mean_ener defined in open-loop (2 bits), exponent = 7.
188
   * \param[out] E_code unbiased innovative code vector energy.
189
   * \param[out] E_code_e exponent of unbiased innovative code vector energy.
190
   */
191
192
350k
#define SF_MEAN_ENER_LG10 9
193
194
/* pow(10.0, {18, 30, 42, 54}/20.0) /(float)(1<<SF_MEAN_ENER_LG10) */
195
static const FIXP_DBL pow_10_mean_energy[4] = {0x01fc5ebd, 0x07e7db92,
196
                                               0x1f791f65, 0x7d4bfba3};
197
198
static void D_gain2_plus(int index, FIXP_COD code[], FIXP_SGL *gain_pit,
199
                         FIXP_DBL *gain_code, int mean_ener_bits, int bfi,
200
                         FIXP_SGL *past_gpit, FIXP_DBL *past_gcode,
201
357k
                         FIXP_DBL *pEner_code, int *pEner_code_e) {
202
357k
  FIXP_DBL Ltmp;
203
357k
  FIXP_DBL gcode0, gcode_inov;
204
357k
  INT gcode0_e, gcode_inov_e;
205
357k
  int i;
206
207
357k
  FIXP_DBL ener_code;
208
357k
  INT ener_code_e;
209
210
  /* ener_code = sum(code[]^2) */
211
357k
  ener_code = FIXP_DBL(0);
212
23.2M
  for (i = 0; i < L_SUBFR; i++) {
213
22.8M
    ener_code += fPow2Div2(code[i]);
214
22.8M
  }
215
216
357k
  ener_code_e = fMax(fNorm(ener_code) - 1, 0);
217
357k
  ener_code <<= ener_code_e;
218
357k
  ener_code_e = 2 * SF_CODE + 1 - ener_code_e;
219
220
  /* export energy of code for calc_period_factor() */
221
357k
  *pEner_code = ener_code;
222
357k
  *pEner_code_e = ener_code_e;
223
224
357k
  ener_code += scaleValue(FL2FXCONST_DBL(0.01f), -ener_code_e);
225
226
  /* ener_code *= 1/L_SUBFR, and make exponent even (because of square root
227
   * below). */
228
357k
  if (ener_code_e & 1) {
229
154k
    ener_code_e -= 5;
230
154k
    ener_code >>= 1;
231
203k
  } else {
232
203k
    ener_code_e -= 6;
233
203k
  }
234
357k
  gcode_inov = invSqrtNorm2(ener_code, &gcode0_e);
235
357k
  gcode_inov_e = gcode0_e - (ener_code_e >> 1);
236
237
357k
  if (bfi) {
238
7.12k
    FIXP_DBL tgcode;
239
7.12k
    FIXP_SGL tgpit;
240
241
7.12k
    tgpit = *past_gpit;
242
243
7.12k
    if (tgpit > FL2FXCONST_SGL(0.95f / (1 << SF_GAIN_P))) {
244
112
      tgpit = FL2FXCONST_SGL(0.95f / (1 << SF_GAIN_P));
245
7.01k
    } else if (tgpit < FL2FXCONST_SGL(0.5f / (1 << SF_GAIN_P))) {
246
5.08k
      tgpit = FL2FXCONST_SGL(0.5f / (1 << SF_GAIN_P));
247
5.08k
    }
248
7.12k
    *gain_pit = tgpit;
249
7.12k
    tgpit = FX_DBL2FX_SGL(fMult(tgpit, FL2FXCONST_DBL(0.95f)));
250
7.12k
    *past_gpit = tgpit;
251
252
7.12k
    tgpit = FL2FXCONST_SGL(1.4f / (1 << SF_GAIN_P)) - tgpit;
253
7.12k
    tgcode = fMult(*past_gcode, tgpit) << SF_GAIN_P;
254
7.12k
    *gain_code = scaleValue(fMult(tgcode, gcode_inov), gcode_inov_e);
255
7.12k
    *past_gcode = tgcode;
256
257
7.12k
    return;
258
7.12k
  }
259
260
  /*-------------- Decode gains ---------------*/
261
  /*
262
   gcode0 = pow(10.0, (float)mean_ener/20.0);
263
   gcode0 = gcode0 / sqrt(ener_code/L_SUBFR);
264
   */
265
350k
  gcode0 = pow_10_mean_energy[mean_ener_bits];
266
350k
  gcode0 = fMultDiv2(gcode0, gcode_inov);
267
350k
  gcode0_e = gcode0_e + SF_MEAN_ENER_LG10 - (ener_code_e >> 1) + 1;
268
269
350k
  i = index << 1;
270
350k
  *gain_pit = t_qua_gain7b[i]; /* adaptive codebook gain */
271
  /* t_qua_gain[ind2p1] : fixed codebook gain correction factor */
272
350k
  Ltmp = fMult(t_qua_gain7b[i + 1], gcode0);
273
350k
  *gain_code = scaleValue(Ltmp, gcode0_e - SF_GAIN_C + SF_QUA_GAIN7B);
274
275
  /* update bad frame handler */
276
350k
  *past_gpit = *gain_pit;
277
278
  /*--------------------------------------------------------
279
    past_gcode  = gain_code/gcode_inov
280
   --------------------------------------------------------*/
281
350k
  {
282
350k
    FIXP_DBL gcode_m;
283
350k
    INT gcode_e;
284
285
350k
    gcode_m = fDivNormHighPrec(Ltmp, gcode_inov, &gcode_e);
286
350k
    gcode_e += (gcode0_e - SF_GAIN_C + SF_QUA_GAIN7B) - (gcode_inov_e);
287
350k
    *past_gcode = scaleValue(gcode_m, gcode_e);
288
350k
  }
289
350k
}
290
291
/**
292
 * \brief Calculate period/voicing factor r_v
293
 * \param[in] exc pitch excitation.
294
 * \param[in] gain_pit gain of pitch g_p.
295
 * \param[in] gain_code gain of code g_c.
296
 * \param[in] gain_code_e exponent of gain of code.
297
 * \param[in] ener_code unbiased innovative code vector energy.
298
 * \param[in] ener_code_e exponent of unbiased innovative code vector energy.
299
 * \return period/voice factor r_v (-1=unvoiced to 1=voiced), exponent SF_PFAC.
300
 */
301
static FIXP_DBL calc_period_factor(FIXP_DBL exc[], FIXP_SGL gain_pit,
302
                                   FIXP_DBL gain_code, FIXP_DBL ener_code,
303
357k
                                   int ener_code_e) {
304
357k
  int ener_exc_e, L_tmp_e, s = 0;
305
357k
  FIXP_DBL ener_exc, L_tmp;
306
357k
  FIXP_DBL period_fac;
307
308
  /* energy of pitch excitation */
309
357k
  ener_exc = (FIXP_DBL)0;
310
23.2M
  for (int i = 0; i < L_SUBFR; i++) {
311
22.8M
    ener_exc += fPow2Div2(exc[i]) >> s;
312
22.8M
    if (ener_exc >= FL2FXCONST_DBL(0.5f)) {
313
90.9k
      ener_exc >>= 1;
314
90.9k
      s++;
315
90.9k
    }
316
22.8M
  }
317
318
357k
  ener_exc_e = fNorm(ener_exc);
319
357k
  ener_exc = fMult(ener_exc << ener_exc_e, fPow2(gain_pit));
320
357k
  if (ener_exc != (FIXP_DBL)0) {
321
312k
    ener_exc_e = 2 * SF_EXC + 1 + 2 * SF_GAIN_P - ener_exc_e + s;
322
312k
  } else {
323
45.5k
    ener_exc_e = 0;
324
45.5k
  }
325
326
  /* energy of innovative code excitation */
327
  /* L_tmp = ener_code * gain_code*gain_code; */
328
357k
  L_tmp_e = fNorm(gain_code);
329
357k
  L_tmp = fPow2(gain_code << L_tmp_e);
330
357k
  L_tmp = fMult(ener_code, L_tmp);
331
357k
  L_tmp_e = 2 * SF_GAIN_C + ener_code_e - 2 * L_tmp_e;
332
333
  /* Find common exponent */
334
357k
  {
335
357k
    FIXP_DBL num, den;
336
357k
    int exp_diff;
337
338
357k
    exp_diff = ener_exc_e - L_tmp_e;
339
357k
    if (exp_diff >= 0) {
340
204k
      ener_exc >>= 1;
341
204k
      if (exp_diff <= DFRACT_BITS - 2) {
342
203k
        L_tmp >>= exp_diff + 1;
343
203k
      } else {
344
207
        L_tmp = (FIXP_DBL)0;
345
207
      }
346
204k
      den = ener_exc + L_tmp;
347
204k
      if (ener_exc_e < DFRACT_BITS - 1) {
348
141k
        den += scaleValue(FL2FXCONST_DBL(0.01f), -ener_exc_e - 1);
349
141k
      }
350
204k
    } else {
351
153k
      if (exp_diff >= -(DFRACT_BITS - 2)) {
352
153k
        ener_exc >>= 1 - exp_diff;
353
153k
      } else {
354
450
        ener_exc = (FIXP_DBL)0;
355
450
      }
356
153k
      L_tmp >>= 1;
357
153k
      den = ener_exc + L_tmp;
358
153k
      if (L_tmp_e < DFRACT_BITS - 1) {
359
148k
        den += scaleValue(FL2FXCONST_DBL(0.01f), -L_tmp_e - 1);
360
148k
      }
361
153k
    }
362
357k
    num = (ener_exc - L_tmp);
363
357k
    num >>= SF_PFAC;
364
365
357k
    if (den > (FIXP_DBL)0) {
366
357k
      if (ener_exc > L_tmp) {
367
126k
        period_fac = schur_div(num, den, 16);
368
231k
      } else {
369
231k
        period_fac = -schur_div(-num, den, 16);
370
231k
      }
371
357k
    } else {
372
106
      period_fac = (FIXP_DBL)MAXVAL_DBL;
373
106
    }
374
357k
  }
375
376
  /* exponent = SF_PFAC */
377
357k
  return period_fac;
378
357k
}
379
380
/*------------------------------------------------------------*
381
 * noise enhancer                                             *
382
 * ~~~~~~~~~~~~~~                                             *
383
 * - Enhance excitation on noise. (modify gain of code)       *
384
 *   If signal is noisy and LPC filter is stable, move gain   *
385
 *   of code 1.5 dB toward gain of code threshold.            *
386
 *   This decrease by 3 dB noise energy variation.            *
387
 *------------------------------------------------------------*/
388
/**
389
 * \brief Enhance excitation on noise. (modify gain of code)
390
 * \param[in] gain_code Quantized codebook gain g_c, exponent = SF_GAIN_C.
391
 * \param[in] period_fac periodicity factor, exponent = SF_PFAC.
392
 * \param[in] stab_fac stability factor, exponent = SF_STAB.
393
 * \param[in,out] p_gc_threshold modified gain of previous subframe.
394
 * \return gain_code smoothed gain of code g_sc, exponent = SF_GAIN_C.
395
 */
396
static FIXP_DBL
397
noise_enhancer(/* (o) : smoothed gain g_sc                     SF_GAIN_C */
398
               FIXP_DBL gain_code, /* (i) : Quantized codebook gain SF_GAIN_C */
399
               FIXP_DBL period_fac, /* (i) : periodicity factor (-1=unvoiced to
400
                                       1=voiced), SF_PFAC */
401
               FIXP_SGL stab_fac,   /* (i) : stability factor (0 <= ... < 1.0)
402
                                       SF_STAB   */
403
               FIXP_DBL
404
                   *p_gc_threshold) /* (io): gain of code threshold SF_GAIN_C */
405
357k
{
406
357k
  FIXP_DBL fac, L_tmp, gc_thres;
407
408
357k
  gc_thres = *p_gc_threshold;
409
410
357k
  L_tmp = gain_code;
411
357k
  if (L_tmp < gc_thres) {
412
165k
    L_tmp += fMultDiv2(gain_code,
413
165k
                       FL2FXCONST_SGL(2.0 * 0.19f)); /* +1.5dB => *(1.0+0.19) */
414
165k
    if (L_tmp > gc_thres) {
415
15.5k
      L_tmp = gc_thres;
416
15.5k
    }
417
192k
  } else {
418
192k
    L_tmp = fMult(gain_code,
419
192k
                  FL2FXCONST_SGL(1.0f / 1.19f)); /* -1.5dB => *10^(-1.5/20) */
420
192k
    if (L_tmp < gc_thres) {
421
13.9k
      L_tmp = gc_thres;
422
13.9k
    }
423
192k
  }
424
357k
  *p_gc_threshold = L_tmp;
425
426
  /* voicing factor     lambda = 0.5*(1-period_fac) */
427
  /* gain smoothing factor S_m = lambda*stab_fac  (=fac)
428
                               = 0.5(stab_fac - stab_fac * period_fac) */
429
357k
  fac = (FX_SGL2FX_DBL(stab_fac) >> (SF_PFAC + 1)) -
430
357k
        fMultDiv2(stab_fac, period_fac);
431
  /* fac_e = SF_PFAC + SF_STAB */
432
357k
  FDK_ASSERT(fac >= (FIXP_DBL)0);
433
434
  /* gain_code = (float)((fac*tmp) + ((1.0-fac)*gain_code)); */
435
357k
  gain_code = fMult(fac, L_tmp) -
436
357k
              fMult(FL2FXCONST_DBL(-1.0f / (1 << (SF_PFAC + SF_STAB))) + fac,
437
357k
                    gain_code);
438
357k
  gain_code <<= (SF_PFAC + SF_STAB);
439
440
357k
  return gain_code;
441
357k
}
442
443
/**
444
 * \brief Update adaptive codebook u'(n) (exc)
445
 *        Enhance pitch of c(n) and build post-processed excitation u(n) (exc2)
446
 * \param[in] code innovative codevector c(n), exponent = SF_CODE.
447
 * \param[in,out] exc filtered adaptive codebook v(n), exponent = SF_EXC.
448
 * \param[in] gain_pit adaptive codebook gain, exponent = SF_GAIN_P.
449
 * \param[in] gain_code innovative codebook gain g_c, exponent = SF_GAIN_C.
450
 * \param[in] gain_code_smoothed smoothed innov. codebook gain g_sc, exponent =
451
 * SF_GAIN_C.
452
 * \param[in] period_fac periodicity factor r_v, exponent = SF_PFAC.
453
 * \param[out] exc2 post-processed excitation u(n), exponent = SF_EXC.
454
 */
455
void BuildAdaptiveExcitation(
456
    FIXP_COD code[],    /* (i) : algebraic codevector c(n)             Q9  */
457
    FIXP_DBL exc[],     /* (io): filtered adaptive codebook v(n)       Q15 */
458
    FIXP_SGL gain_pit,  /* (i) : adaptive codebook gain g_p            Q14 */
459
    FIXP_DBL gain_code, /* (i) : innovative codebook gain g_c          Q16 */
460
    FIXP_DBL gain_code_smoothed, /* (i) : smoothed innov. codebook gain g_sc
461
                                    Q16 */
462
    FIXP_DBL period_fac, /* (i) : periodicity factor r_v                Q15 */
463
    FIXP_DBL exc2[]      /* (o) : post-processed excitation u(n)        Q15 */
464
357k
) {
465
/* Note: code[L_SUBFR] and exc2[L_SUBFR] share the same memory!
466
         If exc2[i] is written, code[i] will be destroyed!
467
*/
468
114M
#define SF_HEADROOM (1)
469
45.7M
#define SF (SF_CODE + SF_GAIN_C + 1 - SF_EXC - SF_HEADROOM)
470
22.8M
#define SF_GAIN_P2 (SF_GAIN_P - SF_HEADROOM)
471
472
357k
  int i;
473
357k
  FIXP_DBL tmp, cpe, code_smooth_prev, code_smooth;
474
475
357k
  FIXP_COD code_i;
476
357k
  FIXP_DBL cpe_code_smooth, cpe_code_smooth_prev;
477
478
  /* cpe = (1+r_v)/8 * 2 ; ( SF = -1) */
479
357k
  cpe = (period_fac >> (2 - SF_PFAC)) + FL2FXCONST_DBL(0.25f);
480
481
  /* u'(n) */
482
357k
  tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1); /* v(0)*g_p */
483
357k
  *exc++ = (tmp + (fMultDiv2(code[0], gain_code) << SF)) << SF_HEADROOM;
484
485
  /* u(n) */
486
357k
  code_smooth_prev = fMultDiv2(*code++, gain_code_smoothed)
487
357k
                     << SF; /* c(0) * g_sc */
488
357k
  code_i = *code++;
489
357k
  code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF; /* c(1) * g_sc */
490
357k
  tmp += code_smooth_prev; /* tmp = v(0)*g_p + c(0)*g_sc */
491
357k
  cpe_code_smooth = fMultDiv2(cpe, code_smooth);
492
357k
  *exc2++ = (tmp - cpe_code_smooth) << SF_HEADROOM;
493
357k
  cpe_code_smooth_prev = fMultDiv2(cpe, code_smooth_prev);
494
495
357k
  i = L_SUBFR - 2;
496
357k
  do /* ARM926: 22 cycles per iteration */
497
22.1M
  {
498
    /* u'(n) */
499
22.1M
    tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1);
500
22.1M
    *exc++ = (tmp + (fMultDiv2(code_i, gain_code) << SF)) << SF_HEADROOM;
501
    /* u(n) */
502
22.1M
    tmp += code_smooth; /* += g_sc * c(i) */
503
22.1M
    tmp -= cpe_code_smooth_prev;
504
22.1M
    cpe_code_smooth_prev = cpe_code_smooth;
505
22.1M
    code_i = *code++;
506
22.1M
    code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF;
507
22.1M
    cpe_code_smooth = fMultDiv2(cpe, code_smooth);
508
22.1M
    *exc2++ = (tmp - cpe_code_smooth)
509
22.1M
              << SF_HEADROOM; /* tmp - c_pe * g_sc * c(i+1) */
510
22.1M
  } while (--i != 0);
511
512
  /* u'(n) */
513
357k
  tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1);
514
357k
  *exc = (tmp + (fMultDiv2(code_i, gain_code) << SF)) << SF_HEADROOM;
515
  /* u(n) */
516
357k
  tmp += code_smooth;
517
357k
  tmp -= cpe_code_smooth_prev;
518
357k
  *exc2++ = tmp << SF_HEADROOM;
519
520
357k
  return;
521
357k
}
522
523
/**
524
 * \brief Interpolate LPC vector in LSP domain for current subframe and convert
525
 * to LP domain
526
 * \param[in] lsp_old LPC vector (LSP domain) corresponding to the beginning of
527
 * current ACELP frame.
528
 * \param[in] lsp_new LPC vector (LSP domain) corresponding to the end of
529
 * current ACELP frame.
530
 * \param[in] subfr_nr number of current ACELP subframe 0..3.
531
 * \param[in] nb_subfr total number of ACELP subframes in this frame.
532
 * \param[out] A LP filter coefficients for current ACELP subframe, exponent =
533
 * SF_A_COEFFS.
534
 */
535
/* static */
536
void int_lpc_acelp(
537
    const FIXP_LPC lsp_old[], /* input : LSPs from past frame              */
538
    const FIXP_LPC lsp_new[], /* input : LSPs from present frame           */
539
    int subfr_nr, int nb_subfr,
540
    FIXP_LPC
541
        A[], /* output: interpolated LP coefficients for current subframe */
542
363k
    INT *A_exp) {
543
363k
  int i;
544
363k
  FIXP_LPC lsp_interpol[M_LP_FILTER_ORDER];
545
363k
  FIXP_SGL fac_old, fac_new;
546
547
363k
  FDK_ASSERT((nb_subfr == 3) || (nb_subfr == 4));
548
549
363k
  fac_old = lsp_interpol_factor[nb_subfr & 0x1][(nb_subfr - 1) - subfr_nr];
550
363k
  fac_new = lsp_interpol_factor[nb_subfr & 0x1][subfr_nr];
551
6.17M
  for (i = 0; i < M_LP_FILTER_ORDER; i++) {
552
5.80M
    lsp_interpol[i] = FX_DBL2FX_LPC(
553
5.80M
        (fMultDiv2(lsp_old[i], fac_old) + fMultDiv2(lsp_new[i], fac_new)) << 1);
554
5.80M
  }
555
556
363k
  E_LPC_f_lsp_a_conversion(lsp_interpol, A, A_exp);
557
558
363k
  return;
559
363k
}
560
561
/**
562
 * \brief Perform LP synthesis by filtering the post-processed excitation u(n)
563
 *        through the LP synthesis filter 1/A(z)
564
 * \param[in] a LP filter coefficients, exponent = SF_A_COEFFS.
565
 * \param[in] length length of input/output signal.
566
 * \param[in] x post-processed excitation u(n).
567
 * \param[in,out] y LP synthesis signal and filter memory
568
 * y[-M_LP_FILTER_ORDER..-1].
569
 */
570
571
/* static */
572
void Syn_filt(const FIXP_LPC a[], /* (i) : a[m] prediction coefficients Q12 */
573
              const INT a_exp,
574
              INT length,   /* (i) : length of input/output signal (64|128)   */
575
              FIXP_DBL x[], /* (i) : input signal Qx  */
576
              FIXP_DBL y[]  /* (i/o) : filter states / output signal  Qx-s*/
577
409k
) {
578
409k
  int i, j;
579
409k
  FIXP_DBL L_tmp;
580
581
27.8M
  for (i = 0; i < length; i++) {
582
27.4M
    L_tmp = (FIXP_DBL)0;
583
584
467M
    for (j = 0; j < M_LP_FILTER_ORDER; j++) {
585
439M
      L_tmp -= fMultDiv2(a[j], y[i - (j + 1)]) >> (LP_FILTER_SCALE - 1);
586
439M
    }
587
588
27.4M
    L_tmp = scaleValue(L_tmp, a_exp + LP_FILTER_SCALE);
589
27.4M
    y[i] = fAddSaturate(L_tmp, x[i]);
590
27.4M
  }
591
592
409k
  return;
593
409k
}
594
595
/**
596
 * \brief Calculate de-emphasis 1/(1 - mu z^-1) on input signal.
597
 * \param[in] x input signal.
598
 * \param[out] y output signal.
599
 * \param[in] L length of signal.
600
 * \param[in,out] mem memory (signal[-1]).
601
 */
602
/* static */
603
148k
void Deemph(FIXP_DBL *x, FIXP_DBL *y, int L, FIXP_DBL *mem) {
604
148k
  int i;
605
148k
  FIXP_DBL yi = *mem;
606
607
27.2M
  for (i = 0; i < L; i++) {
608
27.1M
    FIXP_DBL xi = x[i] >> 1;
609
27.1M
    xi = fMultAddDiv2(xi, PREEMPH_FAC, yi);
610
27.1M
    yi = SATURATE_LEFT_SHIFT(xi, 1, 32);
611
27.1M
    y[i] = yi;
612
27.1M
  }
613
148k
  *mem = yi;
614
148k
  return;
615
148k
}
616
617
/**
618
 * \brief Compute the LP residual by filtering the input speech through the
619
 * analysis filter A(z).
620
 * \param[in] a LP filter coefficients, exponent = SF_A_COEFFS
621
 * \param[in] x input signal (note that values x[-m..-1] are needed), exponent =
622
 * SF_SYNTH
623
 * \param[out] y output signal (residual), exponent = SF_EXC
624
 * \param[in] l length of filtering
625
 */
626
/* static */
627
void E_UTIL_residu(const FIXP_LPC *a, const INT a_exp, FIXP_DBL *x, FIXP_DBL *y,
628
90.5k
                   INT l) {
629
90.5k
  FIXP_DBL s;
630
90.5k
  INT i, j;
631
632
  /* (note that values x[-m..-1] are needed) */
633
18.7M
  for (i = 0; i < l; i++) {
634
18.6M
    s = (FIXP_DBL)0;
635
636
317M
    for (j = 0; j < M_LP_FILTER_ORDER; j++) {
637
298M
      s += fMultDiv2(a[j], x[i - j - 1]) >> (LP_FILTER_SCALE - 1);
638
298M
    }
639
640
18.6M
    s = scaleValue(s, a_exp + LP_FILTER_SCALE);
641
18.6M
    y[i] = fAddSaturate(s, x[i]);
642
18.6M
  }
643
644
90.5k
  return;
645
90.5k
}
646
647
/* use to map subfr number to number of bits used for acb_index */
648
static const UCHAR num_acb_idx_bits_table[2][NB_SUBFR] = {
649
    {9, 6, 9, 6}, /* coreCoderFrameLength == 1024 */
650
    {9, 6, 6, 0}  /* coreCoderFrameLength == 768  */
651
};
652
653
static int DecodePitchLag(HANDLE_FDK_BITSTREAM hBs,
654
                          const UCHAR num_acb_idx_bits,
655
                          const int PIT_MIN, /* TMIN */
656
                          const int PIT_FR2, /* TFR2 */
657
                          const int PIT_FR1, /* TFR1 */
658
                          const int PIT_MAX, /* TMAX */
659
358k
                          int *pT0, int *pT0_frac, int *pT0_min, int *pT0_max) {
660
358k
  int acb_idx;
661
358k
  int error = 0;
662
358k
  int T0, T0_frac;
663
664
358k
  FDK_ASSERT((num_acb_idx_bits == 9) || (num_acb_idx_bits == 6));
665
666
358k
  acb_idx = FDKreadBits(hBs, num_acb_idx_bits);
667
668
358k
  if (num_acb_idx_bits == 6) {
669
    /* When the pitch value is encoded on 6 bits, a pitch resolution of 1/4 is
670
       always used in the range [T1-8, T1+7.75], where T1 is nearest integer to
671
       the fractional pitch lag of the previous subframe.
672
    */
673
204k
    T0 = *pT0_min + acb_idx / 4;
674
204k
    T0_frac = acb_idx & 0x3;
675
204k
  } else { /* num_acb_idx_bits == 9 */
676
    /* When the pitch value is encoded on 9 bits, a fractional pitch delay is
677
       used with resolutions 0.25 in the range [TMIN, TFR2-0.25], resolutions
678
       0.5 in the range [TFR2, TFR1-0.5], and integers only in the range [TFR1,
679
       TMAX]. NOTE: for small sampling rates TMAX can get smaller than TFR1.
680
    */
681
153k
    int T0_min, T0_max;
682
683
153k
    if (acb_idx < (PIT_FR2 - PIT_MIN) * 4) {
684
      /* first interval with 0.25 pitch resolution */
685
91.6k
      T0 = PIT_MIN + (acb_idx / 4);
686
91.6k
      T0_frac = acb_idx & 0x3;
687
91.6k
    } else if (acb_idx < ((PIT_FR2 - PIT_MIN) * 4 + (PIT_FR1 - PIT_FR2) * 2)) {
688
      /* second interval with 0.5 pitch resolution */
689
21.1k
      acb_idx -= (PIT_FR2 - PIT_MIN) * 4;
690
21.1k
      T0 = PIT_FR2 + (acb_idx / 2);
691
21.1k
      T0_frac = (acb_idx & 0x1) * 2;
692
40.7k
    } else {
693
      /* third interval with 1.0 pitch resolution */
694
40.7k
      T0 = acb_idx + PIT_FR1 - ((PIT_FR2 - PIT_MIN) * 4) -
695
40.7k
           ((PIT_FR1 - PIT_FR2) * 2);
696
40.7k
      T0_frac = 0;
697
40.7k
    }
698
    /* find T0_min and T0_max for subframe 1 or 3 */
699
153k
    T0_min = T0 - 8;
700
153k
    if (T0_min < PIT_MIN) {
701
51.9k
      T0_min = PIT_MIN;
702
51.9k
    }
703
153k
    T0_max = T0_min + 15;
704
153k
    if (T0_max > PIT_MAX) {
705
3.97k
      T0_max = PIT_MAX;
706
3.97k
      T0_min = T0_max - 15;
707
3.97k
    }
708
153k
    *pT0_min = T0_min;
709
153k
    *pT0_max = T0_max;
710
153k
  }
711
358k
  *pT0 = T0;
712
358k
  *pT0_frac = T0_frac;
713
714
358k
  return error;
715
358k
}
716
static void ConcealPitchLag(CAcelpStaticMem *acelp_mem, const int PIT_MAX,
717
7.12k
                            int *pT0, int *pT0_frac) {
718
7.12k
  USHORT *pold_T0 = &acelp_mem->old_T0;
719
7.12k
  UCHAR *pold_T0_frac = &acelp_mem->old_T0_frac;
720
721
7.12k
  if ((int)*pold_T0 >= PIT_MAX) {
722
17
    *pold_T0 = (USHORT)(PIT_MAX - 5);
723
17
  }
724
7.12k
  *pT0 = (int)*pold_T0;
725
7.12k
  *pT0_frac = (int)*pold_T0_frac;
726
7.12k
}
727
728
static UCHAR tab_coremode2nbits[8] = {20, 28, 36, 44, 52, 64, 12, 16};
729
730
452k
static int MapCoreMode2NBits(int core_mode) {
731
452k
  return (int)tab_coremode2nbits[core_mode];
732
452k
}
733
734
void CLpd_AcelpDecode(CAcelpStaticMem *acelp_mem, INT i_offset,
735
                      const FIXP_LPC lsp_old[M_LP_FILTER_ORDER],
736
                      const FIXP_LPC lsp_new[M_LP_FILTER_ORDER],
737
                      FIXP_SGL stab_fac, CAcelpChannelData *pAcelpData,
738
                      INT numLostSubframes, int lastLpcLost, int frameCnt,
739
                      FIXP_DBL synth[], int pT[], FIXP_DBL *pit_gain,
740
102k
                      INT coreCoderFrameLength) {
741
102k
  int i_subfr, subfr_nr, l_div, T;
742
102k
  int T0 = -1, T0_frac = -1; /* mark invalid */
743
744
102k
  int pit_gain_index = 0;
745
746
102k
  const int PIT_MAX = PIT_MAX_12k8 + (6 * i_offset); /* maximum pitch lag */
747
748
102k
  FIXP_COD *code;
749
102k
  FIXP_DBL *exc2;
750
102k
  FIXP_DBL *syn;
751
102k
  FIXP_DBL *exc;
752
102k
  FIXP_LPC A[M_LP_FILTER_ORDER];
753
102k
  INT A_exp;
754
755
102k
  FIXP_DBL period_fac;
756
102k
  FIXP_SGL gain_pit;
757
102k
  FIXP_DBL gain_code, gain_code_smooth, Ener_code;
758
102k
  int Ener_code_e;
759
102k
  int n;
760
102k
  int bfi = (numLostSubframes > 0) ? 1 : 0;
761
762
102k
  C_ALLOC_SCRATCH_START(
763
102k
      exc_buf, FIXP_DBL,
764
102k
      PIT_MAX_MAX + L_INTERPOL + L_DIV + 1); /* 411 + 17 + 256 + 1 = 685 */
765
102k
  C_ALLOC_SCRATCH_START(syn_buf, FIXP_DBL,
766
102k
                        M_LP_FILTER_ORDER + L_DIV); /* 16 + 256 = 272 */
767
  /* use same memory for code[L_SUBFR] and exc2[L_SUBFR] */
768
102k
  C_ALLOC_SCRATCH_START(tmp_buf, FIXP_DBL, L_SUBFR); /* 64 */
769
  /* make sure they don't overlap if they are accessed alternatingly in
770
   * BuildAdaptiveExcitation() */
771
102k
#if (COD_BITS == FRACT_BITS)
772
102k
  code = (FIXP_COD *)(tmp_buf + L_SUBFR / 2);
773
#elif (COD_BITS == DFRACT_BITS)
774
  code = (FIXP_COD *)tmp_buf;
775
#endif
776
102k
  exc2 = (FIXP_DBL *)tmp_buf;
777
778
102k
  syn = syn_buf + M_LP_FILTER_ORDER;
779
102k
  exc = exc_buf + PIT_MAX_MAX + L_INTERPOL;
780
781
102k
  FDKmemcpy(syn_buf, acelp_mem->old_syn_mem,
782
102k
            M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
783
102k
  FDKmemcpy(exc_buf, acelp_mem->old_exc_mem,
784
102k
            (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));
785
786
102k
  FDKmemclear(exc_buf + (PIT_MAX_MAX + L_INTERPOL),
787
102k
              (L_DIV + 1) * sizeof(FIXP_DBL));
788
789
102k
  l_div = coreCoderFrameLength / NB_DIV;
790
791
460k
  for (i_subfr = 0, subfr_nr = 0; i_subfr < l_div;
792
357k
       i_subfr += L_SUBFR, subfr_nr++) {
793
    /*-------------------------------------------------*
794
     * - Decode pitch lag (T0 and T0_frac)             *
795
     *-------------------------------------------------*/
796
357k
    if (bfi) {
797
7.12k
      ConcealPitchLag(acelp_mem, PIT_MAX, &T0, &T0_frac);
798
350k
    } else {
799
350k
      T0 = (int)pAcelpData->T0[subfr_nr];
800
350k
      T0_frac = (int)pAcelpData->T0_frac[subfr_nr];
801
350k
    }
802
803
    /*-------------------------------------------------*
804
     * - Find the pitch gain, the interpolation filter *
805
     *   and the adaptive codebook vector.             *
806
     *-------------------------------------------------*/
807
357k
    Pred_lt4(&exc[i_subfr], T0, T0_frac);
808
809
357k
    if ((!bfi && pAcelpData->ltp_filtering_flag[subfr_nr] == 0) ||
810
235k
        (bfi && numLostSubframes == 1 && stab_fac < FL2FXCONST_SGL(0.25f))) {
811
      /* find pitch excitation with lp filter: v'(n) => v(n) */
812
235k
      Pred_lt4_postfilter(&exc[i_subfr]);
813
235k
    }
814
815
    /*-------------------------------------------------------*
816
     * - Decode innovative codebook.                         *
817
     * - Add the fixed-gain pitch contribution to code[].    *
818
     *-------------------------------------------------------*/
819
357k
    if (bfi) {
820
463k
      for (n = 0; n < L_SUBFR; n++) {
821
456k
        code[n] =
822
456k
            FX_SGL2FX_COD((FIXP_SGL)E_UTIL_random(&acelp_mem->seed_ace)) >> 4;
823
456k
      }
824
350k
    } else {
825
350k
      int nbits = MapCoreMode2NBits((int)pAcelpData->acelp_core_mode);
826
350k
      D_ACELP_decode_4t64(pAcelpData->icb_index[subfr_nr], nbits, &code[0]);
827
350k
    }
828
829
357k
    T = T0;
830
357k
    if (T0_frac > 2) {
831
48.6k
      T += 1;
832
48.6k
    }
833
834
357k
    Preemph_code(code);
835
357k
    Pit_shrp(code, T);
836
837
    /* Output pitch lag for bass post-filter */
838
357k
    if (T > PIT_MAX) {
839
2.03k
      pT[subfr_nr] = PIT_MAX;
840
355k
    } else {
841
355k
      pT[subfr_nr] = T;
842
355k
    }
843
357k
    D_gain2_plus(
844
357k
        pAcelpData->gains[subfr_nr],
845
357k
        code,       /* (i)  : Innovative code vector, exponent = SF_CODE */
846
357k
        &gain_pit,  /* (o)  : Quantized pitch gain, exponent = SF_GAIN_P */
847
357k
        &gain_code, /* (o)  : Quantized codebook gain                    */
848
357k
        pAcelpData
849
357k
            ->mean_energy, /* (i)  : mean_ener defined in open-loop (2 bits) */
850
357k
        bfi, &acelp_mem->past_gpit, &acelp_mem->past_gcode,
851
357k
        &Ener_code,    /* (o)  : Innovative code vector energy              */
852
357k
        &Ener_code_e); /* (o)  : Innovative code vector energy exponent     */
853
854
357k
    pit_gain[pit_gain_index++] = FX_SGL2FX_DBL(gain_pit);
855
856
    /* calc periodicity factor r_v */
857
357k
    period_fac =
858
357k
        calc_period_factor(/* (o) : factor (-1=unvoiced to 1=voiced)    */
859
357k
                           &exc[i_subfr], /* (i) : pitch excitation, exponent =
860
                                             SF_EXC */
861
357k
                           gain_pit,      /* (i) : gain of pitch, exponent =
862
                                             SF_GAIN_P */
863
357k
                           gain_code,     /* (i) : gain of code     */
864
357k
                           Ener_code,     /* (i) : Energy of code[]     */
865
357k
                           Ener_code_e);  /* (i) : Exponent of energy of code[]
866
                                           */
867
868
357k
    if (lastLpcLost && frameCnt == 0) {
869
535
      if (gain_pit > FL2FXCONST_SGL(1.0f / (1 << SF_GAIN_P))) {
870
15
        gain_pit = FL2FXCONST_SGL(1.0f / (1 << SF_GAIN_P));
871
15
      }
872
535
    }
873
874
357k
    gain_code_smooth =
875
357k
        noise_enhancer(/* (o) : smoothed gain g_sc exponent = SF_GAIN_C */
876
357k
                       gain_code,  /* (i) : Quantized codebook gain  */
877
357k
                       period_fac, /* (i) : periodicity factor (-1=unvoiced to
878
                                      1=voiced)  */
879
357k
                       stab_fac,   /* (i) : stability factor (0 <= ... < 1),
880
                                      exponent = 1 */
881
357k
                       &acelp_mem->gc_threshold);
882
883
    /* Compute adaptive codebook update u'(n), pitch enhancement c'(n) and
884
     * post-processed excitation u(n). */
885
357k
    BuildAdaptiveExcitation(code, exc + i_subfr, gain_pit, gain_code,
886
357k
                            gain_code_smooth, period_fac, exc2);
887
888
    /* Interpolate filter coeffs for current subframe in lsp domain and convert
889
     * to LP domain */
890
357k
    int_lpc_acelp(lsp_old,  /* input : LSPs from past frame              */
891
357k
                  lsp_new,  /* input : LSPs from present frame           */
892
357k
                  subfr_nr, /* input : ACELP subframe index              */
893
357k
                  coreCoderFrameLength / L_DIV,
894
357k
                  A, /* output: LP coefficients of this subframe  */
895
357k
                  &A_exp);
896
897
357k
    Syn_filt(A, /* (i) : a[m] prediction coefficients               */
898
357k
             A_exp, L_SUBFR, /* (i) : length */
899
357k
             exc2, /* (i) : input signal                               */
900
357k
             &syn[i_subfr] /* (i/o) : filter states / output signal */
901
357k
    );
902
903
357k
  } /* end of subframe loop */
904
905
  /* update pitch value for bfi procedure */
906
102k
  acelp_mem->old_T0_frac = T0_frac;
907
102k
  acelp_mem->old_T0 = T0;
908
909
  /* save old excitation and old synthesis memory for next ACELP frame */
910
102k
  FDKmemcpy(acelp_mem->old_exc_mem, exc + l_div - (PIT_MAX_MAX + L_INTERPOL),
911
102k
            sizeof(FIXP_DBL) * (PIT_MAX_MAX + L_INTERPOL));
912
102k
  FDKmemcpy(acelp_mem->old_syn_mem, syn_buf + l_div,
913
102k
            sizeof(FIXP_DBL) * M_LP_FILTER_ORDER);
914
915
102k
  Deemph(syn, synth, l_div,
916
102k
         &acelp_mem->de_emph_mem); /* ref soft: mem = synth[-1] */
917
918
102k
  scaleValues(synth, l_div, -ACELP_OUTSCALE);
919
102k
  acelp_mem->deemph_mem_wsyn = acelp_mem->de_emph_mem;
920
921
102k
  C_ALLOC_SCRATCH_END(tmp_buf, FIXP_DBL, L_SUBFR);
922
102k
  C_ALLOC_SCRATCH_END(syn_buf, FIXP_DBL, M_LP_FILTER_ORDER + L_DIV);
923
102k
  C_ALLOC_SCRATCH_END(exc_buf, FIXP_DBL, PIT_MAX_MAX + L_INTERPOL + L_DIV + 1);
924
102k
  return;
925
102k
}
926
927
30.4k
void CLpd_AcelpReset(CAcelpStaticMem *acelp) {
928
30.4k
  acelp->gc_threshold = (FIXP_DBL)0;
929
930
30.4k
  acelp->past_gpit = (FIXP_SGL)0;
931
30.4k
  acelp->past_gcode = (FIXP_DBL)0;
932
30.4k
  acelp->old_T0 = 64;
933
30.4k
  acelp->old_T0_frac = 0;
934
30.4k
  acelp->deemph_mem_wsyn = (FIXP_DBL)0;
935
30.4k
  acelp->wsyn_rms = (FIXP_DBL)0;
936
30.4k
  acelp->seed_ace = 0;
937
30.4k
}
938
939
/* TCX time domain concealment */
940
/*   Compare to figure 13a on page 54 in 3GPP TS 26.290 */
941
void CLpd_TcxTDConceal(CAcelpStaticMem *acelp_mem, SHORT *pitch,
942
                       const FIXP_LPC lsp_old[M_LP_FILTER_ORDER],
943
                       const FIXP_LPC lsp_new[M_LP_FILTER_ORDER],
944
                       const FIXP_SGL stab_fac, INT nLostSf, FIXP_DBL synth[],
945
1.48k
                       INT coreCoderFrameLength, UCHAR last_tcx_noise_factor) {
946
  /* repeat past excitation with pitch from previous decoded TCX frame */
947
1.48k
  C_ALLOC_SCRATCH_START(
948
1.48k
      exc_buf, FIXP_DBL,
949
1.48k
      PIT_MAX_MAX + L_INTERPOL + L_DIV); /* 411 +  17 + 256 + 1 =  */
950
1.48k
  C_ALLOC_SCRATCH_START(syn_buf, FIXP_DBL,
951
1.48k
                        M_LP_FILTER_ORDER + L_DIV); /* 256 +  16           =  */
952
                                                    /*                    +=  */
953
1.48k
  FIXP_DBL ns_buf[L_DIV + 1];
954
1.48k
  FIXP_DBL *syn = syn_buf + M_LP_FILTER_ORDER;
955
1.48k
  FIXP_DBL *exc = exc_buf + PIT_MAX_MAX + L_INTERPOL;
956
1.48k
  FIXP_DBL *ns = ns_buf + 1;
957
1.48k
  FIXP_DBL tmp, fact_exc;
958
1.48k
  INT T = fMin(*pitch, (SHORT)PIT_MAX_MAX);
959
1.48k
  int i, i_subfr, subfr_nr;
960
1.48k
  int lDiv = coreCoderFrameLength / NB_DIV;
961
962
1.48k
  FDKmemcpy(syn_buf, acelp_mem->old_syn_mem,
963
1.48k
            M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
964
1.48k
  FDKmemcpy(exc_buf, acelp_mem->old_exc_mem,
965
1.48k
            (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));
966
967
  /* if we lost all packets (i.e. 1 packet of TCX-20 ms, 2 packets of
968
     the TCX-40 ms or 4 packets of the TCX-80ms), we lost the whole
969
     coded frame extrapolation strategy: repeat lost excitation and
970
     use extrapolated LSFs */
971
972
  /* AMR-WB+ like TCX TD concealment */
973
974
  /* number of lost frame cmpt */
975
1.48k
  if (nLostSf < 2) {
976
291
    fact_exc = FL2FXCONST_DBL(0.8f);
977
1.19k
  } else {
978
1.19k
    fact_exc = FL2FXCONST_DBL(0.4f);
979
1.19k
  }
980
981
  /* repeat past excitation */
982
342k
  for (i = 0; i < lDiv; i++) {
983
341k
    exc[i] = fMult(fact_exc, exc[i - T]);
984
341k
  }
985
986
1.48k
  tmp = fMult(fact_exc, acelp_mem->wsyn_rms);
987
1.48k
  acelp_mem->wsyn_rms = tmp;
988
989
  /* init deemph_mem_wsyn */
990
1.48k
  acelp_mem->deemph_mem_wsyn = exc[-1];
991
992
1.48k
  ns[-1] = acelp_mem->deemph_mem_wsyn;
993
994
6.82k
  for (i_subfr = 0, subfr_nr = 0; i_subfr < lDiv;
995
5.33k
       i_subfr += L_SUBFR, subfr_nr++) {
996
5.33k
    FIXP_DBL tRes[L_SUBFR];
997
5.33k
    FIXP_LPC A[M_LP_FILTER_ORDER];
998
5.33k
    INT A_exp;
999
1000
    /* interpolate LPC coefficients */
1001
5.33k
    int_lpc_acelp(lsp_old, lsp_new, subfr_nr, lDiv / L_SUBFR, A, &A_exp);
1002
1003
5.33k
    Syn_filt(A,              /* (i) : a[m] prediction coefficients         */
1004
5.33k
             A_exp, L_SUBFR, /* (i) : length                               */
1005
5.33k
             &exc[i_subfr],  /* (i) : input signal                         */
1006
5.33k
             &syn[i_subfr]   /* (i/o) : filter states / output signal      */
1007
5.33k
    );
1008
1009
5.33k
    E_LPC_a_weight(
1010
5.33k
        A, A,
1011
5.33k
        M_LP_FILTER_ORDER); /* overwrite A as it is not needed any longer */
1012
1013
5.33k
    E_UTIL_residu(A, A_exp, &syn[i_subfr], tRes, L_SUBFR);
1014
1015
5.33k
    Deemph(tRes, &ns[i_subfr], L_SUBFR, &acelp_mem->deemph_mem_wsyn);
1016
1017
    /* Amplitude limiter (saturate at wsyn_rms) */
1018
346k
    for (i = i_subfr; i < i_subfr + L_SUBFR; i++) {
1019
341k
      if (ns[i] > tmp) {
1020
100k
        ns[i] = tmp;
1021
241k
      } else {
1022
241k
        if (ns[i] < -tmp) {
1023
96.5k
          ns[i] = -tmp;
1024
96.5k
        }
1025
241k
      }
1026
341k
    }
1027
1028
5.33k
    E_UTIL_preemph(&ns[i_subfr], tRes, L_SUBFR);
1029
1030
5.33k
    Syn_filt(A,              /* (i) : a[m] prediction coefficients         */
1031
5.33k
             A_exp, L_SUBFR, /* (i) : length                               */
1032
5.33k
             tRes,           /* (i) : input signal                         */
1033
5.33k
             &syn[i_subfr]   /* (i/o) : filter states / output signal      */
1034
5.33k
    );
1035
1036
5.33k
    FDKmemmove(&synth[i_subfr], &syn[i_subfr], L_SUBFR * sizeof(FIXP_DBL));
1037
5.33k
  }
1038
1039
  /* save old excitation and old synthesis memory for next ACELP frame */
1040
1.48k
  FDKmemcpy(acelp_mem->old_exc_mem, exc + lDiv - (PIT_MAX_MAX + L_INTERPOL),
1041
1.48k
            sizeof(FIXP_DBL) * (PIT_MAX_MAX + L_INTERPOL));
1042
1.48k
  FDKmemcpy(acelp_mem->old_syn_mem, syn_buf + lDiv,
1043
1.48k
            sizeof(FIXP_DBL) * M_LP_FILTER_ORDER);
1044
1.48k
  acelp_mem->de_emph_mem = acelp_mem->deemph_mem_wsyn;
1045
1046
1.48k
  C_ALLOC_SCRATCH_END(syn_buf, FIXP_DBL, M_LP_FILTER_ORDER + L_DIV);
1047
1.48k
  C_ALLOC_SCRATCH_END(exc_buf, FIXP_DBL, PIT_MAX_MAX + L_INTERPOL + L_DIV);
1048
1.48k
}
1049
1050
void Acelp_PreProcessing(FIXP_DBL *synth_buf, FIXP_DBL *old_synth, INT *pitch,
1051
                         INT *old_T_pf, FIXP_DBL *pit_gain,
1052
                         FIXP_DBL *old_gain_pf, INT samplingRate, INT *i_offset,
1053
                         INT coreCoderFrameLength, INT synSfd,
1054
43.4k
                         INT nbSubfrSuperfr) {
1055
43.4k
  int n;
1056
1057
  /* init beginning of synth_buf with old synthesis from previous frame */
1058
43.4k
  FDKmemcpy(synth_buf, old_synth, sizeof(FIXP_DBL) * (PIT_MAX_MAX - BPF_DELAY));
1059
1060
  /* calculate pitch lag offset for ACELP decoder */
1061
43.4k
  *i_offset =
1062
43.4k
      (samplingRate * PIT_MIN_12k8 + (FSCALE_DENOM / 2)) / FSCALE_DENOM -
1063
43.4k
      PIT_MIN_12k8;
1064
1065
  /* for bass postfilter */
1066
302k
  for (n = 0; n < synSfd; n++) {
1067
258k
    pitch[n] = old_T_pf[n];
1068
258k
    pit_gain[n] = old_gain_pf[n];
1069
258k
  }
1070
648k
  for (n = 0; n < nbSubfrSuperfr; n++) {
1071
604k
    pitch[n + synSfd] = L_SUBFR;
1072
604k
    pit_gain[n + synSfd] = (FIXP_DBL)0;
1073
604k
  }
1074
43.4k
}
1075
1076
void Acelp_PostProcessing(FIXP_DBL *synth_buf, FIXP_DBL *old_synth, INT *pitch,
1077
                          INT *old_T_pf, INT coreCoderFrameLength, INT synSfd,
1078
43.4k
                          INT nbSubfrSuperfr) {
1079
43.4k
  int n;
1080
1081
  /* store last part of synth_buf (which is not handled by the IMDCT overlap)
1082
   * for next frame */
1083
43.4k
  FDKmemcpy(old_synth, synth_buf + coreCoderFrameLength,
1084
43.4k
            sizeof(FIXP_DBL) * (PIT_MAX_MAX - BPF_DELAY));
1085
1086
  /* for bass postfilter */
1087
302k
  for (n = 0; n < synSfd; n++) {
1088
258k
    old_T_pf[n] = pitch[nbSubfrSuperfr + n];
1089
258k
  }
1090
43.4k
}
1091
1092
41.2k
#define L_FAC_ZIR (LFAC)
1093
1094
void CLpd_Acelp_Zir(const FIXP_LPC A[], const INT A_exp,
1095
                    CAcelpStaticMem *acelp_mem, const INT length,
1096
41.2k
                    FIXP_DBL zir[], int doDeemph) {
1097
41.2k
  C_ALLOC_SCRATCH_START(tmp_buf, FIXP_DBL, L_FAC_ZIR + M_LP_FILTER_ORDER);
1098
41.2k
  FDK_ASSERT(length <= L_FAC_ZIR);
1099
1100
41.2k
  FDKmemcpy(tmp_buf, acelp_mem->old_syn_mem,
1101
41.2k
            M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
1102
41.2k
  FDKmemset(tmp_buf + M_LP_FILTER_ORDER, 0, L_FAC_ZIR * sizeof(FIXP_DBL));
1103
1104
41.2k
  Syn_filt(A, A_exp, length, &tmp_buf[M_LP_FILTER_ORDER],
1105
41.2k
           &tmp_buf[M_LP_FILTER_ORDER]);
1106
41.2k
  if (!doDeemph) {
1107
    /* if last lpd mode was TD concealment, then bypass deemph */
1108
6
    FDKmemcpy(zir, tmp_buf, length * sizeof(*zir));
1109
41.2k
  } else {
1110
41.2k
    Deemph(&tmp_buf[M_LP_FILTER_ORDER], &zir[0], length,
1111
41.2k
           &acelp_mem->de_emph_mem);
1112
41.2k
    scaleValues(zir, length, -ACELP_OUTSCALE);
1113
41.2k
  }
1114
41.2k
  C_ALLOC_SCRATCH_END(tmp_buf, FIXP_DBL, L_FAC_ZIR + M_LP_FILTER_ORDER);
1115
41.2k
}
1116
1117
void CLpd_AcelpPrepareInternalMem(const FIXP_DBL *synth, UCHAR last_lpd_mode,
1118
                                  UCHAR last_last_lpd_mode,
1119
                                  const FIXP_LPC *A_new, const INT A_new_exp,
1120
                                  const FIXP_LPC *A_old, const INT A_old_exp,
1121
                                  CAcelpStaticMem *acelp_mem,
1122
                                  INT coreCoderFrameLength, INT clearOldExc,
1123
49.1k
                                  UCHAR lpd_mode) {
1124
49.1k
  int l_div =
1125
49.1k
      coreCoderFrameLength / NB_DIV; /* length of one ACELP/TCX20 frame */
1126
49.1k
  int l_div_partial;
1127
49.1k
  FIXP_DBL *syn, *old_exc_mem;
1128
1129
49.1k
  C_ALLOC_SCRATCH_START(synth_buf, FIXP_DBL,
1130
49.1k
                        PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
1131
49.1k
  syn = &synth_buf[M_LP_FILTER_ORDER];
1132
1133
49.1k
  l_div_partial = PIT_MAX_MAX + L_INTERPOL - l_div;
1134
49.1k
  old_exc_mem = acelp_mem->old_exc_mem;
1135
1136
49.1k
  if (lpd_mode == 4) {
1137
    /* Bypass Domain conversion. TCXTD Concealment does no deemphasis in the
1138
     * end. */
1139
291
    FDKmemcpy(
1140
291
        synth_buf, &synth[-(PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER)],
1141
291
        (PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER) * sizeof(FIXP_DBL));
1142
    /* Set deemphasis memory state for TD concealment */
1143
291
    acelp_mem->deemph_mem_wsyn = scaleValueSaturate(synth[-1], ACELP_OUTSCALE);
1144
48.8k
  } else {
1145
    /* convert past [PIT_MAX_MAX+L_INTERPOL+M_LP_FILTER_ORDER] synthesis to
1146
     * preemph domain */
1147
48.8k
    E_UTIL_preemph(&synth[-(PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER)],
1148
48.8k
                   synth_buf, PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
1149
48.8k
    scaleValuesSaturate(synth_buf, PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER,
1150
48.8k
                        ACELP_OUTSCALE);
1151
48.8k
  }
1152
1153
  /* Set deemphasis memory state */
1154
49.1k
  acelp_mem->de_emph_mem = scaleValueSaturate(synth[-1], ACELP_OUTSCALE);
1155
1156
  /* update acelp synth filter memory */
1157
49.1k
  FDKmemcpy(acelp_mem->old_syn_mem,
1158
49.1k
            &syn[PIT_MAX_MAX + L_INTERPOL - M_LP_FILTER_ORDER],
1159
49.1k
            M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
1160
1161
49.1k
  if (clearOldExc) {
1162
1
    FDKmemclear(old_exc_mem, (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));
1163
1
    C_ALLOC_SCRATCH_END(synth_buf, FIXP_DBL,
1164
1
                        PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
1165
1
    return;
1166
1
  }
1167
1168
  /* update past [PIT_MAX_MAX+L_INTERPOL] samples of exc memory */
1169
49.1k
  if (last_lpd_mode == 1) {        /* last frame was TCX20 */
1170
24.3k
    if (last_last_lpd_mode == 0) { /* ACELP -> TCX20 -> ACELP transition */
1171
      /* Delay valid part of excitation buffer (from previous ACELP frame) by
1172
       * l_div samples */
1173
13.0k
      FDKmemmove(old_exc_mem, old_exc_mem + l_div,
1174
13.0k
                 sizeof(FIXP_DBL) * l_div_partial);
1175
13.0k
    } else if (last_last_lpd_mode > 0) { /* TCX -> TCX20 -> ACELP transition */
1176
11.3k
      E_UTIL_residu(A_old, A_old_exp, syn, old_exc_mem, l_div_partial);
1177
11.3k
    }
1178
24.3k
    E_UTIL_residu(A_new, A_new_exp, syn + l_div_partial,
1179
24.3k
                  old_exc_mem + l_div_partial, l_div);
1180
24.7k
  } else { /* prev frame was FD, TCX40 or TCX80 */
1181
24.7k
    int exc_A_new_length = (coreCoderFrameLength / 2 > PIT_MAX_MAX + L_INTERPOL)
1182
24.7k
                               ? PIT_MAX_MAX + L_INTERPOL
1183
24.7k
                               : coreCoderFrameLength / 2;
1184
24.7k
    int exc_A_old_length = PIT_MAX_MAX + L_INTERPOL - exc_A_new_length;
1185
24.7k
    E_UTIL_residu(A_old, A_old_exp, syn, old_exc_mem, exc_A_old_length);
1186
24.7k
    E_UTIL_residu(A_new, A_new_exp, &syn[exc_A_old_length],
1187
24.7k
                  &old_exc_mem[exc_A_old_length], exc_A_new_length);
1188
24.7k
  }
1189
49.1k
  C_ALLOC_SCRATCH_END(synth_buf, FIXP_DBL,
1190
49.1k
                      PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
1191
1192
49.1k
  return;
1193
49.1k
}
1194
1195
41.2k
FIXP_DBL *CLpd_ACELP_GetFreeExcMem(CAcelpStaticMem *acelp_mem, INT length) {
1196
41.2k
  FDK_ASSERT(length <= PIT_MAX_MAX + L_INTERPOL);
1197
41.2k
  return acelp_mem->old_exc_mem;
1198
41.2k
}
1199
1200
INT CLpd_AcelpRead(HANDLE_FDK_BITSTREAM hBs, CAcelpChannelData *acelp,
1201
                   INT acelp_core_mode, INT coreCoderFrameLength,
1202
102k
                   INT i_offset) {
1203
102k
  int nb_subfr = coreCoderFrameLength / L_DIV;
1204
102k
  const UCHAR *num_acb_index_bits =
1205
102k
      (nb_subfr == 4) ? num_acb_idx_bits_table[0] : num_acb_idx_bits_table[1];
1206
102k
  int nbits;
1207
102k
  int error = 0;
1208
1209
102k
  const int PIT_MIN = PIT_MIN_12k8 + i_offset;
1210
102k
  const int PIT_FR2 = PIT_FR2_12k8 - i_offset;
1211
102k
  const int PIT_FR1 = PIT_FR1_12k8;
1212
102k
  const int PIT_MAX = PIT_MAX_12k8 + (6 * i_offset);
1213
102k
  int T0, T0_frac, T0_min = 0, T0_max;
1214
1215
102k
  if (PIT_MAX > PIT_MAX_MAX) {
1216
0
    error = AAC_DEC_DECODE_FRAME_ERROR;
1217
0
    goto bail;
1218
0
  }
1219
1220
102k
  acelp->acelp_core_mode = acelp_core_mode;
1221
1222
102k
  nbits = MapCoreMode2NBits(acelp_core_mode);
1223
1224
  /* decode mean energy with 2 bits : 18, 30, 42 or 54 dB */
1225
102k
  acelp->mean_energy = FDKreadBits(hBs, 2);
1226
1227
460k
  for (int sfr = 0; sfr < nb_subfr; sfr++) {
1228
    /* read ACB index and store T0 and T0_frac for each ACELP subframe. */
1229
358k
    error = DecodePitchLag(hBs, num_acb_index_bits[sfr], PIT_MIN, PIT_FR2,
1230
358k
                           PIT_FR1, PIT_MAX, &T0, &T0_frac, &T0_min, &T0_max);
1231
358k
    if (error) {
1232
0
      goto bail;
1233
0
    }
1234
358k
    acelp->T0[sfr] = (USHORT)T0;
1235
358k
    acelp->T0_frac[sfr] = (UCHAR)T0_frac;
1236
358k
    acelp->ltp_filtering_flag[sfr] = FDKreadBits(hBs, 1);
1237
358k
    switch (nbits) {
1238
32.7k
      case 12: /* 12 bits AMR-WB codebook is used */
1239
32.7k
        acelp->icb_index[sfr][0] = FDKreadBits(hBs, 1);
1240
32.7k
        acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);
1241
32.7k
        acelp->icb_index[sfr][2] = FDKreadBits(hBs, 1);
1242
32.7k
        acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
1243
32.7k
        break;
1244
85.3k
      case 16: /* 16 bits AMR-WB codebook is used */
1245
85.3k
        acelp->icb_index[sfr][0] = FDKreadBits(hBs, 1);
1246
85.3k
        acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);
1247
85.3k
        acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);
1248
85.3k
        acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
1249
85.3k
        break;
1250
159k
      case 20: /* 20 bits AMR-WB codebook is used */
1251
159k
        acelp->icb_index[sfr][0] = FDKreadBits(hBs, 5);
1252
159k
        acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);
1253
159k
        acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);
1254
159k
        acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
1255
159k
        break;
1256
16.2k
      case 28: /* 28 bits AMR-WB codebook is used */
1257
16.2k
        acelp->icb_index[sfr][0] = FDKreadBits(hBs, 9);
1258
16.2k
        acelp->icb_index[sfr][1] = FDKreadBits(hBs, 9);
1259
16.2k
        acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);
1260
16.2k
        acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
1261
16.2k
        break;
1262
15.1k
      case 36: /* 36 bits AMR-WB codebook is used */
1263
15.1k
        acelp->icb_index[sfr][0] = FDKreadBits(hBs, 9);
1264
15.1k
        acelp->icb_index[sfr][1] = FDKreadBits(hBs, 9);
1265
15.1k
        acelp->icb_index[sfr][2] = FDKreadBits(hBs, 9);
1266
15.1k
        acelp->icb_index[sfr][3] = FDKreadBits(hBs, 9);
1267
15.1k
        break;
1268
8.17k
      case 44: /* 44 bits AMR-WB codebook is used */
1269
8.17k
        acelp->icb_index[sfr][0] = FDKreadBits(hBs, 13);
1270
8.17k
        acelp->icb_index[sfr][1] = FDKreadBits(hBs, 13);
1271
8.17k
        acelp->icb_index[sfr][2] = FDKreadBits(hBs, 9);
1272
8.17k
        acelp->icb_index[sfr][3] = FDKreadBits(hBs, 9);
1273
8.17k
        break;
1274
7.52k
      case 52: /* 52 bits AMR-WB codebook is used */
1275
7.52k
        acelp->icb_index[sfr][0] = FDKreadBits(hBs, 13);
1276
7.52k
        acelp->icb_index[sfr][1] = FDKreadBits(hBs, 13);
1277
7.52k
        acelp->icb_index[sfr][2] = FDKreadBits(hBs, 13);
1278
7.52k
        acelp->icb_index[sfr][3] = FDKreadBits(hBs, 13);
1279
7.52k
        break;
1280
33.1k
      case 64: /* 64 bits AMR-WB codebook is used */
1281
33.1k
        acelp->icb_index[sfr][0] = FDKreadBits(hBs, 2);
1282
33.1k
        acelp->icb_index[sfr][1] = FDKreadBits(hBs, 2);
1283
33.1k
        acelp->icb_index[sfr][2] = FDKreadBits(hBs, 2);
1284
33.1k
        acelp->icb_index[sfr][3] = FDKreadBits(hBs, 2);
1285
33.1k
        acelp->icb_index[sfr][4] = FDKreadBits(hBs, 14);
1286
33.1k
        acelp->icb_index[sfr][5] = FDKreadBits(hBs, 14);
1287
33.1k
        acelp->icb_index[sfr][6] = FDKreadBits(hBs, 14);
1288
33.1k
        acelp->icb_index[sfr][7] = FDKreadBits(hBs, 14);
1289
33.1k
        break;
1290
0
      default:
1291
0
        FDK_ASSERT(0);
1292
0
        break;
1293
358k
    }
1294
358k
    acelp->gains[sfr] = FDKreadBits(hBs, 7);
1295
358k
  }
1296
1297
102k
bail:
1298
102k
  return error;
1299
102k
}