1
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5 � Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6 All rights reserved.
7
8 1. INTRODUCTION
9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16 of the MPEG specifications.
17
18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
24
25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27 applications information and documentation.
28
29 2. COPYRIGHT LICENSE
30
31 Redistribution and use in source and binary forms, with or without modification, are permitted without
32 payment of copyright license fees provided that you satisfy the following conditions:
33
34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35 your modifications thereto in source code form.
36
37 You must retain the complete text of this software license in the documentation and/or other materials
38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40 modifications thereto to recipients of copies in binary form.
41
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
44
45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46 software or your modifications thereto.
47
48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49 and 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
53 3. NO PATENT LICENSE
54
55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57 respect to this software.
58
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
61
62 4. DISCLAIMER
63
64 This 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
66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69 or business interruption, however caused and on any theory of liability, whether in contract, strict
70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
71 advised of the possibility of such damage.
72
73 5. CONTACT INFORMATION
74
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
77 Am Wolfsmantel 33
78 91058 Erlangen, Germany
79
80 www.iis.fraunhofer.de/amm
81 amm-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
FDKsbrEnc_addFIXP_DBL(const FIXP_DBL * X,const FIXP_DBL * Y,FIXP_DBL * Z,INT n)108 inline 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
116 static 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
124 static 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
133 static 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
142 typedef 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
151 static const FIXP_DBL iidQuant_fx[15] = {
152 0xce000000, 0xdc000000, 0xe4000000, 0xec000000, 0xf2000000, 0xf8000000, 0xfc000000, 0x00000000,
153 0x04000000, 0x08000000, 0x0e000000, 0x14000000, 0x1c000000, 0x24000000, 0x32000000
154 };
155
156 static const FIXP_DBL iidQuantFine_fx[31] = {
157 0x9c000001, 0xa6000001, 0xb0000001, 0xba000001, 0xc4000000, 0xce000000, 0xd4000000, 0xda000000,
158 0xe0000000, 0xe6000000, 0xec000000, 0xf0000000, 0xf4000000, 0xf8000000, 0xfc000000, 0x00000000,
159 0x04000000, 0x08000000, 0x0c000000, 0x10000000, 0x14000000, 0x1a000000, 0x20000000, 0x26000000,
160 0x2c000000, 0x32000000, 0x3c000000, 0x45ffffff, 0x4fffffff, 0x59ffffff, 0x63ffffff
161 };
162
163
164
165 static const FIXP_DBL iccQuant[8] = {
166 0x7fffffff, 0x77ef9d7f, 0x6babc97f, 0x4ceaf27f, 0x2f0ed3c0, 0x00000000, 0xb49ba601, 0x80000000
167 };
168
InitPSData(HANDLE_PS_DATA hPsData)169 static 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
quantizeCoef(const FIXP_DBL * RESTRICT input,const INT nBands,const FIXP_DBL * RESTRICT quantTable,const INT idxOffset,const INT nQuantSteps,INT * RESTRICT quantOut)213 static 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
getICCMode(const INT nBands,const INT rotType)238 static 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
getIIDMode(const INT nBands,const INT iidRes)261 static 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
envelopeReducible(FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS],FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS],INT psBands,INT nEnvelopes)286 static 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
processIidData(PS_DATA * psData,FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS],const INT psBands,const INT nEnvelopes,const FIXP_DBL quantErrorThreshold)336 static 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
similarIid(PS_DATA * psData,const INT psBands,const INT nEnvelopes)514 static 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
similarIcc(PS_DATA * psData,const INT psBands,const INT nEnvelopes)546 static 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
processIccData(PS_DATA * psData,FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS],const INT psBands,const INT nEnvelopes)577 static 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
calculateIID(FIXP_DBL ldPwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS],FIXP_DBL ldPwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS],FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS],INT nEnvelopes,INT psBands)639 static 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
calculateICC(FIXP_DBL ldPwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS],FIXP_DBL ldPwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS],FIXP_DBL pwrCr[PS_MAX_ENVELOPES][PS_MAX_BANDS],FIXP_DBL pwrCi[PS_MAX_ENVELOPES][PS_MAX_BANDS],FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS],INT nEnvelopes,INT psBands)661 static 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
FDKsbrEnc_initPsBandNrgScale(HANDLE_PS_ENCODE hPsEncode)730 void 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
FDKsbrEnc_CreatePSEncode(HANDLE_PS_ENCODE * phPsEncode)753 FDK_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 }
771 bail:
772 return error;
773 }
774
FDKsbrEnc_InitPSEncode(HANDLE_PS_ENCODE hPsEncode,const PS_BANDS psEncMode,const FIXP_DBL iidQuantErrorThreshold)775 FDK_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 }
809 bail:
810 return error;
811 }
812
813
FDKsbrEnc_DestroyPSEncode(HANDLE_PS_ENCODE * phPsEncode)814 FDK_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
827 typedef 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
FDKsbrEnc_PSEncode(HANDLE_PS_ENCODE hPsEncode,HANDLE_PS_OUT hPsOut,UCHAR * dynBandScale,UINT maxEnvelopes,FIXP_DBL * hybridData[HYBRID_FRAMESIZE][MAX_PS_CHANNELS][2],const INT frameSize,const INT sendHeader)838 FDK_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