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