Coverage Report

Created: 2025-07-11 06:50

/src/aac/libSBRenc/src/ps_encode.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
/**************************** SBR encoder library ******************************
96
97
   Author(s):   M. Neuendorf, N. Rettelbach, M. Multrus
98
99
   Description: PS parameter extraction, encoding
100
101
*******************************************************************************/
102
103
/*!
104
  \file
105
  \brief  PS parameter extraction, encoding functions $Revision: 96441 $
106
*/
107
108
#include "ps_main.h"
109
#include "ps_encode.h"
110
#include "qmf.h"
111
#include "sbr_misc.h"
112
#include "sbrenc_ram.h"
113
114
#include "genericStds.h"
115
116
inline void FDKsbrEnc_addFIXP_DBL(const FIXP_DBL *X, const FIXP_DBL *Y,
117
0
                                  FIXP_DBL *Z, INT n) {
118
0
  for (INT i = 0; i < n; i++) Z[i] = (X[i] >> 1) + (Y[i] >> 1);
119
0
}
120
121
#define LOG10_2_10 3.01029995664f /* 10.0f*log10(2.f) */
122
123
static const INT
124
    iidGroupBordersLoRes[QMF_GROUPS_LO_RES + SUBQMF_GROUPS_LO_RES + 1] = {
125
        0,  1,  2,  3,  4,  5, /* 6 subqmf subbands - 0th qmf subband */
126
        6,  7,                 /* 2 subqmf subbands - 1st qmf subband */
127
        8,  9,                 /* 2 subqmf subbands - 2nd qmf subband */
128
        10, 11, 12, 13, 14, 15, 16, 18, 21, 25, 30, 42, 71};
129
130
static const UCHAR
131
    iidGroupWidthLdLoRes[QMF_GROUPS_LO_RES + SUBQMF_GROUPS_LO_RES] = {
132
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 4, 5};
133
134
static const INT subband2parameter20[QMF_GROUPS_LO_RES + SUBQMF_GROUPS_LO_RES] =
135
    {1, 0, 0,  1,  2,  3, /* 6 subqmf subbands - 0th qmf subband */
136
     4, 5,                /* 2 subqmf subbands - 1st qmf subband */
137
     6, 7,                /* 2 subqmf subbands - 2nd qmf subband */
138
     8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
139
140
typedef enum {
141
  MAX_TIME_DIFF_FRAMES = 20,
142
  MAX_PS_NOHEADER_CNT = 10,
143
  MAX_NOENV_CNT = 10,
144
  DO_NOT_USE_THIS_MODE = 0x7FFFFF
145
} __PS_CONSTANTS;
146
147
static const FIXP_DBL iidQuant_fx[15] = {
148
    (FIXP_DBL)0xce000000, (FIXP_DBL)0xdc000000, (FIXP_DBL)0xe4000000,
149
    (FIXP_DBL)0xec000000, (FIXP_DBL)0xf2000000, (FIXP_DBL)0xf8000000,
150
    (FIXP_DBL)0xfc000000, (FIXP_DBL)0x00000000, (FIXP_DBL)0x04000000,
151
    (FIXP_DBL)0x08000000, (FIXP_DBL)0x0e000000, (FIXP_DBL)0x14000000,
152
    (FIXP_DBL)0x1c000000, (FIXP_DBL)0x24000000, (FIXP_DBL)0x32000000};
153
154
static const FIXP_DBL iidQuantFine_fx[31] = {
155
    (FIXP_DBL)0x9c000001, (FIXP_DBL)0xa6000001, (FIXP_DBL)0xb0000001,
156
    (FIXP_DBL)0xba000001, (FIXP_DBL)0xc4000000, (FIXP_DBL)0xce000000,
157
    (FIXP_DBL)0xd4000000, (FIXP_DBL)0xda000000, (FIXP_DBL)0xe0000000,
158
    (FIXP_DBL)0xe6000000, (FIXP_DBL)0xec000000, (FIXP_DBL)0xf0000000,
159
    (FIXP_DBL)0xf4000000, (FIXP_DBL)0xf8000000, (FIXP_DBL)0xfc000000,
160
    (FIXP_DBL)0x00000000, (FIXP_DBL)0x04000000, (FIXP_DBL)0x08000000,
161
    (FIXP_DBL)0x0c000000, (FIXP_DBL)0x10000000, (FIXP_DBL)0x14000000,
162
    (FIXP_DBL)0x1a000000, (FIXP_DBL)0x20000000, (FIXP_DBL)0x26000000,
163
    (FIXP_DBL)0x2c000000, (FIXP_DBL)0x32000000, (FIXP_DBL)0x3c000000,
164
    (FIXP_DBL)0x45ffffff, (FIXP_DBL)0x4fffffff, (FIXP_DBL)0x59ffffff,
165
    (FIXP_DBL)0x63ffffff};
166
167
static const FIXP_DBL iccQuant[8] = {
168
    (FIXP_DBL)0x7fffffff, (FIXP_DBL)0x77ef9d7f, (FIXP_DBL)0x6babc97f,
169
    (FIXP_DBL)0x4ceaf27f, (FIXP_DBL)0x2f0ed3c0, (FIXP_DBL)0x00000000,
170
    (FIXP_DBL)0xb49ba601, (FIXP_DBL)0x80000000};
171
172
0
static FDK_PSENC_ERROR InitPSData(HANDLE_PS_DATA hPsData) {
173
0
  FDK_PSENC_ERROR error = PSENC_OK;
174
175
0
  if (hPsData == NULL) {
176
0
    error = PSENC_INVALID_HANDLE;
177
0
  } else {
178
0
    int i, env;
179
0
    FDKmemclear(hPsData, sizeof(PS_DATA));
180
181
0
    for (i = 0; i < PS_MAX_BANDS; i++) {
182
0
      hPsData->iidIdxLast[i] = 0;
183
0
      hPsData->iccIdxLast[i] = 0;
184
0
    }
185
186
0
    hPsData->iidEnable = hPsData->iidEnableLast = 0;
187
0
    hPsData->iccEnable = hPsData->iccEnableLast = 0;
188
0
    hPsData->iidQuantMode = hPsData->iidQuantModeLast = PS_IID_RES_COARSE;
189
0
    hPsData->iccQuantMode = hPsData->iccQuantModeLast = PS_ICC_ROT_A;
190
191
0
    for (env = 0; env < PS_MAX_ENVELOPES; env++) {
192
0
      hPsData->iccDiffMode[env] = PS_DELTA_FREQ;
193
0
      hPsData->iccDiffMode[env] = PS_DELTA_FREQ;
194
195
0
      for (i = 0; i < PS_MAX_BANDS; i++) {
196
0
        hPsData->iidIdx[env][i] = 0;
197
0
        hPsData->iccIdx[env][i] = 0;
198
0
      }
199
0
    }
200
201
0
    hPsData->nEnvelopesLast = 0;
202
203
0
    hPsData->headerCnt = MAX_PS_NOHEADER_CNT;
204
0
    hPsData->iidTimeCnt = MAX_TIME_DIFF_FRAMES;
205
0
    hPsData->iccTimeCnt = MAX_TIME_DIFF_FRAMES;
206
0
    hPsData->noEnvCnt = MAX_NOENV_CNT;
207
0
  }
208
209
0
  return error;
210
0
}
211
212
static FIXP_DBL quantizeCoef(const FIXP_DBL *RESTRICT input, const INT nBands,
213
                             const FIXP_DBL *RESTRICT quantTable,
214
                             const INT idxOffset, const INT nQuantSteps,
215
0
                             INT *RESTRICT quantOut) {
216
0
  INT idx, band;
217
0
  FIXP_DBL quantErr = FL2FXCONST_DBL(0.f);
218
219
0
  for (band = 0; band < nBands; band++) {
220
0
    for (idx = 0; idx < nQuantSteps - 1; idx++) {
221
0
      if (fixp_abs((input[band] >> 1) - (quantTable[idx + 1] >> 1)) >
222
0
          fixp_abs((input[band] >> 1) - (quantTable[idx] >> 1))) {
223
0
        break;
224
0
      }
225
0
    }
226
0
    quantErr += (fixp_abs(input[band] - quantTable[idx]) >>
227
0
                 PS_QUANT_SCALE); /* don't scale before subtraction; diff
228
                                     smaller (64-25)/64 */
229
0
    quantOut[band] = idx - idxOffset;
230
0
  }
231
232
0
  return quantErr;
233
0
}
234
235
0
static INT getICCMode(const INT nBands, const INT rotType) {
236
0
  INT mode = 0;
237
238
0
  switch (nBands) {
239
0
    case PS_BANDS_COARSE:
240
0
      mode = PS_RES_COARSE;
241
0
      break;
242
0
    case PS_BANDS_MID:
243
0
      mode = PS_RES_MID;
244
0
      break;
245
0
    default:
246
0
      mode = 0;
247
0
  }
248
0
  if (rotType == PS_ICC_ROT_B) {
249
0
    mode += 3;
250
0
  }
251
252
0
  return mode;
253
0
}
254
255
0
static INT getIIDMode(const INT nBands, const INT iidRes) {
256
0
  INT mode = 0;
257
258
0
  switch (nBands) {
259
0
    case PS_BANDS_COARSE:
260
0
      mode = PS_RES_COARSE;
261
0
      break;
262
0
    case PS_BANDS_MID:
263
0
      mode = PS_RES_MID;
264
0
      break;
265
0
    default:
266
0
      mode = 0;
267
0
      break;
268
0
  }
269
270
0
  if (iidRes == PS_IID_RES_FINE) {
271
0
    mode += 3;
272
0
  }
273
274
0
  return mode;
275
0
}
276
277
static INT envelopeReducible(FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS],
278
                             FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS],
279
0
                             INT psBands, INT nEnvelopes) {
280
0
#define THRESH_SCALE 7
281
282
0
  INT reducible = 1; /* true */
283
0
  INT e = 0, b = 0;
284
0
  FIXP_DBL dIid = FL2FXCONST_DBL(0.f);
285
0
  FIXP_DBL dIcc = FL2FXCONST_DBL(0.f);
286
287
0
  FIXP_DBL iidErrThreshold, iccErrThreshold;
288
0
  FIXP_DBL iidMeanError, iccMeanError;
289
290
  /* square values to prevent sqrt,
291
     multiply bands to prevent division; bands shifted DFRACT_BITS instead
292
     (DFRACT_BITS-1) because fMultDiv2 used*/
293
0
  iidErrThreshold =
294
0
      fMultDiv2(FL2FXCONST_DBL(6.5f * 6.5f / (IID_SCALE_FT * IID_SCALE_FT)),
295
0
                (FIXP_DBL)(psBands << ((DFRACT_BITS)-THRESH_SCALE)));
296
0
  iccErrThreshold =
297
0
      fMultDiv2(FL2FXCONST_DBL(0.75f * 0.75f),
298
0
                (FIXP_DBL)(psBands << ((DFRACT_BITS)-THRESH_SCALE)));
299
300
0
  if (nEnvelopes <= 1) {
301
0
    reducible = 0;
302
0
  } else {
303
    /* mean error criterion */
304
0
    for (e = 0; (e < nEnvelopes / 2) && (reducible != 0); e++) {
305
0
      iidMeanError = iccMeanError = FL2FXCONST_DBL(0.f);
306
0
      for (b = 0; b < psBands; b++) {
307
0
        dIid = (iid[2 * e][b] >> 1) -
308
0
               (iid[2 * e + 1][b] >> 1); /* scale 1 bit; squared -> 2 bit */
309
0
        dIcc = (icc[2 * e][b] >> 1) - (icc[2 * e + 1][b] >> 1);
310
0
        iidMeanError += fPow2Div2(dIid) >> (5 - 1); /* + (bands=20) scale = 5 */
311
0
        iccMeanError += fPow2Div2(dIcc) >> (5 - 1);
312
0
      } /* --> scaling = 7 bit = THRESH_SCALE !! */
313
314
      /* instead sqrt values are squared!
315
         instead of division, multiply threshold with psBands
316
         scaling necessary!! */
317
318
      /* quit as soon as threshold is reached */
319
0
      if ((iidMeanError > (iidErrThreshold)) ||
320
0
          (iccMeanError > (iccErrThreshold))) {
321
0
        reducible = 0;
322
0
      }
323
0
    }
324
0
  } /* nEnvelopes != 1 */
325
326
0
  return reducible;
327
0
}
328
329
static void processIidData(PS_DATA *psData,
330
                           FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS],
331
                           const INT psBands, const INT nEnvelopes,
332
0
                           const FIXP_DBL quantErrorThreshold) {
333
0
  INT iidIdxFine[PS_MAX_ENVELOPES][PS_MAX_BANDS];
334
0
  INT iidIdxCoarse[PS_MAX_ENVELOPES][PS_MAX_BANDS];
335
336
0
  FIXP_DBL errIID = FL2FXCONST_DBL(0.f);
337
0
  FIXP_DBL errIIDFine = FL2FXCONST_DBL(0.f);
338
0
  INT bitsIidFreq = 0;
339
0
  INT bitsIidTime = 0;
340
0
  INT bitsFineTot = 0;
341
0
  INT bitsCoarseTot = 0;
342
0
  INT error = 0;
343
0
  INT env, band;
344
0
  INT diffMode[PS_MAX_ENVELOPES], diffModeFine[PS_MAX_ENVELOPES];
345
0
  INT loudnDiff = 0;
346
0
  INT iidTransmit = 0;
347
348
  /* Quantize IID coefficients */
349
0
  for (env = 0; env < nEnvelopes; env++) {
350
0
    errIID +=
351
0
        quantizeCoef(iid[env], psBands, iidQuant_fx, 7, 15, iidIdxCoarse[env]);
352
0
    errIIDFine += quantizeCoef(iid[env], psBands, iidQuantFine_fx, 15, 31,
353
0
                               iidIdxFine[env]);
354
0
  }
355
356
  /* normalize error to number of envelopes, ps bands
357
     errIID /= psBands*nEnvelopes;
358
     errIIDFine /= psBands*nEnvelopes; */
359
360
  /* Check if IID coefficients should be used in this frame */
361
0
  psData->iidEnable = 0;
362
0
  for (env = 0; env < nEnvelopes; env++) {
363
0
    for (band = 0; band < psBands; band++) {
364
0
      loudnDiff += fixp_abs(iidIdxCoarse[env][band]);
365
0
      iidTransmit++;
366
0
    }
367
0
  }
368
369
0
  if (loudnDiff >
370
0
      fMultI(FL2FXCONST_DBL(0.7f), iidTransmit)) { /* 0.7f empiric value */
371
0
    psData->iidEnable = 1;
372
0
  }
373
374
  /* if iid not active -> RESET data */
375
0
  if (psData->iidEnable == 0) {
376
0
    psData->iidTimeCnt = MAX_TIME_DIFF_FRAMES;
377
0
    for (env = 0; env < nEnvelopes; env++) {
378
0
      psData->iidDiffMode[env] = PS_DELTA_FREQ;
379
0
      FDKmemclear(psData->iidIdx[env], sizeof(INT) * psBands);
380
0
    }
381
0
    return;
382
0
  }
383
384
  /* count COARSE quantization bits for first envelope*/
385
0
  bitsIidFreq = FDKsbrEnc_EncodeIid(NULL, iidIdxCoarse[0], NULL, psBands,
386
0
                                    PS_IID_RES_COARSE, PS_DELTA_FREQ, &error);
387
388
0
  if ((psData->iidTimeCnt >= MAX_TIME_DIFF_FRAMES) ||
389
0
      (psData->iidQuantModeLast == PS_IID_RES_FINE)) {
390
0
    bitsIidTime = DO_NOT_USE_THIS_MODE;
391
0
  } else {
392
0
    bitsIidTime =
393
0
        FDKsbrEnc_EncodeIid(NULL, iidIdxCoarse[0], psData->iidIdxLast, psBands,
394
0
                            PS_IID_RES_COARSE, PS_DELTA_TIME, &error);
395
0
  }
396
397
  /* decision DELTA_FREQ vs DELTA_TIME */
398
0
  if (bitsIidTime > bitsIidFreq) {
399
0
    diffMode[0] = PS_DELTA_FREQ;
400
0
    bitsCoarseTot = bitsIidFreq;
401
0
  } else {
402
0
    diffMode[0] = PS_DELTA_TIME;
403
0
    bitsCoarseTot = bitsIidTime;
404
0
  }
405
406
  /* count COARSE quantization bits for following envelopes*/
407
0
  for (env = 1; env < nEnvelopes; env++) {
408
0
    bitsIidFreq = FDKsbrEnc_EncodeIid(NULL, iidIdxCoarse[env], NULL, psBands,
409
0
                                      PS_IID_RES_COARSE, PS_DELTA_FREQ, &error);
410
0
    bitsIidTime =
411
0
        FDKsbrEnc_EncodeIid(NULL, iidIdxCoarse[env], iidIdxCoarse[env - 1],
412
0
                            psBands, PS_IID_RES_COARSE, PS_DELTA_TIME, &error);
413
414
    /* decision DELTA_FREQ vs DELTA_TIME */
415
0
    if (bitsIidTime > bitsIidFreq) {
416
0
      diffMode[env] = PS_DELTA_FREQ;
417
0
      bitsCoarseTot += bitsIidFreq;
418
0
    } else {
419
0
      diffMode[env] = PS_DELTA_TIME;
420
0
      bitsCoarseTot += bitsIidTime;
421
0
    }
422
0
  }
423
424
  /* count FINE quantization bits for first envelope*/
425
0
  bitsIidFreq = FDKsbrEnc_EncodeIid(NULL, iidIdxFine[0], NULL, psBands,
426
0
                                    PS_IID_RES_FINE, PS_DELTA_FREQ, &error);
427
428
0
  if ((psData->iidTimeCnt >= MAX_TIME_DIFF_FRAMES) ||
429
0
      (psData->iidQuantModeLast == PS_IID_RES_COARSE)) {
430
0
    bitsIidTime = DO_NOT_USE_THIS_MODE;
431
0
  } else {
432
0
    bitsIidTime =
433
0
        FDKsbrEnc_EncodeIid(NULL, iidIdxFine[0], psData->iidIdxLast, psBands,
434
0
                            PS_IID_RES_FINE, PS_DELTA_TIME, &error);
435
0
  }
436
437
  /* decision DELTA_FREQ vs DELTA_TIME */
438
0
  if (bitsIidTime > bitsIidFreq) {
439
0
    diffModeFine[0] = PS_DELTA_FREQ;
440
0
    bitsFineTot = bitsIidFreq;
441
0
  } else {
442
0
    diffModeFine[0] = PS_DELTA_TIME;
443
0
    bitsFineTot = bitsIidTime;
444
0
  }
445
446
  /* count FINE quantization bits for following envelopes*/
447
0
  for (env = 1; env < nEnvelopes; env++) {
448
0
    bitsIidFreq = FDKsbrEnc_EncodeIid(NULL, iidIdxFine[env], NULL, psBands,
449
0
                                      PS_IID_RES_FINE, PS_DELTA_FREQ, &error);
450
0
    bitsIidTime =
451
0
        FDKsbrEnc_EncodeIid(NULL, iidIdxFine[env], iidIdxFine[env - 1], psBands,
452
0
                            PS_IID_RES_FINE, PS_DELTA_TIME, &error);
453
454
    /* decision DELTA_FREQ vs DELTA_TIME */
455
0
    if (bitsIidTime > bitsIidFreq) {
456
0
      diffModeFine[env] = PS_DELTA_FREQ;
457
0
      bitsFineTot += bitsIidFreq;
458
0
    } else {
459
0
      diffModeFine[env] = PS_DELTA_TIME;
460
0
      bitsFineTot += bitsIidTime;
461
0
    }
462
0
  }
463
464
0
  if (bitsFineTot == bitsCoarseTot) {
465
    /* if same number of bits is needed, use the quantization with lower error
466
     */
467
0
    if (errIIDFine < errIID) {
468
0
      bitsCoarseTot = DO_NOT_USE_THIS_MODE;
469
0
    } else {
470
0
      bitsFineTot = DO_NOT_USE_THIS_MODE;
471
0
    }
472
0
  } else {
473
    /* const FIXP_DBL minThreshold =
474
     * FL2FXCONST_DBL(0.2f/(IID_SCALE_FT*PS_QUANT_SCALE_FT)*(psBands*nEnvelopes));
475
     */
476
0
    const FIXP_DBL minThreshold =
477
0
        (FIXP_DBL)((LONG)0x00019999 * (psBands * nEnvelopes));
478
479
    /* decision RES_FINE vs RES_COARSE                 */
480
    /* test if errIIDFine*quantErrorThreshold < errIID */
481
    /* shiftVal 2 comes from scaling of quantErrorThreshold */
482
0
    if (fixMax(((errIIDFine >> 1) + (minThreshold >> 1)) >> 1,
483
0
               fMult(quantErrorThreshold, errIIDFine)) < (errIID >> 2)) {
484
0
      bitsCoarseTot = DO_NOT_USE_THIS_MODE;
485
0
    } else if (fixMax(((errIID >> 1) + (minThreshold >> 1)) >> 1,
486
0
                      fMult(quantErrorThreshold, errIID)) < (errIIDFine >> 2)) {
487
0
      bitsFineTot = DO_NOT_USE_THIS_MODE;
488
0
    }
489
0
  }
490
491
  /* decision RES_FINE vs RES_COARSE */
492
0
  if (bitsFineTot < bitsCoarseTot) {
493
0
    psData->iidQuantMode = PS_IID_RES_FINE;
494
0
    for (env = 0; env < nEnvelopes; env++) {
495
0
      psData->iidDiffMode[env] = diffModeFine[env];
496
0
      FDKmemcpy(psData->iidIdx[env], iidIdxFine[env], psBands * sizeof(INT));
497
0
    }
498
0
  } else {
499
0
    psData->iidQuantMode = PS_IID_RES_COARSE;
500
0
    for (env = 0; env < nEnvelopes; env++) {
501
0
      psData->iidDiffMode[env] = diffMode[env];
502
0
      FDKmemcpy(psData->iidIdx[env], iidIdxCoarse[env], psBands * sizeof(INT));
503
0
    }
504
0
  }
505
506
  /* Count DELTA_TIME encoding streaks */
507
0
  for (env = 0; env < nEnvelopes; env++) {
508
0
    if (psData->iidDiffMode[env] == PS_DELTA_TIME)
509
0
      psData->iidTimeCnt++;
510
0
    else
511
0
      psData->iidTimeCnt = 0;
512
0
  }
513
0
}
514
515
static INT similarIid(PS_DATA *psData, const INT psBands,
516
0
                      const INT nEnvelopes) {
517
0
  const INT diffThr = (psData->iidQuantMode == PS_IID_RES_COARSE) ? 2 : 3;
518
0
  const INT sumDiffThr = diffThr * psBands / 4;
519
0
  INT similar = 0;
520
0
  INT diff = 0;
521
0
  INT sumDiff = 0;
522
0
  INT env = 0;
523
0
  INT b = 0;
524
0
  if ((nEnvelopes == psData->nEnvelopesLast) && (nEnvelopes == 1)) {
525
0
    similar = 1;
526
0
    for (env = 0; env < nEnvelopes; env++) {
527
0
      sumDiff = 0;
528
0
      b = 0;
529
0
      do {
530
0
        diff = fixp_abs(psData->iidIdx[env][b] - psData->iidIdxLast[b]);
531
0
        sumDiff += diff;
532
0
        if ((diff > diffThr) /* more than x quantization steps in any band */
533
0
            || (sumDiff > sumDiffThr)) { /* more than x quantisations steps
534
                                            overall difference */
535
0
          similar = 0;
536
0
        }
537
0
        b++;
538
0
      } while ((b < psBands) && (similar > 0));
539
0
    }
540
0
  } /* nEnvelopes==1  */
541
542
0
  return similar;
543
0
}
544
545
static INT similarIcc(PS_DATA *psData, const INT psBands,
546
0
                      const INT nEnvelopes) {
547
0
  const INT diffThr = 2;
548
0
  const INT sumDiffThr = diffThr * psBands / 4;
549
0
  INT similar = 0;
550
0
  INT diff = 0;
551
0
  INT sumDiff = 0;
552
0
  INT env = 0;
553
0
  INT b = 0;
554
0
  if ((nEnvelopes == psData->nEnvelopesLast) && (nEnvelopes == 1)) {
555
0
    similar = 1;
556
0
    for (env = 0; env < nEnvelopes; env++) {
557
0
      sumDiff = 0;
558
0
      b = 0;
559
0
      do {
560
0
        diff = fixp_abs(psData->iccIdx[env][b] - psData->iccIdxLast[b]);
561
0
        sumDiff += diff;
562
0
        if ((diff > diffThr) /* more than x quantisation step in any band */
563
0
            || (sumDiff > sumDiffThr)) { /* more than x quantisations steps
564
                                            overall difference */
565
0
          similar = 0;
566
0
        }
567
0
        b++;
568
0
      } while ((b < psBands) && (similar > 0));
569
0
    }
570
0
  } /* nEnvelopes==1  */
571
572
0
  return similar;
573
0
}
574
575
static void processIccData(
576
    PS_DATA *psData,
577
    FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS], /* const input values:
578
                                                     unable to declare as
579
                                                     const, since it does
580
                                                     not poINT to const
581
                                                     memory */
582
0
    const INT psBands, const INT nEnvelopes) {
583
0
  FIXP_DBL errICC = FL2FXCONST_DBL(0.f);
584
0
  INT env, band;
585
0
  INT bitsIccFreq, bitsIccTime;
586
0
  INT error = 0;
587
0
  INT inCoherence = 0, iccTransmit = 0;
588
0
  INT *iccIdxLast;
589
590
0
  iccIdxLast = psData->iccIdxLast;
591
592
  /* Quantize ICC coefficients */
593
0
  for (env = 0; env < nEnvelopes; env++) {
594
0
    errICC +=
595
0
        quantizeCoef(icc[env], psBands, iccQuant, 0, 8, psData->iccIdx[env]);
596
0
  }
597
598
  /* Check if ICC coefficients should be used */
599
0
  psData->iccEnable = 0;
600
0
  for (env = 0; env < nEnvelopes; env++) {
601
0
    for (band = 0; band < psBands; band++) {
602
0
      inCoherence += psData->iccIdx[env][band];
603
0
      iccTransmit++;
604
0
    }
605
0
  }
606
0
  if (inCoherence >
607
0
      fMultI(FL2FXCONST_DBL(0.5f), iccTransmit)) { /* 0.5f empiric value */
608
0
    psData->iccEnable = 1;
609
0
  }
610
611
0
  if (psData->iccEnable == 0) {
612
0
    psData->iccTimeCnt = MAX_TIME_DIFF_FRAMES;
613
0
    for (env = 0; env < nEnvelopes; env++) {
614
0
      psData->iccDiffMode[env] = PS_DELTA_FREQ;
615
0
      FDKmemclear(psData->iccIdx[env], sizeof(INT) * psBands);
616
0
    }
617
0
    return;
618
0
  }
619
620
0
  for (env = 0; env < nEnvelopes; env++) {
621
0
    bitsIccFreq = FDKsbrEnc_EncodeIcc(NULL, psData->iccIdx[env], NULL, psBands,
622
0
                                      PS_DELTA_FREQ, &error);
623
624
0
    if (psData->iccTimeCnt < MAX_TIME_DIFF_FRAMES) {
625
0
      bitsIccTime = FDKsbrEnc_EncodeIcc(NULL, psData->iccIdx[env], iccIdxLast,
626
0
                                        psBands, PS_DELTA_TIME, &error);
627
0
    } else {
628
0
      bitsIccTime = DO_NOT_USE_THIS_MODE;
629
0
    }
630
631
0
    if (bitsIccFreq > bitsIccTime) {
632
0
      psData->iccDiffMode[env] = PS_DELTA_TIME;
633
0
      psData->iccTimeCnt++;
634
0
    } else {
635
0
      psData->iccDiffMode[env] = PS_DELTA_FREQ;
636
0
      psData->iccTimeCnt = 0;
637
0
    }
638
0
    iccIdxLast = psData->iccIdx[env];
639
0
  }
640
0
}
641
642
static void calculateIID(FIXP_DBL ldPwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS],
643
                         FIXP_DBL ldPwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS],
644
                         FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS],
645
0
                         INT nEnvelopes, INT psBands) {
646
0
  INT i = 0;
647
0
  INT env = 0;
648
0
  for (env = 0; env < nEnvelopes; env++) {
649
0
    for (i = 0; i < psBands; i++) {
650
      /* iid[env][i] = 10.0f*(float)log10(pwrL[env][i]/pwrR[env][i]);
651
       */
652
0
      FIXP_DBL IID = fMultDiv2(FL2FXCONST_DBL(LOG10_2_10 / IID_SCALE_FT),
653
0
                               (ldPwrL[env][i] - ldPwrR[env][i]));
654
655
0
      IID = fixMin(IID, (FIXP_DBL)(MAXVAL_DBL >> (LD_DATA_SHIFT + 1)));
656
0
      IID = fixMax(IID, (FIXP_DBL)(MINVAL_DBL >> (LD_DATA_SHIFT + 1)));
657
0
      iid[env][i] = IID << (LD_DATA_SHIFT + 1);
658
0
    }
659
0
  }
660
0
}
661
662
static void calculateICC(FIXP_DBL pwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS],
663
                         FIXP_DBL pwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS],
664
                         FIXP_DBL pwrCr[PS_MAX_ENVELOPES][PS_MAX_BANDS],
665
                         FIXP_DBL pwrCi[PS_MAX_ENVELOPES][PS_MAX_BANDS],
666
                         FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS],
667
0
                         INT nEnvelopes, INT psBands) {
668
0
  INT i = 0;
669
0
  INT env = 0;
670
0
  INT border = psBands;
671
672
0
  switch (psBands) {
673
0
    case PS_BANDS_COARSE:
674
0
      border = 5;
675
0
      break;
676
0
    case PS_BANDS_MID:
677
0
      border = 11;
678
0
      break;
679
0
    default:
680
0
      break;
681
0
  }
682
683
0
  for (env = 0; env < nEnvelopes; env++) {
684
0
    for (i = 0; i < border; i++) {
685
      /* icc[env][i] = min( pwrCr[env][i] / (float) sqrt(pwrL[env][i] *
686
       * pwrR[env][i]) , 1.f);
687
       */
688
0
      int scale;
689
0
      FIXP_DBL invNrg = invSqrtNorm2(
690
0
          fMax(fMult(pwrL[env][i], pwrR[env][i]), (FIXP_DBL)1), &scale);
691
0
      icc[env][i] =
692
0
          SATURATE_LEFT_SHIFT(fMult(pwrCr[env][i], invNrg), scale, DFRACT_BITS);
693
0
    }
694
695
0
    for (; i < psBands; i++) {
696
0
      int denom_e;
697
0
      FIXP_DBL denom_m = fMultNorm(pwrL[env][i], pwrR[env][i], &denom_e);
698
699
0
      if (denom_m == (FIXP_DBL)0) {
700
0
        icc[env][i] = (FIXP_DBL)MAXVAL_DBL;
701
0
      } else {
702
0
        int num_e, result_e;
703
0
        FIXP_DBL num_m, result_m;
704
705
0
        num_e = CountLeadingBits(
706
0
            fixMax(fixp_abs(pwrCr[env][i]), fixp_abs(pwrCi[env][i])));
707
0
        num_m = fPow2Div2((pwrCr[env][i] << num_e)) +
708
0
                fPow2Div2((pwrCi[env][i] << num_e));
709
710
0
        result_m = fDivNorm(num_m, denom_m, &result_e);
711
0
        result_e += (-2 * num_e + 1) - denom_e;
712
0
        icc[env][i] = scaleValueSaturate(sqrtFixp(result_m >> (result_e & 1)),
713
0
                                         (result_e + (result_e & 1)) >> 1);
714
0
      }
715
0
    }
716
0
  }
717
0
}
718
719
0
void FDKsbrEnc_initPsBandNrgScale(HANDLE_PS_ENCODE hPsEncode) {
720
0
  INT group, bin;
721
0
  INT nIidGroups = hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups;
722
723
0
  FDKmemclear(hPsEncode->psBandNrgScale, PS_MAX_BANDS * sizeof(SCHAR));
724
725
0
  for (group = 0; group < nIidGroups; group++) {
726
    /* Translate group to bin */
727
0
    bin = hPsEncode->subband2parameterIndex[group];
728
729
    /* Translate from 20 bins to 10 bins */
730
0
    if (hPsEncode->psEncMode == PS_BANDS_COARSE) {
731
0
      bin = bin >> 1;
732
0
    }
733
734
0
    hPsEncode->psBandNrgScale[bin] =
735
0
        (hPsEncode->psBandNrgScale[bin] == 0)
736
0
            ? (hPsEncode->iidGroupWidthLd[group] + 5)
737
0
            : (fixMax(hPsEncode->iidGroupWidthLd[group],
738
0
                      hPsEncode->psBandNrgScale[bin]) +
739
0
               1);
740
0
  }
741
0
}
742
743
0
FDK_PSENC_ERROR FDKsbrEnc_CreatePSEncode(HANDLE_PS_ENCODE *phPsEncode) {
744
0
  FDK_PSENC_ERROR error = PSENC_OK;
745
746
0
  if (phPsEncode == NULL) {
747
0
    error = PSENC_INVALID_HANDLE;
748
0
  } else {
749
0
    HANDLE_PS_ENCODE hPsEncode = NULL;
750
0
    if (NULL == (hPsEncode = GetRam_PsEncode())) {
751
0
      error = PSENC_MEMORY_ERROR;
752
0
      goto bail;
753
0
    }
754
0
    FDKmemclear(hPsEncode, sizeof(PS_ENCODE));
755
0
    *phPsEncode = hPsEncode; /* return allocated handle */
756
0
  }
757
0
bail:
758
0
  return error;
759
0
}
760
761
FDK_PSENC_ERROR FDKsbrEnc_InitPSEncode(HANDLE_PS_ENCODE hPsEncode,
762
                                       const PS_BANDS psEncMode,
763
0
                                       const FIXP_DBL iidQuantErrorThreshold) {
764
0
  FDK_PSENC_ERROR error = PSENC_OK;
765
766
0
  if (NULL == hPsEncode) {
767
0
    error = PSENC_INVALID_HANDLE;
768
0
  } else {
769
0
    if (PSENC_OK != (InitPSData(&hPsEncode->psData))) {
770
0
      goto bail;
771
0
    }
772
773
0
    switch (psEncMode) {
774
0
      case PS_BANDS_COARSE:
775
0
      case PS_BANDS_MID:
776
0
        hPsEncode->nQmfIidGroups = QMF_GROUPS_LO_RES;
777
0
        hPsEncode->nSubQmfIidGroups = SUBQMF_GROUPS_LO_RES;
778
0
        FDKmemcpy(hPsEncode->iidGroupBorders, iidGroupBordersLoRes,
779
0
                  (hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups + 1) *
780
0
                      sizeof(INT));
781
0
        FDKmemcpy(hPsEncode->subband2parameterIndex, subband2parameter20,
782
0
                  (hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups) *
783
0
                      sizeof(INT));
784
0
        FDKmemcpy(hPsEncode->iidGroupWidthLd, iidGroupWidthLdLoRes,
785
0
                  (hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups) *
786
0
                      sizeof(UCHAR));
787
0
        break;
788
0
      default:
789
0
        error = PSENC_INIT_ERROR;
790
0
        goto bail;
791
0
    }
792
793
0
    hPsEncode->psEncMode = psEncMode;
794
0
    hPsEncode->iidQuantErrorThreshold = iidQuantErrorThreshold;
795
0
    FDKsbrEnc_initPsBandNrgScale(hPsEncode);
796
0
  }
797
0
bail:
798
0
  return error;
799
0
}
800
801
0
FDK_PSENC_ERROR FDKsbrEnc_DestroyPSEncode(HANDLE_PS_ENCODE *phPsEncode) {
802
0
  FDK_PSENC_ERROR error = PSENC_OK;
803
804
0
  if (NULL != phPsEncode) {
805
0
    FreeRam_PsEncode(phPsEncode);
806
0
  }
807
808
0
  return error;
809
0
}
810
811
typedef struct {
812
  FIXP_DBL pwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS];
813
  FIXP_DBL pwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS];
814
  FIXP_DBL ldPwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS];
815
  FIXP_DBL ldPwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS];
816
  FIXP_DBL pwrCr[PS_MAX_ENVELOPES][PS_MAX_BANDS];
817
  FIXP_DBL pwrCi[PS_MAX_ENVELOPES][PS_MAX_BANDS];
818
819
} PS_PWR_DATA;
820
821
FDK_PSENC_ERROR FDKsbrEnc_PSEncode(
822
    HANDLE_PS_ENCODE hPsEncode, HANDLE_PS_OUT hPsOut, UCHAR *dynBandScale,
823
    UINT maxEnvelopes,
824
    FIXP_DBL *hybridData[HYBRID_FRAMESIZE][MAX_PS_CHANNELS][2],
825
0
    const INT frameSize, const INT sendHeader) {
826
0
  FDK_PSENC_ERROR error = PSENC_OK;
827
828
0
  HANDLE_PS_DATA hPsData = &hPsEncode->psData;
829
0
  FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS];
830
0
  FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS];
831
0
  int envBorder[PS_MAX_ENVELOPES + 1];
832
833
0
  int group, bin, col, subband, band;
834
0
  int i = 0;
835
836
0
  int env = 0;
837
0
  int psBands = (int)hPsEncode->psEncMode;
838
0
  int nIidGroups = hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups;
839
0
  int nEnvelopes = fixMin(maxEnvelopes, (UINT)PS_MAX_ENVELOPES);
840
841
0
  C_ALLOC_SCRATCH_START(pwrData, PS_PWR_DATA, 1)
842
843
0
  for (env = 0; env < nEnvelopes + 1; env++) {
844
0
    envBorder[env] = fMultI(GetInvInt(nEnvelopes), frameSize * env);
845
0
  }
846
847
0
  for (env = 0; env < nEnvelopes; env++) {
848
    /* clear energy array */
849
0
    for (band = 0; band < psBands; band++) {
850
0
      pwrData->pwrL[env][band] = pwrData->pwrR[env][band] =
851
0
          pwrData->pwrCr[env][band] = pwrData->pwrCi[env][band] = FIXP_DBL(1);
852
0
    }
853
854
    /**** calculate energies and correlation ****/
855
856
    /* start with hybrid data */
857
0
    for (group = 0; group < nIidGroups; group++) {
858
      /* Translate group to bin */
859
0
      bin = hPsEncode->subband2parameterIndex[group];
860
861
      /* Translate from 20 bins to 10 bins */
862
0
      if (hPsEncode->psEncMode == PS_BANDS_COARSE) {
863
0
        bin >>= 1;
864
0
      }
865
866
      /* determine group border */
867
0
      int bScale = hPsEncode->psBandNrgScale[bin];
868
869
0
      FIXP_DBL pwrL_env_bin = pwrData->pwrL[env][bin];
870
0
      FIXP_DBL pwrR_env_bin = pwrData->pwrR[env][bin];
871
0
      FIXP_DBL pwrCr_env_bin = pwrData->pwrCr[env][bin];
872
0
      FIXP_DBL pwrCi_env_bin = pwrData->pwrCi[env][bin];
873
874
0
      int scale = (int)dynBandScale[bin];
875
0
      for (col = envBorder[env]; col < envBorder[env + 1]; col++) {
876
0
        for (subband = hPsEncode->iidGroupBorders[group];
877
0
             subband < hPsEncode->iidGroupBorders[group + 1]; subband++) {
878
0
          FIXP_DBL l_real = (hybridData[col][0][0][subband]) << scale;
879
0
          FIXP_DBL l_imag = (hybridData[col][0][1][subband]) << scale;
880
0
          FIXP_DBL r_real = (hybridData[col][1][0][subband]) << scale;
881
0
          FIXP_DBL r_imag = (hybridData[col][1][1][subband]) << scale;
882
883
0
          pwrL_env_bin += (fPow2Div2(l_real) + fPow2Div2(l_imag)) >> bScale;
884
0
          pwrR_env_bin += (fPow2Div2(r_real) + fPow2Div2(r_imag)) >> bScale;
885
0
          pwrCr_env_bin +=
886
0
              (fMultDiv2(l_real, r_real) + fMultDiv2(l_imag, r_imag)) >> bScale;
887
0
          pwrCi_env_bin +=
888
0
              (fMultDiv2(r_real, l_imag) - fMultDiv2(l_real, r_imag)) >> bScale;
889
0
        }
890
0
      }
891
      /* assure, nrg's of left and right channel are not negative; necessary on
892
       * 16 bit multiply units */
893
0
      pwrData->pwrL[env][bin] = fixMax((FIXP_DBL)0, pwrL_env_bin);
894
0
      pwrData->pwrR[env][bin] = fixMax((FIXP_DBL)0, pwrR_env_bin);
895
896
0
      pwrData->pwrCr[env][bin] = pwrCr_env_bin;
897
0
      pwrData->pwrCi[env][bin] = pwrCi_env_bin;
898
899
0
    } /* nIidGroups */
900
901
    /* calc logarithmic energy */
902
0
    LdDataVector(pwrData->pwrL[env], pwrData->ldPwrL[env], psBands);
903
0
    LdDataVector(pwrData->pwrR[env], pwrData->ldPwrR[env], psBands);
904
905
0
  } /* nEnvelopes */
906
907
  /* calculate iid and icc */
908
0
  calculateIID(pwrData->ldPwrL, pwrData->ldPwrR, iid, nEnvelopes, psBands);
909
0
  calculateICC(pwrData->pwrL, pwrData->pwrR, pwrData->pwrCr, pwrData->pwrCi,
910
0
               icc, nEnvelopes, psBands);
911
912
  /*** Envelope Reduction ***/
913
0
  while (envelopeReducible(iid, icc, psBands, nEnvelopes)) {
914
0
    int e = 0;
915
    /* sum energies of two neighboring envelopes */
916
0
    nEnvelopes >>= 1;
917
0
    for (e = 0; e < nEnvelopes; e++) {
918
0
      FDKsbrEnc_addFIXP_DBL(pwrData->pwrL[2 * e], pwrData->pwrL[2 * e + 1],
919
0
                            pwrData->pwrL[e], psBands);
920
0
      FDKsbrEnc_addFIXP_DBL(pwrData->pwrR[2 * e], pwrData->pwrR[2 * e + 1],
921
0
                            pwrData->pwrR[e], psBands);
922
0
      FDKsbrEnc_addFIXP_DBL(pwrData->pwrCr[2 * e], pwrData->pwrCr[2 * e + 1],
923
0
                            pwrData->pwrCr[e], psBands);
924
0
      FDKsbrEnc_addFIXP_DBL(pwrData->pwrCi[2 * e], pwrData->pwrCi[2 * e + 1],
925
0
                            pwrData->pwrCi[e], psBands);
926
927
      /* calc logarithmic energy */
928
0
      LdDataVector(pwrData->pwrL[e], pwrData->ldPwrL[e], psBands);
929
0
      LdDataVector(pwrData->pwrR[e], pwrData->ldPwrR[e], psBands);
930
931
      /* reduce number of envelopes and adjust borders */
932
0
      envBorder[e] = envBorder[2 * e];
933
0
    }
934
0
    envBorder[nEnvelopes] = envBorder[2 * nEnvelopes];
935
936
    /* re-calculate iid and icc */
937
0
    calculateIID(pwrData->ldPwrL, pwrData->ldPwrR, iid, nEnvelopes, psBands);
938
0
    calculateICC(pwrData->pwrL, pwrData->pwrR, pwrData->pwrCr, pwrData->pwrCi,
939
0
                 icc, nEnvelopes, psBands);
940
0
  }
941
942
  /*  */
943
0
  if (sendHeader) {
944
0
    hPsData->headerCnt = MAX_PS_NOHEADER_CNT;
945
0
    hPsData->iidTimeCnt = MAX_TIME_DIFF_FRAMES;
946
0
    hPsData->iccTimeCnt = MAX_TIME_DIFF_FRAMES;
947
0
    hPsData->noEnvCnt = MAX_NOENV_CNT;
948
0
  }
949
950
  /*** Parameter processing, quantisation etc ***/
951
0
  processIidData(hPsData, iid, psBands, nEnvelopes,
952
0
                 hPsEncode->iidQuantErrorThreshold);
953
0
  processIccData(hPsData, icc, psBands, nEnvelopes);
954
955
  /*** Initialize output struct ***/
956
957
  /* PS Header on/off ? */
958
0
  if ((hPsData->headerCnt < MAX_PS_NOHEADER_CNT) &&
959
0
      ((hPsData->iidQuantMode == hPsData->iidQuantModeLast) &&
960
0
       (hPsData->iccQuantMode == hPsData->iccQuantModeLast)) &&
961
0
      ((hPsData->iidEnable == hPsData->iidEnableLast) &&
962
0
       (hPsData->iccEnable == hPsData->iccEnableLast))) {
963
0
    hPsOut->enablePSHeader = 0;
964
0
  } else {
965
0
    hPsOut->enablePSHeader = 1;
966
0
    hPsData->headerCnt = 0;
967
0
  }
968
969
  /* nEnvelopes = 0 ? */
970
0
  if ((hPsData->noEnvCnt < MAX_NOENV_CNT) &&
971
0
      (similarIid(hPsData, psBands, nEnvelopes)) &&
972
0
      (similarIcc(hPsData, psBands, nEnvelopes))) {
973
0
    hPsOut->nEnvelopes = nEnvelopes = 0;
974
0
    hPsData->noEnvCnt++;
975
0
  } else {
976
0
    hPsData->noEnvCnt = 0;
977
0
  }
978
979
0
  if (nEnvelopes > 0) {
980
0
    hPsOut->enableIID = hPsData->iidEnable;
981
0
    hPsOut->iidMode = getIIDMode(psBands, hPsData->iidQuantMode);
982
983
0
    hPsOut->enableICC = hPsData->iccEnable;
984
0
    hPsOut->iccMode = getICCMode(psBands, hPsData->iccQuantMode);
985
986
0
    hPsOut->enableIpdOpd = 0;
987
0
    hPsOut->frameClass = 0;
988
0
    hPsOut->nEnvelopes = nEnvelopes;
989
990
0
    for (env = 0; env < nEnvelopes; env++) {
991
0
      hPsOut->frameBorder[env] = envBorder[env + 1];
992
0
      hPsOut->deltaIID[env] = (PS_DELTA)hPsData->iidDiffMode[env];
993
0
      hPsOut->deltaICC[env] = (PS_DELTA)hPsData->iccDiffMode[env];
994
0
      for (band = 0; band < psBands; band++) {
995
0
        hPsOut->iid[env][band] = hPsData->iidIdx[env][band];
996
0
        hPsOut->icc[env][band] = hPsData->iccIdx[env][band];
997
0
      }
998
0
    }
999
1000
    /* IPD OPD not supported right now */
1001
0
    FDKmemclear(hPsOut->ipd,
1002
0
                PS_MAX_ENVELOPES * PS_MAX_BANDS * sizeof(PS_DELTA));
1003
0
    for (env = 0; env < PS_MAX_ENVELOPES; env++) {
1004
0
      hPsOut->deltaIPD[env] = PS_DELTA_FREQ;
1005
0
      hPsOut->deltaOPD[env] = PS_DELTA_FREQ;
1006
0
    }
1007
1008
0
    FDKmemclear(hPsOut->ipdLast, PS_MAX_BANDS * sizeof(INT));
1009
0
    FDKmemclear(hPsOut->opdLast, PS_MAX_BANDS * sizeof(INT));
1010
1011
0
    for (band = 0; band < PS_MAX_BANDS; band++) {
1012
0
      hPsOut->iidLast[band] = hPsData->iidIdxLast[band];
1013
0
      hPsOut->iccLast[band] = hPsData->iccIdxLast[band];
1014
0
    }
1015
1016
    /* save iids and iccs for differential time coding in the next frame */
1017
0
    hPsData->nEnvelopesLast = nEnvelopes;
1018
0
    hPsData->iidEnableLast = hPsData->iidEnable;
1019
0
    hPsData->iccEnableLast = hPsData->iccEnable;
1020
0
    hPsData->iidQuantModeLast = hPsData->iidQuantMode;
1021
0
    hPsData->iccQuantModeLast = hPsData->iccQuantMode;
1022
0
    for (i = 0; i < psBands; i++) {
1023
0
      hPsData->iidIdxLast[i] = hPsData->iidIdx[nEnvelopes - 1][i];
1024
0
      hPsData->iccIdxLast[i] = hPsData->iccIdx[nEnvelopes - 1][i];
1025
0
    }
1026
0
  } /* Envelope > 0 */
1027
1028
0
  C_ALLOC_SCRATCH_END(pwrData, PS_PWR_DATA, 1)
1029
1030
0
  return error;
1031
0
}