1
2/* -----------------------------------------------------------------------------------------------------------
3Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5� Copyright  1995 - 2015 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6  All rights reserved.
7
8 1.    INTRODUCTION
9The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12
13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16of the MPEG specifications.
17
18Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20individually for the purpose of encoding or decoding bit streams in products that are compliant with
21the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23software may already be covered under those patent licenses when it is used for those licensed purposes only.
24
25Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27applications information and documentation.
28
292.    COPYRIGHT LICENSE
30
31Redistribution and use in source and binary forms, with or without modification, are permitted without
32payment of copyright license fees provided that you satisfy the following conditions:
33
34You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35your modifications thereto in source code form.
36
37You must retain the complete text of this software license in the documentation and/or other materials
38provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40modifications thereto to recipients of copies in binary form.
41
42The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43prior written permission.
44
45You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46software or your modifications thereto.
47
48Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49and the date of any change. For modified versions of the FDK AAC Codec, the term
50"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
51"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
52
533.    NO PATENT LICENSE
54
55NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57respect to this software.
58
59You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60by appropriate patent licenses.
61
624.    DISCLAIMER
63
64This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
65"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
66of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69or business interruption, however caused and on any theory of liability, whether in contract, strict
70liability, or tort (including negligence), arising in any way out of the use of this software, even if
71advised of the possibility of such damage.
72
735.    CONTACT INFORMATION
74
75Fraunhofer Institute for Integrated Circuits IIS
76Attention: Audio and Multimedia Departments - FDK AAC LL
77Am Wolfsmantel 33
7891058 Erlangen, Germany
79
80www.iis.fraunhofer.de/amm
81amm-info@iis.fraunhofer.de
82----------------------------------------------------------------------------------------------------------- */
83
84/*****************************  MPEG Audio Encoder  ***************************
85
86   Initial Authors:      M. Neuendorf, N. Rettelbach, M. Multrus
87   Contents/Description: PS parameter extraction, encoding
88
89******************************************************************************/
90/*!
91  \file
92  \brief  PS parameter extraction, encoding functions
93*/
94
95#include "ps_main.h"
96
97
98#include "sbr_ram.h"
99#include "ps_encode.h"
100
101#include "qmf.h"
102
103#include "ps_const.h"
104#include "sbr_misc.h"
105
106#include "genericStds.h"
107
108inline void FDKsbrEnc_addFIXP_DBL(const FIXP_DBL *X, const FIXP_DBL *Y, FIXP_DBL *Z, INT n)
109{
110  for (INT i=0; i<n; i++)
111    Z[i] = (X[i]>>1) + (Y[i]>>1);
112}
113
114#define LOG10_2_10             3.01029995664f /* 10.0f*log10(2.f) */
115
116static const INT iidGroupBordersLoRes[QMF_GROUPS_LO_RES + SUBQMF_GROUPS_LO_RES + 1] =
117{
118  0, 1, 2, 3, 4, 5,    /* 6 subqmf subbands - 0th qmf subband */
119  6, 7,                /* 2 subqmf subbands - 1st qmf subband */
120  8, 9,                /* 2 subqmf subbands - 2nd qmf subband */
121  10, 11, 12, 13, 14, 15, 16, 18, 21, 25, 30, 42, 71
122};
123
124static const UCHAR iidGroupWidthLdLoRes[QMF_GROUPS_LO_RES + SUBQMF_GROUPS_LO_RES] =
125{
126  0, 0, 0, 0, 0, 0,
127  0, 0,
128  0, 0,
129  0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 4, 5
130};
131
132
133static const INT subband2parameter20[QMF_GROUPS_LO_RES + SUBQMF_GROUPS_LO_RES] =
134{
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
141
142typedef enum {
143  MAX_TIME_DIFF_FRAMES = 20,
144  MAX_PS_NOHEADER_CNT  = 10,
145  MAX_NOENV_CNT        = 10,
146  DO_NOT_USE_THIS_MODE = 0x7FFFFF
147} __PS_CONSTANTS;
148
149
150
151static const FIXP_DBL iidQuant_fx[15] = {
152  (FIXP_DBL)0xce000000, (FIXP_DBL)0xdc000000, (FIXP_DBL)0xe4000000, (FIXP_DBL)0xec000000, (FIXP_DBL)0xf2000000, (FIXP_DBL)0xf8000000, (FIXP_DBL)0xfc000000, (FIXP_DBL)0x00000000,
153  (FIXP_DBL)0x04000000, (FIXP_DBL)0x08000000, (FIXP_DBL)0x0e000000, (FIXP_DBL)0x14000000, (FIXP_DBL)0x1c000000, (FIXP_DBL)0x24000000, (FIXP_DBL)0x32000000
154};
155
156static const FIXP_DBL iidQuantFine_fx[31] = {
157  (FIXP_DBL)0x9c000001, (FIXP_DBL)0xa6000001, (FIXP_DBL)0xb0000001, (FIXP_DBL)0xba000001, (FIXP_DBL)0xc4000000, (FIXP_DBL)0xce000000, (FIXP_DBL)0xd4000000, (FIXP_DBL)0xda000000,
158  (FIXP_DBL)0xe0000000, (FIXP_DBL)0xe6000000, (FIXP_DBL)0xec000000, (FIXP_DBL)0xf0000000, (FIXP_DBL)0xf4000000, (FIXP_DBL)0xf8000000, (FIXP_DBL)0xfc000000, (FIXP_DBL)0x00000000,
159  (FIXP_DBL)0x04000000, (FIXP_DBL)0x08000000, (FIXP_DBL)0x0c000000, (FIXP_DBL)0x10000000, (FIXP_DBL)0x14000000, (FIXP_DBL)0x1a000000, (FIXP_DBL)0x20000000, (FIXP_DBL)0x26000000,
160  (FIXP_DBL)0x2c000000, (FIXP_DBL)0x32000000, (FIXP_DBL)0x3c000000, (FIXP_DBL)0x45ffffff, (FIXP_DBL)0x4fffffff, (FIXP_DBL)0x59ffffff, (FIXP_DBL)0x63ffffff
161};
162
163
164
165static const FIXP_DBL iccQuant[8] = {
166  (FIXP_DBL)0x7fffffff, (FIXP_DBL)0x77ef9d7f, (FIXP_DBL)0x6babc97f, (FIXP_DBL)0x4ceaf27f, (FIXP_DBL)0x2f0ed3c0, (FIXP_DBL)0x00000000, (FIXP_DBL)0xb49ba601, (FIXP_DBL)0x80000000
167};
168
169static FDK_PSENC_ERROR InitPSData(
170        HANDLE_PS_DATA            hPsData
171        )
172{
173  FDK_PSENC_ERROR error = PSENC_OK;
174
175  if(hPsData == NULL) {
176    error = PSENC_INVALID_HANDLE;
177  }
178  else {
179    int i, env;
180    FDKmemclear(hPsData,sizeof(PS_DATA));
181
182    for (i=0; i<PS_MAX_BANDS; i++) {
183      hPsData->iidIdxLast[i] = 0;
184      hPsData->iccIdxLast[i] = 0;
185    }
186
187    hPsData->iidEnable    = hPsData->iidEnableLast = 0;
188    hPsData->iccEnable    = hPsData->iccEnableLast = 0;
189    hPsData->iidQuantMode = hPsData->iidQuantModeLast = PS_IID_RES_COARSE;
190    hPsData->iccQuantMode = hPsData->iccQuantModeLast = PS_ICC_ROT_A;
191
192    for(env=0; env<PS_MAX_ENVELOPES; env++) {
193      hPsData->iccDiffMode[env] = PS_DELTA_FREQ;
194      hPsData->iccDiffMode[env] = PS_DELTA_FREQ;
195
196      for (i=0; i<PS_MAX_BANDS; i++) {
197        hPsData->iidIdx[env][i] = 0;
198        hPsData->iccIdx[env][i] = 0;
199      }
200    }
201
202    hPsData->nEnvelopesLast = 0;
203
204    hPsData->headerCnt  = MAX_PS_NOHEADER_CNT;
205    hPsData->iidTimeCnt = MAX_TIME_DIFF_FRAMES;
206    hPsData->iccTimeCnt = MAX_TIME_DIFF_FRAMES;
207    hPsData->noEnvCnt   = MAX_NOENV_CNT;
208  }
209
210  return error;
211}
212
213static FIXP_DBL quantizeCoef( const FIXP_DBL *RESTRICT input,
214                              const INT       nBands,
215                              const FIXP_DBL *RESTRICT quantTable,
216                              const INT       idxOffset,
217                              const INT       nQuantSteps,
218                              INT            *RESTRICT quantOut)
219{
220  INT idx, band;
221  FIXP_DBL quantErr = FL2FXCONST_DBL(0.f);
222
223  for (band=0; band<nBands;band++) {
224    for(idx=0; idx<nQuantSteps-1; idx++){
225      if( fixp_abs((input[band]>>1)-(quantTable[idx+1]>>1)) >
226          fixp_abs((input[band]>>1)-(quantTable[idx]>>1)) )
227      {
228        break;
229      }
230    }
231    quantErr      += (fixp_abs(input[band]-quantTable[idx])>>PS_QUANT_SCALE);   /* don't scale before subtraction; diff smaller (64-25)/64 */
232    quantOut[band] = idx - idxOffset;
233  }
234
235  return quantErr;
236}
237
238static INT getICCMode(const INT nBands,
239                      const INT rotType)
240{
241  INT mode = 0;
242
243  switch(nBands) {
244  case PS_BANDS_COARSE:
245    mode = PS_RES_COARSE;
246    break;
247  case PS_BANDS_MID:
248    mode = PS_RES_MID;
249    break;
250  default:
251    mode = 0;
252  }
253  if(rotType==PS_ICC_ROT_B){
254    mode += 3;
255  }
256
257  return mode;
258}
259
260
261static INT getIIDMode(const INT nBands,
262                      const INT iidRes)
263{
264  INT mode = 0;
265
266  switch(nBands) {
267  case PS_BANDS_COARSE:
268    mode = PS_RES_COARSE;
269    break;
270  case PS_BANDS_MID:
271    mode = PS_RES_MID;
272    break;
273  default:
274    mode = 0;
275    break;
276  }
277
278  if(iidRes == PS_IID_RES_FINE){
279    mode += 3;
280  }
281
282  return mode;
283}
284
285
286static INT envelopeReducible(FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS],
287                             FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS],
288                             INT psBands,
289                             INT nEnvelopes)
290{
291  #define THRESH_SCALE     7
292
293  INT reducible = 1; /* true */
294  INT e = 0, b = 0;
295  FIXP_DBL dIid = FL2FXCONST_DBL(0.f);
296  FIXP_DBL dIcc = FL2FXCONST_DBL(0.f);
297
298  FIXP_DBL iidErrThreshold, iccErrThreshold;
299  FIXP_DBL iidMeanError, iccMeanError;
300
301  /* square values to prevent sqrt,
302     multiply bands to prevent division; bands shifted DFRACT_BITS instead (DFRACT_BITS-1) because fMultDiv2 used*/
303  iidErrThreshold = fMultDiv2 ( FL2FXCONST_DBL(6.5f*6.5f/(IID_SCALE_FT*IID_SCALE_FT)), (FIXP_DBL)(psBands<<((DFRACT_BITS)-THRESH_SCALE)) );
304  iccErrThreshold = fMultDiv2 ( FL2FXCONST_DBL(0.75f*0.75f),                           (FIXP_DBL)(psBands<<((DFRACT_BITS)-THRESH_SCALE)) );
305
306  if (nEnvelopes <= 1) {
307    reducible = 0;
308  } else {
309
310    /* mean error criterion */
311    for (e=0; (e < nEnvelopes/2) && (reducible!=0 ) ; e++) {
312      iidMeanError = iccMeanError = FL2FXCONST_DBL(0.f);
313      for(b=0; b<psBands; b++) {
314        dIid = (iid[2*e][b]>>1) - (iid[2*e+1][b]>>1);   /* scale 1 bit; squared -> 2 bit */
315        dIcc = (icc[2*e][b]>>1) - (icc[2*e+1][b]>>1);
316        iidMeanError += fPow2Div2(dIid)>>(5-1);    /* + (bands=20) scale = 5 */
317        iccMeanError += fPow2Div2(dIcc)>>(5-1);
318      }                                                 /* --> scaling = 7 bit = THRESH_SCALE !! */
319
320      /* instead sqrt values are squared!
321         instead of division, multiply threshold with psBands
322         scaling necessary!! */
323
324      /* quit as soon as threshold is reached */
325      if ( (iidMeanError > (iidErrThreshold)) ||
326           (iccMeanError > (iccErrThreshold)) ) {
327        reducible = 0;
328      }
329    }
330  } /* nEnvelopes != 1 */
331
332  return reducible;
333}
334
335
336static void processIidData(PS_DATA       *psData,
337                           FIXP_DBL       iid[PS_MAX_ENVELOPES][PS_MAX_BANDS],
338                           const INT      psBands,
339                           const INT      nEnvelopes,
340                           const FIXP_DBL quantErrorThreshold)
341{
342  INT iidIdxFine  [PS_MAX_ENVELOPES][PS_MAX_BANDS];
343  INT iidIdxCoarse[PS_MAX_ENVELOPES][PS_MAX_BANDS];
344
345  FIXP_DBL errIID = FL2FXCONST_DBL(0.f);
346  FIXP_DBL errIIDFine = FL2FXCONST_DBL(0.f);
347  INT   bitsIidFreq = 0;
348  INT   bitsIidTime = 0;
349  INT   bitsFineTot = 0;
350  INT   bitsCoarseTot = 0;
351  INT   error = 0;
352  INT   env, band;
353  INT   diffMode[PS_MAX_ENVELOPES], diffModeFine[PS_MAX_ENVELOPES];
354  INT loudnDiff = 0;
355  INT iidTransmit = 0;
356
357  bitsIidFreq = bitsIidTime = 0;
358
359  /* Quantize IID coefficients */
360  for(env=0;env<nEnvelopes; env++) {
361    errIID     += quantizeCoef(iid[env], psBands, iidQuant_fx,      7, 15, iidIdxCoarse[env]);
362    errIIDFine += quantizeCoef(iid[env], psBands, iidQuantFine_fx, 15, 31, iidIdxFine[env]);
363  }
364
365  /* normalize error to number of envelopes, ps bands
366     errIID /= psBands*nEnvelopes;
367     errIIDFine /= psBands*nEnvelopes; */
368
369
370  /* Check if IID coefficients should be used in this frame */
371  psData->iidEnable = 0;
372  for(env=0;env<nEnvelopes; env++) {
373    for(band=0;band<psBands;band++) {
374      loudnDiff   += fixp_abs(iidIdxCoarse[env][band]);
375      iidTransmit ++;
376    }
377  }
378
379  if(loudnDiff > fMultI(FL2FXCONST_DBL(0.7f),iidTransmit)){    /* 0.7f empiric value */
380    psData->iidEnable = 1;
381  }
382
383  /* if iid not active -> RESET data */
384  if(psData->iidEnable==0) {
385    psData->iidTimeCnt = MAX_TIME_DIFF_FRAMES;
386    for(env=0;env<nEnvelopes; env++) {
387      psData->iidDiffMode[env] = PS_DELTA_FREQ;
388      FDKmemclear(psData->iidIdx[env], sizeof(INT)*psBands);
389    }
390    return;
391  }
392
393  /* count COARSE quantization bits for first envelope*/
394  bitsIidFreq = FDKsbrEnc_EncodeIid(NULL, iidIdxCoarse[0], NULL, psBands, PS_IID_RES_COARSE, PS_DELTA_FREQ, &error);
395
396  if( (psData->iidTimeCnt>=MAX_TIME_DIFF_FRAMES) || (psData->iidQuantModeLast==PS_IID_RES_FINE) ) {
397    bitsIidTime     = DO_NOT_USE_THIS_MODE;
398  }
399  else {
400    bitsIidTime     = FDKsbrEnc_EncodeIid(NULL, iidIdxCoarse[0], psData->iidIdxLast, psBands, PS_IID_RES_COARSE, PS_DELTA_TIME, &error);
401  }
402
403  /* decision DELTA_FREQ vs DELTA_TIME */
404  if(bitsIidTime>bitsIidFreq) {
405    diffMode[0]   = PS_DELTA_FREQ;
406    bitsCoarseTot = bitsIidFreq;
407  }
408  else {
409    diffMode[0]   = PS_DELTA_TIME;
410    bitsCoarseTot = bitsIidTime;
411  }
412
413  /* count COARSE quantization bits for following envelopes*/
414  for(env=1;env<nEnvelopes; env++) {
415    bitsIidFreq  = FDKsbrEnc_EncodeIid(NULL, iidIdxCoarse[env], NULL,                psBands, PS_IID_RES_COARSE, PS_DELTA_FREQ, &error);
416    bitsIidTime  = FDKsbrEnc_EncodeIid(NULL, iidIdxCoarse[env], iidIdxCoarse[env-1], psBands, PS_IID_RES_COARSE, PS_DELTA_TIME, &error);
417
418    /* decision DELTA_FREQ vs DELTA_TIME */
419    if(bitsIidTime>bitsIidFreq) {
420      diffMode[env]  = PS_DELTA_FREQ;
421      bitsCoarseTot += bitsIidFreq;
422    }
423    else {
424      diffMode[env]  = PS_DELTA_TIME;
425      bitsCoarseTot += bitsIidTime;
426    }
427  }
428
429
430  /* count FINE quantization bits for first envelope*/
431  bitsIidFreq = FDKsbrEnc_EncodeIid(NULL, iidIdxFine[0],   NULL, psBands, PS_IID_RES_FINE,   PS_DELTA_FREQ, &error);
432
433  if( (psData->iidTimeCnt>=MAX_TIME_DIFF_FRAMES) || (psData->iidQuantModeLast==PS_IID_RES_COARSE) ) {
434    bitsIidTime = DO_NOT_USE_THIS_MODE;
435  }
436  else {
437    bitsIidTime = FDKsbrEnc_EncodeIid(NULL, iidIdxFine[0],  psData->iidIdxLast, psBands, PS_IID_RES_FINE, PS_DELTA_TIME, &error);
438  }
439
440  /* decision DELTA_FREQ vs DELTA_TIME */
441  if(bitsIidTime>bitsIidFreq) {
442    diffModeFine[0]   = PS_DELTA_FREQ;
443    bitsFineTot       = bitsIidFreq;
444  }
445  else {
446    diffModeFine[0]   = PS_DELTA_TIME;
447    bitsFineTot       = bitsIidTime;
448  }
449
450  /* count FINE quantization bits for following envelopes*/
451  for(env=1;env<nEnvelopes; env++) {
452    bitsIidFreq = FDKsbrEnc_EncodeIid(NULL, iidIdxFine[env],   NULL,              psBands, PS_IID_RES_FINE, PS_DELTA_FREQ, &error);
453    bitsIidTime = FDKsbrEnc_EncodeIid(NULL, iidIdxFine[env],   iidIdxFine[env-1], psBands, PS_IID_RES_FINE, PS_DELTA_TIME, &error);
454
455    /* decision DELTA_FREQ vs DELTA_TIME */
456    if(bitsIidTime>bitsIidFreq) {
457      diffModeFine[env]  = PS_DELTA_FREQ;
458      bitsFineTot += bitsIidFreq;
459    }
460    else {
461      diffModeFine[env]  = PS_DELTA_TIME;
462      bitsFineTot       += bitsIidTime;
463    }
464  }
465
466  if(bitsFineTot == bitsCoarseTot){
467    /* if same number of bits is needed, use the quantization with lower error */
468    if(errIIDFine < errIID){
469      bitsCoarseTot = DO_NOT_USE_THIS_MODE;
470    } else {
471      bitsFineTot = DO_NOT_USE_THIS_MODE;
472    }
473  } else {
474    /* const FIXP_DBL minThreshold = FL2FXCONST_DBL(0.2f/(IID_SCALE_FT*PS_QUANT_SCALE_FT)*(psBands*nEnvelopes)); */
475    const FIXP_DBL minThreshold = (FIXP_DBL)((LONG)0x00019999 * (psBands*nEnvelopes));
476
477    /* decision RES_FINE vs RES_COARSE                 */
478    /* test if errIIDFine*quantErrorThreshold < errIID */
479    /* shiftVal 2 comes from scaling of quantErrorThreshold */
480    if(fixMax(((errIIDFine>>1)+(minThreshold>>1))>>1, fMult(quantErrorThreshold,errIIDFine)) < (errIID>>2) ) {
481      bitsCoarseTot = DO_NOT_USE_THIS_MODE;
482    }
483    else if(fixMax(((errIID>>1)+(minThreshold>>1))>>1, fMult(quantErrorThreshold,errIID)) < (errIIDFine>>2) ) {
484      bitsFineTot = DO_NOT_USE_THIS_MODE;
485    }
486  }
487
488  /* decision RES_FINE vs RES_COARSE */
489  if(bitsFineTot<bitsCoarseTot) {
490    psData->iidQuantMode = PS_IID_RES_FINE;
491    for(env=0;env<nEnvelopes; env++) {
492      psData->iidDiffMode[env] = diffModeFine[env];
493      FDKmemcpy(psData->iidIdx[env], iidIdxFine[env], psBands*sizeof(INT));
494    }
495  }
496  else {
497    psData->iidQuantMode = PS_IID_RES_COARSE;
498    for(env=0;env<nEnvelopes; env++) {
499      psData->iidDiffMode[env] = diffMode[env];
500      FDKmemcpy(psData->iidIdx[env], iidIdxCoarse[env], psBands*sizeof(INT));
501    }
502  }
503
504  /* Count DELTA_TIME encoding streaks */
505  for(env=0;env<nEnvelopes; env++) {
506    if(psData->iidDiffMode[env]==PS_DELTA_TIME)
507      psData->iidTimeCnt++;
508    else
509      psData->iidTimeCnt=0;
510  }
511}
512
513
514static INT similarIid(PS_DATA   *psData,
515                      const INT  psBands,
516                      const INT  nEnvelopes)
517{
518  const INT diffThr = (psData->iidQuantMode == PS_IID_RES_COARSE) ? 2 : 3;
519  const INT sumDiffThr = diffThr * psBands/4;
520  INT similar = 0;
521  INT diff    = 0;
522  INT sumDiff = 0;
523  INT env = 0;
524  INT b   = 0;
525  if ((nEnvelopes == psData->nEnvelopesLast) && (nEnvelopes==1)) {
526    similar = 1;
527    for (env=0; env<nEnvelopes; env++) {
528      sumDiff = 0;
529      b = 0;
530      do {
531        diff = fixp_abs(psData->iidIdx[env][b] - psData->iidIdxLast[b]);
532        sumDiff += diff;
533        if ( (diff > diffThr) /* more than x quantization steps in any band */
534             || (sumDiff > sumDiffThr) ) {  /* more than x quantisations steps overall difference */
535          similar = 0;
536        }
537        b++;
538      } while ((b<psBands) && (similar>0));
539    }
540  } /* nEnvelopes==1  */
541
542  return similar;
543}
544
545
546static INT similarIcc(PS_DATA *psData,
547                      const INT    psBands,
548                      const INT    nEnvelopes)
549{
550  const INT diffThr = 2;
551  const INT sumDiffThr = diffThr * psBands/4;
552  INT similar = 0;
553  INT diff    = 0;
554  INT sumDiff = 0;
555  INT env = 0;
556  INT b   = 0;
557  if ((nEnvelopes == psData->nEnvelopesLast) && (nEnvelopes==1)) {
558    similar = 1;
559    for (env=0; env<nEnvelopes; env++) {
560      sumDiff = 0;
561      b = 0;
562      do {
563        diff = fixp_abs(psData->iccIdx[env][b] - psData->iccIdxLast[b]);
564        sumDiff += diff;
565        if ( (diff > diffThr) /* more than x quantisation step in any band */
566             || (sumDiff > sumDiffThr) ) {  /* more than x quantisations steps overall difference */
567          similar = 0;
568        }
569        b++;
570      } while ((b<psBands) && (similar>0));
571    }
572  } /* nEnvelopes==1  */
573
574  return similar;
575}
576
577static void processIccData(PS_DATA   *psData,
578                           FIXP_DBL   icc[PS_MAX_ENVELOPES][PS_MAX_BANDS], /* const input values: unable to declare as const, since it does not poINT to const memory */
579                           const INT  psBands,
580                           const INT  nEnvelopes)
581{
582  FIXP_DBL errICC = FL2FXCONST_DBL(0.f);
583  INT   env, band;
584  INT   bitsIccFreq, bitsIccTime;
585  INT   error = 0;
586  INT   inCoherence=0, iccTransmit=0;
587  INT  *iccIdxLast;
588
589  iccIdxLast = psData->iccIdxLast;
590
591  /* Quantize ICC coefficients */
592  for(env=0;env<nEnvelopes; env++) {
593    errICC += quantizeCoef(icc[env], psBands, iccQuant, 0, 8, psData->iccIdx[env]);
594  }
595
596  /* Check if ICC coefficients should be used */
597  psData->iccEnable = 0;
598  for(env=0;env<nEnvelopes; env++) {
599    for(band=0;band<psBands;band++) {
600      inCoherence += psData->iccIdx[env][band];
601      iccTransmit ++;
602    }
603  }
604  if(inCoherence > fMultI(FL2FXCONST_DBL(0.5f),iccTransmit)){   /* 0.5f empiric value */
605    psData->iccEnable = 1;
606  }
607
608  if(psData->iccEnable==0) {
609    psData->iccTimeCnt = MAX_TIME_DIFF_FRAMES;
610    for(env=0;env<nEnvelopes; env++) {
611      psData->iccDiffMode[env] = PS_DELTA_FREQ;
612      FDKmemclear(psData->iccIdx[env], sizeof(INT)*psBands);
613    }
614    return;
615  }
616
617  for(env=0;env<nEnvelopes; env++) {
618    bitsIccFreq  = FDKsbrEnc_EncodeIcc(NULL, psData->iccIdx[env],   NULL,       psBands, PS_DELTA_FREQ, &error);
619
620    if(psData->iccTimeCnt<MAX_TIME_DIFF_FRAMES) {
621      bitsIccTime  = FDKsbrEnc_EncodeIcc(NULL, psData->iccIdx[env], iccIdxLast, psBands, PS_DELTA_TIME, &error);
622    }
623    else {
624      bitsIccTime  = DO_NOT_USE_THIS_MODE;
625    }
626
627    if(bitsIccFreq>bitsIccTime) {
628      psData->iccDiffMode[env] = PS_DELTA_TIME;
629      psData->iccTimeCnt++;
630    }
631    else {
632      psData->iccDiffMode[env] = PS_DELTA_FREQ;
633      psData->iccTimeCnt=0;
634    }
635    iccIdxLast = psData->iccIdx[env];
636  }
637}
638
639static void calculateIID(FIXP_DBL ldPwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS],
640                         FIXP_DBL ldPwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS],
641                         FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS],
642                         INT   nEnvelopes,
643                         INT   psBands)
644{
645  INT i=0;
646  INT env=0;
647  for(env=0; env<nEnvelopes;env++) {
648    for (i=0; i<psBands; i++) {
649
650      /* iid[env][i] = 10.0f*(float)log10(pwrL[env][i]/pwrR[env][i]);
651      */
652      FIXP_DBL IID = fMultDiv2( FL2FXCONST_DBL(LOG10_2_10/IID_SCALE_FT), (ldPwrL[env][i]-ldPwrR[env][i]) );
653
654      IID = fixMin( IID, (FIXP_DBL)(MAXVAL_DBL>>(LD_DATA_SHIFT+1)) );
655      IID = fixMax( IID, (FIXP_DBL)(MINVAL_DBL>>(LD_DATA_SHIFT+1)) );
656      iid[env][i] = IID << (LD_DATA_SHIFT+1);
657    }
658  }
659}
660
661static void calculateICC(FIXP_DBL ldPwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS],
662                         FIXP_DBL ldPwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS],
663                         FIXP_DBL pwrCr[PS_MAX_ENVELOPES][PS_MAX_BANDS],
664                         FIXP_DBL pwrCi[PS_MAX_ENVELOPES][PS_MAX_BANDS],
665                         FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS],
666                         INT   nEnvelopes,
667                         INT   psBands)
668{
669  INT i = 0;
670  INT env = 0;
671  INT border = psBands;
672
673  switch (psBands) {
674  case PS_BANDS_COARSE:
675    border = 5;
676    break;
677  case PS_BANDS_MID:
678    border = 11;
679    break;
680  default:
681    break;
682  }
683
684  for(env=0; env<nEnvelopes;env++) {
685    for (i=0; i<border; i++) {
686
687      /* icc[env][i] = min( pwrCr[env][i] / (float) sqrt(pwrL[env][i] * pwrR[env][i]) , 1.f);
688      */
689      FIXP_DBL ICC, invNrg = CalcInvLdData ( -((ldPwrL[env][i]>>1) + (ldPwrR[env][i]>>1) + (FIXP_DBL)1) );
690      INT      scale, invScale = CountLeadingBits(invNrg);
691
692      scale = (DFRACT_BITS-1) - invScale;
693      ICC = fMult(pwrCr[env][i], invNrg<<invScale) ;
694      icc[env][i] = SATURATE_LEFT_SHIFT(ICC, scale, DFRACT_BITS);
695    }
696
697    for (; i<psBands; i++) {
698      INT sc1, sc2;
699      FIXP_DBL cNrgR, cNrgI, ICC;
700
701      sc1 = CountLeadingBits( fixMax(fixp_abs(pwrCr[env][i]),fixp_abs(pwrCi[env][i])) ) ;
702      cNrgR = fPow2Div2((pwrCr[env][i]<<sc1));       /* squared nrg's expect explicit scaling */
703      cNrgI = fPow2Div2((pwrCi[env][i]<<sc1));
704
705      ICC = CalcInvLdData( (CalcLdData((cNrgR + cNrgI)>>1)>>1) - (FIXP_DBL)((sc1-1)<<(DFRACT_BITS-1-LD_DATA_SHIFT)) );
706
707      FIXP_DBL invNrg = CalcInvLdData ( -((ldPwrL[env][i]>>1) + (ldPwrR[env][i]>>1) + (FIXP_DBL)1) );
708      sc1 = CountLeadingBits(invNrg);
709      invNrg <<= sc1;
710
711      sc2 = CountLeadingBits(ICC);
712      ICC = fMult(ICC<<sc2,invNrg);
713
714      sc1 = ( (DFRACT_BITS-1) - sc1 - sc2 );
715      if (sc1 < 0) {
716          ICC >>= -sc1;
717      }
718      else {
719          if (ICC >= ((FIXP_DBL)MAXVAL_DBL>>sc1) )
720              ICC = (FIXP_DBL)MAXVAL_DBL;
721          else
722              ICC <<= sc1;
723      }
724
725      icc[env][i] = ICC;
726    }
727  }
728}
729
730void FDKsbrEnc_initPsBandNrgScale(HANDLE_PS_ENCODE hPsEncode)
731{
732  INT group, bin;
733  INT nIidGroups   = hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups;
734
735  FDKmemclear(hPsEncode->psBandNrgScale, PS_MAX_BANDS*sizeof(SCHAR));
736
737  for (group=0; group < nIidGroups; group++) {
738    /* Translate group to bin */
739    bin = hPsEncode->subband2parameterIndex[group];
740
741    /* Translate from 20 bins to 10 bins */
742    if (hPsEncode->psEncMode == PS_BANDS_COARSE) {
743      bin = bin>>1;
744    }
745
746    hPsEncode->psBandNrgScale[bin] = (hPsEncode->psBandNrgScale[bin]==0)
747                          ? (hPsEncode->iidGroupWidthLd[group] + 5)
748                          : (fixMax(hPsEncode->iidGroupWidthLd[group],hPsEncode->psBandNrgScale[bin]) + 1) ;
749
750  }
751}
752
753FDK_PSENC_ERROR FDKsbrEnc_CreatePSEncode(
754        HANDLE_PS_ENCODE         *phPsEncode
755        )
756{
757  FDK_PSENC_ERROR error = PSENC_OK;
758
759  if (phPsEncode==NULL) {
760    error = PSENC_INVALID_HANDLE;
761  }
762  else {
763    HANDLE_PS_ENCODE hPsEncode = NULL;
764    if (NULL==(hPsEncode = GetRam_PsEncode())) {
765      error = PSENC_MEMORY_ERROR;
766      goto bail;
767    }
768    FDKmemclear(hPsEncode,sizeof(PS_ENCODE));
769    *phPsEncode = hPsEncode; /* return allocated handle */
770  }
771bail:
772  return error;
773}
774
775FDK_PSENC_ERROR FDKsbrEnc_InitPSEncode(
776        HANDLE_PS_ENCODE          hPsEncode,
777        const PS_BANDS            psEncMode,
778        const FIXP_DBL            iidQuantErrorThreshold
779        )
780{
781  FDK_PSENC_ERROR error = PSENC_OK;
782
783  if (NULL==hPsEncode) {
784    error = PSENC_INVALID_HANDLE;
785  }
786  else {
787    if (PSENC_OK != (InitPSData(&hPsEncode->psData))) {
788      goto bail;
789    }
790
791    switch(psEncMode){
792      case PS_BANDS_COARSE:
793      case PS_BANDS_MID:
794        hPsEncode->nQmfIidGroups    = QMF_GROUPS_LO_RES;
795        hPsEncode->nSubQmfIidGroups = SUBQMF_GROUPS_LO_RES;
796        FDKmemcpy(hPsEncode->iidGroupBorders,        iidGroupBordersLoRes, (hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups + 1)*sizeof(INT));
797        FDKmemcpy(hPsEncode->subband2parameterIndex, subband2parameter20,  (hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups)    *sizeof(INT));
798        FDKmemcpy(hPsEncode->iidGroupWidthLd,        iidGroupWidthLdLoRes, (hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups)    *sizeof(UCHAR));
799        break;
800      default:
801        error = PSENC_INIT_ERROR;
802        goto bail;
803    }
804
805    hPsEncode->psEncMode = psEncMode;
806    hPsEncode->iidQuantErrorThreshold = iidQuantErrorThreshold;
807    FDKsbrEnc_initPsBandNrgScale(hPsEncode);
808  }
809bail:
810  return error;
811}
812
813
814FDK_PSENC_ERROR FDKsbrEnc_DestroyPSEncode(
815        HANDLE_PS_ENCODE         *phPsEncode
816        )
817{
818  FDK_PSENC_ERROR error = PSENC_OK;
819
820  if (NULL !=phPsEncode) {
821    FreeRam_PsEncode(phPsEncode);
822  }
823
824  return error;
825}
826
827typedef struct {
828  FIXP_DBL pwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS];
829  FIXP_DBL pwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS];
830  FIXP_DBL ldPwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS];
831  FIXP_DBL ldPwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS];
832  FIXP_DBL pwrCr[PS_MAX_ENVELOPES][PS_MAX_BANDS];
833  FIXP_DBL pwrCi[PS_MAX_ENVELOPES][PS_MAX_BANDS];
834
835} PS_PWR_DATA;
836
837
838FDK_PSENC_ERROR FDKsbrEnc_PSEncode(
839        HANDLE_PS_ENCODE          hPsEncode,
840        HANDLE_PS_OUT             hPsOut,
841        UCHAR                    *dynBandScale,
842        UINT                      maxEnvelopes,
843        FIXP_DBL                 *hybridData[HYBRID_FRAMESIZE][MAX_PS_CHANNELS][2],
844        const INT                 frameSize,
845        const INT                 sendHeader
846        )
847{
848  FDK_PSENC_ERROR error = PSENC_OK;
849
850  HANDLE_PS_DATA hPsData = &hPsEncode->psData;
851  FIXP_DBL iid [PS_MAX_ENVELOPES][PS_MAX_BANDS];
852  FIXP_DBL icc [PS_MAX_ENVELOPES][PS_MAX_BANDS];
853  int envBorder[PS_MAX_ENVELOPES+1];
854
855  int group, bin, col, subband, band;
856  int i = 0;
857
858  int env = 0;
859  int psBands      = (int) hPsEncode->psEncMode;
860  int nIidGroups   = hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups;
861  int nEnvelopes   = fixMin(maxEnvelopes, (UINT)PS_MAX_ENVELOPES);
862
863  C_ALLOC_SCRATCH_START(pwrData, PS_PWR_DATA, 1);
864
865  for(env=0; env<nEnvelopes+1;env++) {
866    envBorder[env] = fMultI(GetInvInt(nEnvelopes),frameSize*env);
867  }
868
869  for(env=0; env<nEnvelopes;env++) {
870
871    /* clear energy array */
872    for (band=0; band<psBands; band++) {
873      pwrData->pwrL[env][band] = pwrData->pwrR[env][band] = pwrData->pwrCr[env][band] = pwrData->pwrCi[env][band] = FIXP_DBL(1);
874    }
875
876    /**** calculate energies and correlation ****/
877
878    /* start with hybrid data */
879    for (group=0; group < nIidGroups; group++) {
880      /* Translate group to bin */
881      bin = hPsEncode->subband2parameterIndex[group];
882
883      /* Translate from 20 bins to 10 bins */
884      if (hPsEncode->psEncMode == PS_BANDS_COARSE) {
885        bin >>= 1;
886      }
887
888      /* determine group border */
889      int bScale = hPsEncode->psBandNrgScale[bin];
890
891      FIXP_DBL pwrL_env_bin = pwrData->pwrL[env][bin];
892      FIXP_DBL pwrR_env_bin = pwrData->pwrR[env][bin];
893      FIXP_DBL pwrCr_env_bin = pwrData->pwrCr[env][bin];
894      FIXP_DBL pwrCi_env_bin = pwrData->pwrCi[env][bin];
895
896      int scale = (int)dynBandScale[bin];
897      for (col=envBorder[env]; col<envBorder[env+1]; col++) {
898        for (subband = hPsEncode->iidGroupBorders[group]; subband < hPsEncode->iidGroupBorders[group+1]; subband++) {
899          FIXP_QMF l_real = (hybridData[col][0][0][subband]) << scale;
900          FIXP_QMF l_imag = (hybridData[col][0][1][subband]) << scale;
901          FIXP_QMF r_real = (hybridData[col][1][0][subband]) << scale;
902          FIXP_QMF r_imag = (hybridData[col][1][1][subband]) << scale;
903
904          pwrL_env_bin  += (fPow2Div2(l_real) + fPow2Div2(l_imag)) >> bScale;
905          pwrR_env_bin  += (fPow2Div2(r_real) + fPow2Div2(r_imag)) >> bScale;
906          pwrCr_env_bin += (fMultDiv2(l_real, r_real) + fMultDiv2(l_imag, r_imag)) >> bScale;
907          pwrCi_env_bin += (fMultDiv2(r_real, l_imag) - fMultDiv2(l_real, r_imag)) >> bScale;
908        }
909      }
910      /* assure, nrg's of left and right channel are not negative; necessary on 16 bit multiply units */
911      pwrData->pwrL[env][bin] = fixMax((FIXP_DBL)0,pwrL_env_bin);
912      pwrData->pwrR[env][bin] = fixMax((FIXP_DBL)0,pwrR_env_bin);
913
914      pwrData->pwrCr[env][bin] = pwrCr_env_bin;
915      pwrData->pwrCi[env][bin] = pwrCi_env_bin;
916
917    } /* nIidGroups */
918
919    /* calc logarithmic energy */
920    LdDataVector(pwrData->pwrL[env], pwrData->ldPwrL[env], psBands);
921    LdDataVector(pwrData->pwrR[env], pwrData->ldPwrR[env], psBands);
922
923  } /* nEnvelopes */
924
925  /* calculate iid and icc */
926  calculateIID(pwrData->ldPwrL, pwrData->ldPwrR, iid, nEnvelopes, psBands);
927  calculateICC(pwrData->ldPwrL, pwrData->ldPwrR, pwrData->pwrCr, pwrData->pwrCi, icc, nEnvelopes, psBands);
928
929  /*** Envelope Reduction ***/
930  while (envelopeReducible(iid,icc,psBands,nEnvelopes)) {
931    int e=0;
932    /* sum energies of two neighboring envelopes */
933    nEnvelopes >>= 1;
934    for (e=0; e<nEnvelopes; e++) {
935      FDKsbrEnc_addFIXP_DBL(pwrData->pwrL[2*e], pwrData->pwrL[2*e+1], pwrData->pwrL[e], psBands);
936      FDKsbrEnc_addFIXP_DBL(pwrData->pwrR[2*e], pwrData->pwrR[2*e+1], pwrData->pwrR[e], psBands);
937      FDKsbrEnc_addFIXP_DBL(pwrData->pwrCr[2*e],pwrData->pwrCr[2*e+1],pwrData->pwrCr[e],psBands);
938      FDKsbrEnc_addFIXP_DBL(pwrData->pwrCi[2*e],pwrData->pwrCi[2*e+1],pwrData->pwrCi[e],psBands);
939
940      /* calc logarithmic energy */
941      LdDataVector(pwrData->pwrL[e], pwrData->ldPwrL[e], psBands);
942      LdDataVector(pwrData->pwrR[e], pwrData->ldPwrR[e], psBands);
943
944      /* reduce number of envelopes and adjust borders */
945      envBorder[e] = envBorder[2*e];
946    }
947    envBorder[nEnvelopes] = envBorder[2*nEnvelopes];
948
949    /* re-calculate iid and icc */
950    calculateIID(pwrData->ldPwrL, pwrData->ldPwrR, iid, nEnvelopes, psBands);
951    calculateICC(pwrData->ldPwrL, pwrData->ldPwrR, pwrData->pwrCr, pwrData->pwrCi, icc, nEnvelopes, psBands);
952  }
953
954
955  /*  */
956  if(sendHeader) {
957    hPsData->headerCnt  = MAX_PS_NOHEADER_CNT;
958    hPsData->iidTimeCnt = MAX_TIME_DIFF_FRAMES;
959    hPsData->iccTimeCnt = MAX_TIME_DIFF_FRAMES;
960    hPsData->noEnvCnt   = MAX_NOENV_CNT;
961  }
962
963  /*** Parameter processing, quantisation etc ***/
964  processIidData(hPsData, iid, psBands, nEnvelopes, hPsEncode->iidQuantErrorThreshold);
965  processIccData(hPsData, icc, psBands, nEnvelopes);
966
967
968  /*** Initialize output struct ***/
969
970  /* PS Header on/off ? */
971  if( (hPsData->headerCnt<MAX_PS_NOHEADER_CNT)
972       && ( (hPsData->iidQuantMode == hPsData->iidQuantModeLast) && (hPsData->iccQuantMode == hPsData->iccQuantModeLast) )
973       && ( (hPsData->iidEnable    == hPsData->iidEnableLast)    && (hPsData->iccEnable    == hPsData->iccEnableLast)  ) ) {
974    hPsOut->enablePSHeader = 0;
975  }
976  else {
977    hPsOut->enablePSHeader = 1;
978    hPsData->headerCnt = 0;
979  }
980
981  /* nEnvelopes = 0 ? */
982  if ( (hPsData->noEnvCnt < MAX_NOENV_CNT)
983       && (similarIid(hPsData, psBands, nEnvelopes))
984       && (similarIcc(hPsData, psBands, nEnvelopes)) ) {
985    hPsOut->nEnvelopes = nEnvelopes = 0;
986    hPsData->noEnvCnt++;
987  } else {
988    hPsData->noEnvCnt = 0;
989  }
990
991
992  if (nEnvelopes>0) {
993
994    hPsOut->enableIID      = hPsData->iidEnable;
995    hPsOut->iidMode        = getIIDMode(psBands, hPsData->iidQuantMode);
996
997    hPsOut->enableICC      = hPsData->iccEnable;
998    hPsOut->iccMode        = getICCMode(psBands, hPsData->iccQuantMode);
999
1000    hPsOut->enableIpdOpd  = 0;
1001    hPsOut->frameClass    = 0;
1002    hPsOut->nEnvelopes    = nEnvelopes;
1003
1004    for(env=0; env<nEnvelopes; env++) {
1005      hPsOut->frameBorder[env] = envBorder[env+1];
1006    }
1007
1008    for(env=0; env<hPsOut->nEnvelopes; env++) {
1009      hPsOut->deltaIID[env] = (PS_DELTA)hPsData->iidDiffMode[env];
1010
1011      for(band=0; band<psBands; band++) {
1012        hPsOut->iid[env][band] = hPsData->iidIdx[env][band];
1013      }
1014    }
1015
1016    for(env=0; env<hPsOut->nEnvelopes; env++) {
1017      hPsOut->deltaICC[env] = (PS_DELTA)hPsData->iccDiffMode[env];
1018      for(band=0; band<psBands; band++) {
1019        hPsOut->icc[env][band] = hPsData->iccIdx[env][band];
1020      }
1021    }
1022
1023    /* IPD OPD not supported right now */
1024    FDKmemclear(hPsOut->ipd, PS_MAX_ENVELOPES*PS_MAX_BANDS*sizeof(PS_DELTA));
1025    for(env=0; env<PS_MAX_ENVELOPES; env++) {
1026      hPsOut->deltaIPD[env] = PS_DELTA_FREQ;
1027      hPsOut->deltaOPD[env] = PS_DELTA_FREQ;
1028    }
1029
1030    FDKmemclear(hPsOut->ipdLast, PS_MAX_BANDS*sizeof(INT));
1031    FDKmemclear(hPsOut->opdLast, PS_MAX_BANDS*sizeof(INT));
1032
1033    for(band=0; band<PS_MAX_BANDS; band++) {
1034      hPsOut->iidLast[band] = hPsData->iidIdxLast[band];
1035      hPsOut->iccLast[band] = hPsData->iccIdxLast[band];
1036    }
1037
1038    /* save iids and iccs for differential time coding in the next frame */
1039    hPsData->nEnvelopesLast   = nEnvelopes;
1040    hPsData->iidEnableLast    = hPsData->iidEnable;
1041    hPsData->iccEnableLast    = hPsData->iccEnable;
1042    hPsData->iidQuantModeLast = hPsData->iidQuantMode;
1043    hPsData->iccQuantModeLast = hPsData->iccQuantMode;
1044    for (i=0; i<psBands; i++) {
1045      hPsData->iidIdxLast[i] = hPsData->iidIdx[nEnvelopes-1][i];
1046      hPsData->iccIdxLast[i] = hPsData->iccIdx[nEnvelopes-1][i];
1047    }
1048  } /* Envelope > 0 */
1049
1050  C_ALLOC_SCRATCH_END(pwrData, PS_PWR_DATA, 1)
1051
1052  return error;
1053}
1054
1055