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 - 2020 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 /************************* MPEG-D DRC decoder library **************************
96*e5436536SAndroid Build Coastguard Worker
97*e5436536SAndroid Build Coastguard Worker Author(s):
98*e5436536SAndroid Build Coastguard Worker
99*e5436536SAndroid Build Coastguard Worker Description:
100*e5436536SAndroid Build Coastguard Worker
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker
103*e5436536SAndroid Build Coastguard Worker #include "fixpoint_math.h"
104*e5436536SAndroid Build Coastguard Worker #include "drcDec_reader.h"
105*e5436536SAndroid Build Coastguard Worker #include "drcDec_tools.h"
106*e5436536SAndroid Build Coastguard Worker #include "drcDec_rom.h"
107*e5436536SAndroid Build Coastguard Worker #include "drcDecoder.h"
108*e5436536SAndroid Build Coastguard Worker
109*e5436536SAndroid Build Coastguard Worker /* MPEG-D DRC AMD 1 */
110*e5436536SAndroid Build Coastguard Worker
111*e5436536SAndroid Build Coastguard Worker #define UNIDRCCONFEXT_PARAM_DRC 0x1
112*e5436536SAndroid Build Coastguard Worker #define UNIDRCCONFEXT_V1 0x2
113*e5436536SAndroid Build Coastguard Worker #define UNIDRCLOUDEXT_EQ 0x1
114*e5436536SAndroid Build Coastguard Worker
115*e5436536SAndroid Build Coastguard Worker #define UNIDRCGAINEXT_TERM 0x0
116*e5436536SAndroid Build Coastguard Worker #define UNIDRCLOUDEXT_TERM 0x0
117*e5436536SAndroid Build Coastguard Worker #define UNIDRCCONFEXT_TERM 0x0
118*e5436536SAndroid Build Coastguard Worker
_getZ(const int nNodesMax)119*e5436536SAndroid Build Coastguard Worker static int _getZ(const int nNodesMax) {
120*e5436536SAndroid Build Coastguard Worker /* Z is the minimum codeword length that is needed to encode all possible
121*e5436536SAndroid Build Coastguard Worker * timeDelta values */
122*e5436536SAndroid Build Coastguard Worker /* Z = ceil(log2(2*nNodesMax)) */
123*e5436536SAndroid Build Coastguard Worker int Z = 1;
124*e5436536SAndroid Build Coastguard Worker while ((1 << Z) < (2 * nNodesMax)) {
125*e5436536SAndroid Build Coastguard Worker Z++;
126*e5436536SAndroid Build Coastguard Worker }
127*e5436536SAndroid Build Coastguard Worker return Z;
128*e5436536SAndroid Build Coastguard Worker }
129*e5436536SAndroid Build Coastguard Worker
_getTimeDeltaMin(const GAIN_SET * pGset,const int deltaTminDefault)130*e5436536SAndroid Build Coastguard Worker static int _getTimeDeltaMin(const GAIN_SET* pGset, const int deltaTminDefault) {
131*e5436536SAndroid Build Coastguard Worker if (pGset->timeDeltaMinPresent) {
132*e5436536SAndroid Build Coastguard Worker return pGset->timeDeltaMin;
133*e5436536SAndroid Build Coastguard Worker } else {
134*e5436536SAndroid Build Coastguard Worker return deltaTminDefault;
135*e5436536SAndroid Build Coastguard Worker }
136*e5436536SAndroid Build Coastguard Worker }
137*e5436536SAndroid Build Coastguard Worker
138*e5436536SAndroid Build Coastguard Worker /* compare and assign */
_compAssign(UCHAR * dest,const UCHAR src)139*e5436536SAndroid Build Coastguard Worker static inline int _compAssign(UCHAR* dest, const UCHAR src) {
140*e5436536SAndroid Build Coastguard Worker int diff = 0;
141*e5436536SAndroid Build Coastguard Worker if (*dest != src) diff = 1;
142*e5436536SAndroid Build Coastguard Worker *dest = src;
143*e5436536SAndroid Build Coastguard Worker return diff;
144*e5436536SAndroid Build Coastguard Worker }
145*e5436536SAndroid Build Coastguard Worker
_compAssign(ULONG * dest,const ULONG src)146*e5436536SAndroid Build Coastguard Worker static inline int _compAssign(ULONG* dest, const ULONG src) {
147*e5436536SAndroid Build Coastguard Worker int diff = 0;
148*e5436536SAndroid Build Coastguard Worker if (*dest != src) diff = 1;
149*e5436536SAndroid Build Coastguard Worker *dest = src;
150*e5436536SAndroid Build Coastguard Worker return diff;
151*e5436536SAndroid Build Coastguard Worker }
152*e5436536SAndroid Build Coastguard Worker
153*e5436536SAndroid Build Coastguard Worker typedef const SCHAR (*Huffman)[2];
154*e5436536SAndroid Build Coastguard Worker
_decodeHuffmanCW(Huffman h,HANDLE_FDK_BITSTREAM hBs)155*e5436536SAndroid Build Coastguard Worker int _decodeHuffmanCW(Huffman h, /*!< pointer to huffman codebook table */
156*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM hBs) /*!< Handle to bitbuffer */
157*e5436536SAndroid Build Coastguard Worker {
158*e5436536SAndroid Build Coastguard Worker SCHAR index = 0;
159*e5436536SAndroid Build Coastguard Worker int value, bit;
160*e5436536SAndroid Build Coastguard Worker
161*e5436536SAndroid Build Coastguard Worker while (index >= 0) {
162*e5436536SAndroid Build Coastguard Worker bit = FDKreadBits(hBs, 1);
163*e5436536SAndroid Build Coastguard Worker index = h[index][bit];
164*e5436536SAndroid Build Coastguard Worker }
165*e5436536SAndroid Build Coastguard Worker
166*e5436536SAndroid Build Coastguard Worker value = index + 64; /* Add offset */
167*e5436536SAndroid Build Coastguard Worker
168*e5436536SAndroid Build Coastguard Worker return value;
169*e5436536SAndroid Build Coastguard Worker }
170*e5436536SAndroid Build Coastguard Worker
171*e5436536SAndroid Build Coastguard Worker /**********/
172*e5436536SAndroid Build Coastguard Worker /* uniDrc */
173*e5436536SAndroid Build Coastguard Worker /**********/
174*e5436536SAndroid Build Coastguard Worker
175*e5436536SAndroid Build Coastguard Worker DRC_ERROR
drcDec_readUniDrc(HANDLE_FDK_BITSTREAM hBs,HANDLE_UNI_DRC_CONFIG hUniDrcConfig,HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,const int frameSize,const int deltaTminDefault,HANDLE_UNI_DRC_GAIN hUniDrcGain)176*e5436536SAndroid Build Coastguard Worker drcDec_readUniDrc(HANDLE_FDK_BITSTREAM hBs, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
177*e5436536SAndroid Build Coastguard Worker HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
178*e5436536SAndroid Build Coastguard Worker const int frameSize, const int deltaTminDefault,
179*e5436536SAndroid Build Coastguard Worker HANDLE_UNI_DRC_GAIN hUniDrcGain) {
180*e5436536SAndroid Build Coastguard Worker DRC_ERROR err = DE_OK;
181*e5436536SAndroid Build Coastguard Worker int loudnessInfoSetPresent, uniDrcConfigPresent;
182*e5436536SAndroid Build Coastguard Worker
183*e5436536SAndroid Build Coastguard Worker loudnessInfoSetPresent = FDKreadBits(hBs, 1);
184*e5436536SAndroid Build Coastguard Worker if (loudnessInfoSetPresent) {
185*e5436536SAndroid Build Coastguard Worker uniDrcConfigPresent = FDKreadBits(hBs, 1);
186*e5436536SAndroid Build Coastguard Worker if (uniDrcConfigPresent) {
187*e5436536SAndroid Build Coastguard Worker err = drcDec_readUniDrcConfig(hBs, hUniDrcConfig);
188*e5436536SAndroid Build Coastguard Worker if (err) {
189*e5436536SAndroid Build Coastguard Worker /* clear config, if parsing error occured */
190*e5436536SAndroid Build Coastguard Worker FDKmemclear(hUniDrcConfig, sizeof(UNI_DRC_CONFIG));
191*e5436536SAndroid Build Coastguard Worker hUniDrcConfig->diff = 1;
192*e5436536SAndroid Build Coastguard Worker }
193*e5436536SAndroid Build Coastguard Worker }
194*e5436536SAndroid Build Coastguard Worker err = drcDec_readLoudnessInfoSet(hBs, hLoudnessInfoSet);
195*e5436536SAndroid Build Coastguard Worker if (err) {
196*e5436536SAndroid Build Coastguard Worker /* clear config, if parsing error occured */
197*e5436536SAndroid Build Coastguard Worker FDKmemclear(hLoudnessInfoSet, sizeof(LOUDNESS_INFO_SET));
198*e5436536SAndroid Build Coastguard Worker hLoudnessInfoSet->diff = 1;
199*e5436536SAndroid Build Coastguard Worker }
200*e5436536SAndroid Build Coastguard Worker }
201*e5436536SAndroid Build Coastguard Worker
202*e5436536SAndroid Build Coastguard Worker err = drcDec_readUniDrcGain(hBs, hUniDrcConfig, frameSize, deltaTminDefault,
203*e5436536SAndroid Build Coastguard Worker hUniDrcGain);
204*e5436536SAndroid Build Coastguard Worker
205*e5436536SAndroid Build Coastguard Worker return err;
206*e5436536SAndroid Build Coastguard Worker }
207*e5436536SAndroid Build Coastguard Worker
208*e5436536SAndroid Build Coastguard Worker /**************/
209*e5436536SAndroid Build Coastguard Worker /* uniDrcGain */
210*e5436536SAndroid Build Coastguard Worker /**************/
211*e5436536SAndroid Build Coastguard Worker
_decodeGainInitial(HANDLE_FDK_BITSTREAM hBs,const GAIN_CODING_PROFILE gainCodingProfile)212*e5436536SAndroid Build Coastguard Worker static FIXP_SGL _decodeGainInitial(
213*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM hBs, const GAIN_CODING_PROFILE gainCodingProfile) {
214*e5436536SAndroid Build Coastguard Worker int sign, magn;
215*e5436536SAndroid Build Coastguard Worker FIXP_SGL gainInitial = (FIXP_SGL)0;
216*e5436536SAndroid Build Coastguard Worker switch (gainCodingProfile) {
217*e5436536SAndroid Build Coastguard Worker case GCP_REGULAR:
218*e5436536SAndroid Build Coastguard Worker sign = FDKreadBits(hBs, 1);
219*e5436536SAndroid Build Coastguard Worker magn = FDKreadBits(hBs, 8);
220*e5436536SAndroid Build Coastguard Worker
221*e5436536SAndroid Build Coastguard Worker gainInitial =
222*e5436536SAndroid Build Coastguard Worker (FIXP_SGL)(magn << (FRACT_BITS - 1 - 3 - 7)); /* magn * 0.125; */
223*e5436536SAndroid Build Coastguard Worker if (sign) gainInitial = -gainInitial;
224*e5436536SAndroid Build Coastguard Worker break;
225*e5436536SAndroid Build Coastguard Worker case GCP_FADING:
226*e5436536SAndroid Build Coastguard Worker sign = FDKreadBits(hBs, 1);
227*e5436536SAndroid Build Coastguard Worker if (sign == 0)
228*e5436536SAndroid Build Coastguard Worker gainInitial = (FIXP_SGL)0;
229*e5436536SAndroid Build Coastguard Worker else {
230*e5436536SAndroid Build Coastguard Worker magn = FDKreadBits(hBs, 10);
231*e5436536SAndroid Build Coastguard Worker gainInitial = -(FIXP_SGL)(
232*e5436536SAndroid Build Coastguard Worker (magn + 1) << (FRACT_BITS - 1 - 3 - 7)); /* - (magn + 1) * 0.125; */
233*e5436536SAndroid Build Coastguard Worker }
234*e5436536SAndroid Build Coastguard Worker break;
235*e5436536SAndroid Build Coastguard Worker case GCP_CLIPPING_DUCKING:
236*e5436536SAndroid Build Coastguard Worker sign = FDKreadBits(hBs, 1);
237*e5436536SAndroid Build Coastguard Worker if (sign == 0)
238*e5436536SAndroid Build Coastguard Worker gainInitial = (FIXP_SGL)0;
239*e5436536SAndroid Build Coastguard Worker else {
240*e5436536SAndroid Build Coastguard Worker magn = FDKreadBits(hBs, 8);
241*e5436536SAndroid Build Coastguard Worker gainInitial = -(FIXP_SGL)(
242*e5436536SAndroid Build Coastguard Worker (magn + 1) << (FRACT_BITS - 1 - 3 - 7)); /* - (magn + 1) * 0.125; */
243*e5436536SAndroid Build Coastguard Worker }
244*e5436536SAndroid Build Coastguard Worker break;
245*e5436536SAndroid Build Coastguard Worker case GCP_CONSTANT:
246*e5436536SAndroid Build Coastguard Worker break;
247*e5436536SAndroid Build Coastguard Worker }
248*e5436536SAndroid Build Coastguard Worker return gainInitial;
249*e5436536SAndroid Build Coastguard Worker }
250*e5436536SAndroid Build Coastguard Worker
_decodeNNodes(HANDLE_FDK_BITSTREAM hBs)251*e5436536SAndroid Build Coastguard Worker static int _decodeNNodes(HANDLE_FDK_BITSTREAM hBs) {
252*e5436536SAndroid Build Coastguard Worker int nNodes = 0, endMarker = 0;
253*e5436536SAndroid Build Coastguard Worker
254*e5436536SAndroid Build Coastguard Worker /* decode number of nodes */
255*e5436536SAndroid Build Coastguard Worker while (endMarker != 1) {
256*e5436536SAndroid Build Coastguard Worker nNodes++;
257*e5436536SAndroid Build Coastguard Worker if (nNodes >= 128) break;
258*e5436536SAndroid Build Coastguard Worker endMarker = FDKreadBits(hBs, 1);
259*e5436536SAndroid Build Coastguard Worker }
260*e5436536SAndroid Build Coastguard Worker return nNodes;
261*e5436536SAndroid Build Coastguard Worker }
262*e5436536SAndroid Build Coastguard Worker
_decodeGains(HANDLE_FDK_BITSTREAM hBs,const GAIN_CODING_PROFILE gainCodingProfile,const int nNodes,GAIN_NODE * pNodes)263*e5436536SAndroid Build Coastguard Worker static void _decodeGains(HANDLE_FDK_BITSTREAM hBs,
264*e5436536SAndroid Build Coastguard Worker const GAIN_CODING_PROFILE gainCodingProfile,
265*e5436536SAndroid Build Coastguard Worker const int nNodes, GAIN_NODE* pNodes) {
266*e5436536SAndroid Build Coastguard Worker int k, deltaGain;
267*e5436536SAndroid Build Coastguard Worker Huffman deltaGainCodebook;
268*e5436536SAndroid Build Coastguard Worker
269*e5436536SAndroid Build Coastguard Worker pNodes[0].gainDb = _decodeGainInitial(hBs, gainCodingProfile);
270*e5436536SAndroid Build Coastguard Worker
271*e5436536SAndroid Build Coastguard Worker if (gainCodingProfile == GCP_CLIPPING_DUCKING) {
272*e5436536SAndroid Build Coastguard Worker deltaGainCodebook = (Huffman)&deltaGain_codingProfile_2_huffman;
273*e5436536SAndroid Build Coastguard Worker } else {
274*e5436536SAndroid Build Coastguard Worker deltaGainCodebook = (Huffman)&deltaGain_codingProfile_0_1_huffman;
275*e5436536SAndroid Build Coastguard Worker }
276*e5436536SAndroid Build Coastguard Worker
277*e5436536SAndroid Build Coastguard Worker for (k = 1; k < nNodes; k++) {
278*e5436536SAndroid Build Coastguard Worker deltaGain = _decodeHuffmanCW(deltaGainCodebook, hBs);
279*e5436536SAndroid Build Coastguard Worker if (k >= 16) continue;
280*e5436536SAndroid Build Coastguard Worker /* gain_dB_e = 7 */
281*e5436536SAndroid Build Coastguard Worker pNodes[k].gainDb =
282*e5436536SAndroid Build Coastguard Worker pNodes[k - 1].gainDb +
283*e5436536SAndroid Build Coastguard Worker (FIXP_SGL)(deltaGain << (FRACT_BITS - 1 - 7 -
284*e5436536SAndroid Build Coastguard Worker 3)); /* pNodes[k-1].gainDb + 0.125*deltaGain */
285*e5436536SAndroid Build Coastguard Worker }
286*e5436536SAndroid Build Coastguard Worker }
287*e5436536SAndroid Build Coastguard Worker
_decodeSlopes(HANDLE_FDK_BITSTREAM hBs,const GAIN_INTERPOLATION_TYPE gainInterpolationType,const int nNodes,GAIN_NODE * pNodes)288*e5436536SAndroid Build Coastguard Worker static void _decodeSlopes(HANDLE_FDK_BITSTREAM hBs,
289*e5436536SAndroid Build Coastguard Worker const GAIN_INTERPOLATION_TYPE gainInterpolationType,
290*e5436536SAndroid Build Coastguard Worker const int nNodes, GAIN_NODE* pNodes) {
291*e5436536SAndroid Build Coastguard Worker int k = 0;
292*e5436536SAndroid Build Coastguard Worker
293*e5436536SAndroid Build Coastguard Worker if (gainInterpolationType == GIT_SPLINE) {
294*e5436536SAndroid Build Coastguard Worker /* decode slope steepness */
295*e5436536SAndroid Build Coastguard Worker for (k = 0; k < nNodes; k++) {
296*e5436536SAndroid Build Coastguard Worker _decodeHuffmanCW((Huffman)&slopeSteepness_huffman, hBs);
297*e5436536SAndroid Build Coastguard Worker }
298*e5436536SAndroid Build Coastguard Worker }
299*e5436536SAndroid Build Coastguard Worker }
300*e5436536SAndroid Build Coastguard Worker
_decodeTimeDelta(HANDLE_FDK_BITSTREAM hBs,const int Z)301*e5436536SAndroid Build Coastguard Worker static int _decodeTimeDelta(HANDLE_FDK_BITSTREAM hBs, const int Z) {
302*e5436536SAndroid Build Coastguard Worker int prefix, mu;
303*e5436536SAndroid Build Coastguard Worker
304*e5436536SAndroid Build Coastguard Worker prefix = FDKreadBits(hBs, 2);
305*e5436536SAndroid Build Coastguard Worker switch (prefix) {
306*e5436536SAndroid Build Coastguard Worker case 0x0:
307*e5436536SAndroid Build Coastguard Worker return 1;
308*e5436536SAndroid Build Coastguard Worker case 0x1:
309*e5436536SAndroid Build Coastguard Worker mu = FDKreadBits(hBs, 2);
310*e5436536SAndroid Build Coastguard Worker return mu + 2;
311*e5436536SAndroid Build Coastguard Worker case 0x2:
312*e5436536SAndroid Build Coastguard Worker mu = FDKreadBits(hBs, 3);
313*e5436536SAndroid Build Coastguard Worker return mu + 6;
314*e5436536SAndroid Build Coastguard Worker case 0x3:
315*e5436536SAndroid Build Coastguard Worker mu = FDKreadBits(hBs, Z);
316*e5436536SAndroid Build Coastguard Worker return mu + 14;
317*e5436536SAndroid Build Coastguard Worker default:
318*e5436536SAndroid Build Coastguard Worker return 0;
319*e5436536SAndroid Build Coastguard Worker }
320*e5436536SAndroid Build Coastguard Worker }
321*e5436536SAndroid Build Coastguard Worker
_decodeTimes(HANDLE_FDK_BITSTREAM hBs,const int deltaTmin,const int frameSize,const int fullFrame,const int timeOffset,const int Z,const int nNodes,GAIN_NODE * pNodes)322*e5436536SAndroid Build Coastguard Worker static void _decodeTimes(HANDLE_FDK_BITSTREAM hBs, const int deltaTmin,
323*e5436536SAndroid Build Coastguard Worker const int frameSize, const int fullFrame,
324*e5436536SAndroid Build Coastguard Worker const int timeOffset, const int Z, const int nNodes,
325*e5436536SAndroid Build Coastguard Worker GAIN_NODE* pNodes) {
326*e5436536SAndroid Build Coastguard Worker int timeDelta, k;
327*e5436536SAndroid Build Coastguard Worker int timeOffs = timeOffset;
328*e5436536SAndroid Build Coastguard Worker int frameEndFlag, nodeTimeTmp, nodeResFlag;
329*e5436536SAndroid Build Coastguard Worker
330*e5436536SAndroid Build Coastguard Worker if (fullFrame == 0) {
331*e5436536SAndroid Build Coastguard Worker frameEndFlag = FDKreadBits(hBs, 1);
332*e5436536SAndroid Build Coastguard Worker } else {
333*e5436536SAndroid Build Coastguard Worker frameEndFlag = 1;
334*e5436536SAndroid Build Coastguard Worker }
335*e5436536SAndroid Build Coastguard Worker
336*e5436536SAndroid Build Coastguard Worker if (frameEndFlag ==
337*e5436536SAndroid Build Coastguard Worker 1) { /* frameEndFlag == 1 signals that the last node is at the end of the
338*e5436536SAndroid Build Coastguard Worker DRC frame */
339*e5436536SAndroid Build Coastguard Worker nodeResFlag = 0;
340*e5436536SAndroid Build Coastguard Worker for (k = 0; k < nNodes - 1; k++) {
341*e5436536SAndroid Build Coastguard Worker /* decode a delta time value */
342*e5436536SAndroid Build Coastguard Worker timeDelta = _decodeTimeDelta(hBs, Z);
343*e5436536SAndroid Build Coastguard Worker if (k >= (16 - 1)) continue;
344*e5436536SAndroid Build Coastguard Worker /* frameEndFlag == 1 needs special handling for last node with node
345*e5436536SAndroid Build Coastguard Worker * reservoir */
346*e5436536SAndroid Build Coastguard Worker nodeTimeTmp = timeOffs + timeDelta * deltaTmin;
347*e5436536SAndroid Build Coastguard Worker if (nodeTimeTmp > frameSize + timeOffset) {
348*e5436536SAndroid Build Coastguard Worker if (nodeResFlag == 0) {
349*e5436536SAndroid Build Coastguard Worker pNodes[k].time = frameSize + timeOffset;
350*e5436536SAndroid Build Coastguard Worker nodeResFlag = 1;
351*e5436536SAndroid Build Coastguard Worker }
352*e5436536SAndroid Build Coastguard Worker pNodes[k + 1].time = nodeTimeTmp;
353*e5436536SAndroid Build Coastguard Worker } else {
354*e5436536SAndroid Build Coastguard Worker pNodes[k].time = nodeTimeTmp;
355*e5436536SAndroid Build Coastguard Worker }
356*e5436536SAndroid Build Coastguard Worker timeOffs = nodeTimeTmp;
357*e5436536SAndroid Build Coastguard Worker }
358*e5436536SAndroid Build Coastguard Worker if (nodeResFlag == 0) {
359*e5436536SAndroid Build Coastguard Worker k = fMin(k, 16 - 1);
360*e5436536SAndroid Build Coastguard Worker pNodes[k].time = frameSize + timeOffset;
361*e5436536SAndroid Build Coastguard Worker }
362*e5436536SAndroid Build Coastguard Worker } else {
363*e5436536SAndroid Build Coastguard Worker for (k = 0; k < nNodes; k++) {
364*e5436536SAndroid Build Coastguard Worker /* decode a delta time value */
365*e5436536SAndroid Build Coastguard Worker timeDelta = _decodeTimeDelta(hBs, Z);
366*e5436536SAndroid Build Coastguard Worker if (k >= 16) continue;
367*e5436536SAndroid Build Coastguard Worker pNodes[k].time = timeOffs + timeDelta * deltaTmin;
368*e5436536SAndroid Build Coastguard Worker timeOffs = pNodes[k].time;
369*e5436536SAndroid Build Coastguard Worker }
370*e5436536SAndroid Build Coastguard Worker }
371*e5436536SAndroid Build Coastguard Worker }
372*e5436536SAndroid Build Coastguard Worker
_readNodes(HANDLE_FDK_BITSTREAM hBs,GAIN_SET * gainSet,const int frameSize,const int timeDeltaMin,UCHAR * pNNodes,GAIN_NODE * pNodes)373*e5436536SAndroid Build Coastguard Worker static void _readNodes(HANDLE_FDK_BITSTREAM hBs, GAIN_SET* gainSet,
374*e5436536SAndroid Build Coastguard Worker const int frameSize, const int timeDeltaMin,
375*e5436536SAndroid Build Coastguard Worker UCHAR* pNNodes, GAIN_NODE* pNodes) {
376*e5436536SAndroid Build Coastguard Worker int timeOffset, drcGainCodingMode, nNodes;
377*e5436536SAndroid Build Coastguard Worker int Z = _getZ(frameSize / timeDeltaMin);
378*e5436536SAndroid Build Coastguard Worker if (gainSet->timeAlignment == 0) {
379*e5436536SAndroid Build Coastguard Worker timeOffset = -1;
380*e5436536SAndroid Build Coastguard Worker } else {
381*e5436536SAndroid Build Coastguard Worker timeOffset = -timeDeltaMin +
382*e5436536SAndroid Build Coastguard Worker (timeDeltaMin - 1) /
383*e5436536SAndroid Build Coastguard Worker 2; /* timeOffset = - deltaTmin + floor((deltaTmin-1)/2); */
384*e5436536SAndroid Build Coastguard Worker }
385*e5436536SAndroid Build Coastguard Worker
386*e5436536SAndroid Build Coastguard Worker drcGainCodingMode = FDKreadBits(hBs, 1);
387*e5436536SAndroid Build Coastguard Worker if (drcGainCodingMode == 0) {
388*e5436536SAndroid Build Coastguard Worker /* "simple" mode: only one node at the end of the frame with slope = 0 */
389*e5436536SAndroid Build Coastguard Worker nNodes = 1;
390*e5436536SAndroid Build Coastguard Worker pNodes[0].gainDb = _decodeGainInitial(
391*e5436536SAndroid Build Coastguard Worker hBs, (GAIN_CODING_PROFILE)gainSet->gainCodingProfile);
392*e5436536SAndroid Build Coastguard Worker pNodes[0].time = frameSize + timeOffset;
393*e5436536SAndroid Build Coastguard Worker } else {
394*e5436536SAndroid Build Coastguard Worker nNodes = _decodeNNodes(hBs);
395*e5436536SAndroid Build Coastguard Worker
396*e5436536SAndroid Build Coastguard Worker _decodeSlopes(hBs, (GAIN_INTERPOLATION_TYPE)gainSet->gainInterpolationType,
397*e5436536SAndroid Build Coastguard Worker nNodes, pNodes);
398*e5436536SAndroid Build Coastguard Worker
399*e5436536SAndroid Build Coastguard Worker _decodeTimes(hBs, timeDeltaMin, frameSize, gainSet->fullFrame, timeOffset,
400*e5436536SAndroid Build Coastguard Worker Z, nNodes, pNodes);
401*e5436536SAndroid Build Coastguard Worker
402*e5436536SAndroid Build Coastguard Worker _decodeGains(hBs, (GAIN_CODING_PROFILE)gainSet->gainCodingProfile, nNodes,
403*e5436536SAndroid Build Coastguard Worker pNodes);
404*e5436536SAndroid Build Coastguard Worker }
405*e5436536SAndroid Build Coastguard Worker *pNNodes = (UCHAR)nNodes;
406*e5436536SAndroid Build Coastguard Worker }
407*e5436536SAndroid Build Coastguard Worker
_readDrcGainSequence(HANDLE_FDK_BITSTREAM hBs,GAIN_SET * gainSet,const int frameSize,const int timeDeltaMin,UCHAR * pNNodes,GAIN_NODE pNodes[16])408*e5436536SAndroid Build Coastguard Worker static void _readDrcGainSequence(HANDLE_FDK_BITSTREAM hBs, GAIN_SET* gainSet,
409*e5436536SAndroid Build Coastguard Worker const int frameSize, const int timeDeltaMin,
410*e5436536SAndroid Build Coastguard Worker UCHAR* pNNodes, GAIN_NODE pNodes[16]) {
411*e5436536SAndroid Build Coastguard Worker SHORT timeBufPrevFrame[16], timeBufCurFrame[16];
412*e5436536SAndroid Build Coastguard Worker int nNodesNodeRes, nNodesCur, k, m;
413*e5436536SAndroid Build Coastguard Worker
414*e5436536SAndroid Build Coastguard Worker if (gainSet->gainCodingProfile == GCP_CONSTANT) {
415*e5436536SAndroid Build Coastguard Worker *pNNodes = 1;
416*e5436536SAndroid Build Coastguard Worker pNodes[0].time = frameSize - 1;
417*e5436536SAndroid Build Coastguard Worker pNodes[0].gainDb = (FIXP_SGL)0;
418*e5436536SAndroid Build Coastguard Worker } else {
419*e5436536SAndroid Build Coastguard Worker _readNodes(hBs, gainSet, frameSize, timeDeltaMin, pNNodes, pNodes);
420*e5436536SAndroid Build Coastguard Worker
421*e5436536SAndroid Build Coastguard Worker /* count number of nodes in node reservoir */
422*e5436536SAndroid Build Coastguard Worker nNodesNodeRes = 0;
423*e5436536SAndroid Build Coastguard Worker nNodesCur = 0;
424*e5436536SAndroid Build Coastguard Worker /* count and buffer nodes from node reservoir */
425*e5436536SAndroid Build Coastguard Worker for (k = 0; k < *pNNodes; k++) {
426*e5436536SAndroid Build Coastguard Worker if (k >= 16) continue;
427*e5436536SAndroid Build Coastguard Worker if (pNodes[k].time >= frameSize) {
428*e5436536SAndroid Build Coastguard Worker /* write node reservoir times into buffer */
429*e5436536SAndroid Build Coastguard Worker timeBufPrevFrame[nNodesNodeRes] = pNodes[k].time;
430*e5436536SAndroid Build Coastguard Worker nNodesNodeRes++;
431*e5436536SAndroid Build Coastguard Worker } else { /* times from current frame */
432*e5436536SAndroid Build Coastguard Worker timeBufCurFrame[nNodesCur] = pNodes[k].time;
433*e5436536SAndroid Build Coastguard Worker nNodesCur++;
434*e5436536SAndroid Build Coastguard Worker }
435*e5436536SAndroid Build Coastguard Worker }
436*e5436536SAndroid Build Coastguard Worker /* compose right time order (bit reservoir first) */
437*e5436536SAndroid Build Coastguard Worker for (k = 0; k < nNodesNodeRes; k++) {
438*e5436536SAndroid Build Coastguard Worker /* subtract two time frameSize: one to remove node reservoir offset and
439*e5436536SAndroid Build Coastguard Worker * one to get the negative index relative to the current frame
440*e5436536SAndroid Build Coastguard Worker */
441*e5436536SAndroid Build Coastguard Worker pNodes[k].time = timeBufPrevFrame[k] - 2 * frameSize;
442*e5436536SAndroid Build Coastguard Worker }
443*e5436536SAndroid Build Coastguard Worker /* ...and times from current frame */
444*e5436536SAndroid Build Coastguard Worker for (m = 0; m < nNodesCur; m++, k++) {
445*e5436536SAndroid Build Coastguard Worker pNodes[k].time = timeBufCurFrame[m];
446*e5436536SAndroid Build Coastguard Worker }
447*e5436536SAndroid Build Coastguard Worker }
448*e5436536SAndroid Build Coastguard Worker }
449*e5436536SAndroid Build Coastguard Worker
_readUniDrcGainExtension(HANDLE_FDK_BITSTREAM hBs,UNI_DRC_GAIN_EXTENSION * pExt)450*e5436536SAndroid Build Coastguard Worker static DRC_ERROR _readUniDrcGainExtension(HANDLE_FDK_BITSTREAM hBs,
451*e5436536SAndroid Build Coastguard Worker UNI_DRC_GAIN_EXTENSION* pExt) {
452*e5436536SAndroid Build Coastguard Worker DRC_ERROR err = DE_OK;
453*e5436536SAndroid Build Coastguard Worker int k, bitSizeLen, extSizeBits, bitSize;
454*e5436536SAndroid Build Coastguard Worker
455*e5436536SAndroid Build Coastguard Worker k = 0;
456*e5436536SAndroid Build Coastguard Worker pExt->uniDrcGainExtType[k] = FDKreadBits(hBs, 4);
457*e5436536SAndroid Build Coastguard Worker while (pExt->uniDrcGainExtType[k] != UNIDRCGAINEXT_TERM) {
458*e5436536SAndroid Build Coastguard Worker if (k >= (8 - 1)) return DE_MEMORY_ERROR;
459*e5436536SAndroid Build Coastguard Worker bitSizeLen = FDKreadBits(hBs, 3);
460*e5436536SAndroid Build Coastguard Worker extSizeBits = bitSizeLen + 4;
461*e5436536SAndroid Build Coastguard Worker
462*e5436536SAndroid Build Coastguard Worker bitSize = FDKreadBits(hBs, extSizeBits);
463*e5436536SAndroid Build Coastguard Worker pExt->extBitSize[k] = bitSize + 1;
464*e5436536SAndroid Build Coastguard Worker
465*e5436536SAndroid Build Coastguard Worker switch (pExt->uniDrcGainExtType[k]) {
466*e5436536SAndroid Build Coastguard Worker /* add future extensions here */
467*e5436536SAndroid Build Coastguard Worker default:
468*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, pExt->extBitSize[k]);
469*e5436536SAndroid Build Coastguard Worker break;
470*e5436536SAndroid Build Coastguard Worker }
471*e5436536SAndroid Build Coastguard Worker k++;
472*e5436536SAndroid Build Coastguard Worker pExt->uniDrcGainExtType[k] = FDKreadBits(hBs, 4);
473*e5436536SAndroid Build Coastguard Worker }
474*e5436536SAndroid Build Coastguard Worker
475*e5436536SAndroid Build Coastguard Worker return err;
476*e5436536SAndroid Build Coastguard Worker }
477*e5436536SAndroid Build Coastguard Worker
478*e5436536SAndroid Build Coastguard Worker DRC_ERROR
drcDec_readUniDrcGain(HANDLE_FDK_BITSTREAM hBs,HANDLE_UNI_DRC_CONFIG hUniDrcConfig,const int frameSize,const int deltaTminDefault,HANDLE_UNI_DRC_GAIN hUniDrcGain)479*e5436536SAndroid Build Coastguard Worker drcDec_readUniDrcGain(HANDLE_FDK_BITSTREAM hBs,
480*e5436536SAndroid Build Coastguard Worker HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int frameSize,
481*e5436536SAndroid Build Coastguard Worker const int deltaTminDefault,
482*e5436536SAndroid Build Coastguard Worker HANDLE_UNI_DRC_GAIN hUniDrcGain) {
483*e5436536SAndroid Build Coastguard Worker DRC_ERROR err = DE_OK;
484*e5436536SAndroid Build Coastguard Worker int seq, gainSequenceCount;
485*e5436536SAndroid Build Coastguard Worker DRC_COEFFICIENTS_UNI_DRC* pCoef =
486*e5436536SAndroid Build Coastguard Worker selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
487*e5436536SAndroid Build Coastguard Worker if (hUniDrcGain == NULL) return DE_NOT_OK;
488*e5436536SAndroid Build Coastguard Worker hUniDrcGain->status = 0;
489*e5436536SAndroid Build Coastguard Worker if (pCoef) {
490*e5436536SAndroid Build Coastguard Worker gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);
491*e5436536SAndroid Build Coastguard Worker } else {
492*e5436536SAndroid Build Coastguard Worker gainSequenceCount = 0;
493*e5436536SAndroid Build Coastguard Worker }
494*e5436536SAndroid Build Coastguard Worker
495*e5436536SAndroid Build Coastguard Worker for (seq = 0; seq < gainSequenceCount; seq++) {
496*e5436536SAndroid Build Coastguard Worker UCHAR index = pCoef->gainSetIndexForGainSequence[seq];
497*e5436536SAndroid Build Coastguard Worker GAIN_SET* gainSet;
498*e5436536SAndroid Build Coastguard Worker int timeDeltaMin;
499*e5436536SAndroid Build Coastguard Worker UCHAR tmpNNodes = 0;
500*e5436536SAndroid Build Coastguard Worker GAIN_NODE tmpNodes[16];
501*e5436536SAndroid Build Coastguard Worker
502*e5436536SAndroid Build Coastguard Worker if ((index >= pCoef->gainSetCount) || (index >= 12)) return DE_NOT_OK;
503*e5436536SAndroid Build Coastguard Worker gainSet = &(pCoef->gainSet[index]);
504*e5436536SAndroid Build Coastguard Worker
505*e5436536SAndroid Build Coastguard Worker timeDeltaMin = _getTimeDeltaMin(gainSet, deltaTminDefault);
506*e5436536SAndroid Build Coastguard Worker
507*e5436536SAndroid Build Coastguard Worker _readDrcGainSequence(hBs, gainSet, frameSize, timeDeltaMin, &tmpNNodes,
508*e5436536SAndroid Build Coastguard Worker tmpNodes);
509*e5436536SAndroid Build Coastguard Worker
510*e5436536SAndroid Build Coastguard Worker hUniDrcGain->nNodes[seq] = tmpNNodes;
511*e5436536SAndroid Build Coastguard Worker FDKmemcpy(hUniDrcGain->gainNode[seq], tmpNodes,
512*e5436536SAndroid Build Coastguard Worker fMin(tmpNNodes, (UCHAR)16) * sizeof(GAIN_NODE));
513*e5436536SAndroid Build Coastguard Worker }
514*e5436536SAndroid Build Coastguard Worker
515*e5436536SAndroid Build Coastguard Worker if (pCoef && (gainSequenceCount ==
516*e5436536SAndroid Build Coastguard Worker pCoef->gainSequenceCount)) { /* all sequences have been read */
517*e5436536SAndroid Build Coastguard Worker hUniDrcGain->uniDrcGainExtPresent = FDKreadBits(hBs, 1);
518*e5436536SAndroid Build Coastguard Worker if (hUniDrcGain->uniDrcGainExtPresent == 1) {
519*e5436536SAndroid Build Coastguard Worker err = _readUniDrcGainExtension(hBs, &(hUniDrcGain->uniDrcGainExtension));
520*e5436536SAndroid Build Coastguard Worker if (err) return err;
521*e5436536SAndroid Build Coastguard Worker }
522*e5436536SAndroid Build Coastguard Worker }
523*e5436536SAndroid Build Coastguard Worker
524*e5436536SAndroid Build Coastguard Worker if (err == DE_OK && gainSequenceCount > 0) {
525*e5436536SAndroid Build Coastguard Worker hUniDrcGain->status = 1;
526*e5436536SAndroid Build Coastguard Worker }
527*e5436536SAndroid Build Coastguard Worker return err;
528*e5436536SAndroid Build Coastguard Worker }
529*e5436536SAndroid Build Coastguard Worker
530*e5436536SAndroid Build Coastguard Worker /****************/
531*e5436536SAndroid Build Coastguard Worker /* uniDrcConfig */
532*e5436536SAndroid Build Coastguard Worker /****************/
533*e5436536SAndroid Build Coastguard Worker
_decodeDuckingModification(HANDLE_FDK_BITSTREAM hBs,DUCKING_MODIFICATION * pDMod,int isBox)534*e5436536SAndroid Build Coastguard Worker static void _decodeDuckingModification(HANDLE_FDK_BITSTREAM hBs,
535*e5436536SAndroid Build Coastguard Worker DUCKING_MODIFICATION* pDMod, int isBox) {
536*e5436536SAndroid Build Coastguard Worker int bsDuckingScaling, sigma, mu;
537*e5436536SAndroid Build Coastguard Worker
538*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 7); /* reserved */
539*e5436536SAndroid Build Coastguard Worker pDMod->duckingScalingPresent = FDKreadBits(hBs, 1);
540*e5436536SAndroid Build Coastguard Worker
541*e5436536SAndroid Build Coastguard Worker if (pDMod->duckingScalingPresent) {
542*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 4); /* reserved */
543*e5436536SAndroid Build Coastguard Worker bsDuckingScaling = FDKreadBits(hBs, 4);
544*e5436536SAndroid Build Coastguard Worker sigma = bsDuckingScaling >> 3;
545*e5436536SAndroid Build Coastguard Worker mu = bsDuckingScaling & 0x7;
546*e5436536SAndroid Build Coastguard Worker
547*e5436536SAndroid Build Coastguard Worker if (sigma) {
548*e5436536SAndroid Build Coastguard Worker pDMod->duckingScaling = (FIXP_SGL)(
549*e5436536SAndroid Build Coastguard Worker (7 - mu) << (FRACT_BITS - 1 - 3 - 2)); /* 1.0 - 0.125 * (1 + mu); */
550*e5436536SAndroid Build Coastguard Worker } else {
551*e5436536SAndroid Build Coastguard Worker pDMod->duckingScaling = (FIXP_SGL)(
552*e5436536SAndroid Build Coastguard Worker (9 + mu) << (FRACT_BITS - 1 - 3 - 2)); /* 1.0 + 0.125 * (1 + mu); */
553*e5436536SAndroid Build Coastguard Worker }
554*e5436536SAndroid Build Coastguard Worker } else {
555*e5436536SAndroid Build Coastguard Worker pDMod->duckingScaling = (FIXP_SGL)(1 << (FRACT_BITS - 1 - 2)); /* 1.0 */
556*e5436536SAndroid Build Coastguard Worker }
557*e5436536SAndroid Build Coastguard Worker }
558*e5436536SAndroid Build Coastguard Worker
_decodeGainModification(HANDLE_FDK_BITSTREAM hBs,const int version,int bandCount,GAIN_MODIFICATION * pGMod,int isBox)559*e5436536SAndroid Build Coastguard Worker static void _decodeGainModification(HANDLE_FDK_BITSTREAM hBs, const int version,
560*e5436536SAndroid Build Coastguard Worker int bandCount, GAIN_MODIFICATION* pGMod,
561*e5436536SAndroid Build Coastguard Worker int isBox) {
562*e5436536SAndroid Build Coastguard Worker int sign, bsGainOffset, bsAttenuationScaling, bsAmplificationScaling;
563*e5436536SAndroid Build Coastguard Worker
564*e5436536SAndroid Build Coastguard Worker if (version > 0) {
565*e5436536SAndroid Build Coastguard Worker int b, shapeFilterPresent;
566*e5436536SAndroid Build Coastguard Worker
567*e5436536SAndroid Build Coastguard Worker if (isBox) {
568*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 4); /* reserved */
569*e5436536SAndroid Build Coastguard Worker bandCount = FDKreadBits(hBs, 4);
570*e5436536SAndroid Build Coastguard Worker }
571*e5436536SAndroid Build Coastguard Worker
572*e5436536SAndroid Build Coastguard Worker for (b = 0; b < bandCount; b++) {
573*e5436536SAndroid Build Coastguard Worker if (isBox) {
574*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 4); /* reserved */
575*e5436536SAndroid Build Coastguard Worker pGMod[b].targetCharacteristicLeftPresent = FDKreadBits(hBs, 1);
576*e5436536SAndroid Build Coastguard Worker pGMod[b].targetCharacteristicRightPresent = FDKreadBits(hBs, 1);
577*e5436536SAndroid Build Coastguard Worker pGMod[b].gainScalingPresent = FDKreadBits(hBs, 1);
578*e5436536SAndroid Build Coastguard Worker pGMod[b].gainOffsetPresent = FDKreadBits(hBs, 1);
579*e5436536SAndroid Build Coastguard Worker }
580*e5436536SAndroid Build Coastguard Worker
581*e5436536SAndroid Build Coastguard Worker if (!isBox)
582*e5436536SAndroid Build Coastguard Worker pGMod[b].targetCharacteristicLeftPresent = FDKreadBits(hBs, 1);
583*e5436536SAndroid Build Coastguard Worker if (pGMod[b].targetCharacteristicLeftPresent) {
584*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 4); /* reserved */
585*e5436536SAndroid Build Coastguard Worker pGMod[b].targetCharacteristicLeftIndex = FDKreadBits(hBs, 4);
586*e5436536SAndroid Build Coastguard Worker }
587*e5436536SAndroid Build Coastguard Worker if (!isBox)
588*e5436536SAndroid Build Coastguard Worker pGMod[b].targetCharacteristicRightPresent = FDKreadBits(hBs, 1);
589*e5436536SAndroid Build Coastguard Worker if (pGMod[b].targetCharacteristicRightPresent) {
590*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 4); /* reserved */
591*e5436536SAndroid Build Coastguard Worker pGMod[b].targetCharacteristicRightIndex = FDKreadBits(hBs, 4);
592*e5436536SAndroid Build Coastguard Worker }
593*e5436536SAndroid Build Coastguard Worker if (!isBox) pGMod[b].gainScalingPresent = FDKreadBits(hBs, 1);
594*e5436536SAndroid Build Coastguard Worker if (pGMod[b].gainScalingPresent) {
595*e5436536SAndroid Build Coastguard Worker bsAttenuationScaling = FDKreadBits(hBs, 4);
596*e5436536SAndroid Build Coastguard Worker pGMod[b].attenuationScaling = (FIXP_SGL)(
597*e5436536SAndroid Build Coastguard Worker bsAttenuationScaling
598*e5436536SAndroid Build Coastguard Worker << (FRACT_BITS - 1 - 3 - 2)); /* bsAttenuationScaling * 0.125; */
599*e5436536SAndroid Build Coastguard Worker bsAmplificationScaling = FDKreadBits(hBs, 4);
600*e5436536SAndroid Build Coastguard Worker pGMod[b].amplificationScaling = (FIXP_SGL)(
601*e5436536SAndroid Build Coastguard Worker bsAmplificationScaling
602*e5436536SAndroid Build Coastguard Worker << (FRACT_BITS - 1 - 3 - 2)); /* bsAmplificationScaling * 0.125; */
603*e5436536SAndroid Build Coastguard Worker }
604*e5436536SAndroid Build Coastguard Worker if (!isBox) pGMod[b].gainOffsetPresent = FDKreadBits(hBs, 1);
605*e5436536SAndroid Build Coastguard Worker if (pGMod[b].gainOffsetPresent) {
606*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 2); /* reserved */
607*e5436536SAndroid Build Coastguard Worker sign = FDKreadBits(hBs, 1);
608*e5436536SAndroid Build Coastguard Worker bsGainOffset = FDKreadBits(hBs, 5);
609*e5436536SAndroid Build Coastguard Worker pGMod[b].gainOffset = (FIXP_SGL)(
610*e5436536SAndroid Build Coastguard Worker (1 + bsGainOffset)
611*e5436536SAndroid Build Coastguard Worker << (FRACT_BITS - 1 - 2 - 4)); /* (1+bsGainOffset) * 0.25; */
612*e5436536SAndroid Build Coastguard Worker if (sign) {
613*e5436536SAndroid Build Coastguard Worker pGMod[b].gainOffset = -pGMod[b].gainOffset;
614*e5436536SAndroid Build Coastguard Worker }
615*e5436536SAndroid Build Coastguard Worker }
616*e5436536SAndroid Build Coastguard Worker }
617*e5436536SAndroid Build Coastguard Worker if (bandCount == 1) {
618*e5436536SAndroid Build Coastguard Worker shapeFilterPresent = FDKreadBits(hBs, 1);
619*e5436536SAndroid Build Coastguard Worker if (shapeFilterPresent) {
620*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 3); /* reserved */
621*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 4); /* pGMod->shapeFilterIndex */
622*e5436536SAndroid Build Coastguard Worker } else {
623*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 7); /* reserved */
624*e5436536SAndroid Build Coastguard Worker }
625*e5436536SAndroid Build Coastguard Worker }
626*e5436536SAndroid Build Coastguard Worker } else {
627*e5436536SAndroid Build Coastguard Worker int b, gainScalingPresent, gainOffsetPresent;
628*e5436536SAndroid Build Coastguard Worker FIXP_SGL attenuationScaling = FL2FXCONST_SGL(1.0f / (float)(1 << 2)),
629*e5436536SAndroid Build Coastguard Worker amplificationScaling = FL2FXCONST_SGL(1.0f / (float)(1 << 2)),
630*e5436536SAndroid Build Coastguard Worker gainOffset = (FIXP_SGL)0;
631*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 7); /* reserved */
632*e5436536SAndroid Build Coastguard Worker gainScalingPresent = FDKreadBits(hBs, 1);
633*e5436536SAndroid Build Coastguard Worker if (gainScalingPresent) {
634*e5436536SAndroid Build Coastguard Worker bsAttenuationScaling = FDKreadBits(hBs, 4);
635*e5436536SAndroid Build Coastguard Worker attenuationScaling = (FIXP_SGL)(
636*e5436536SAndroid Build Coastguard Worker bsAttenuationScaling
637*e5436536SAndroid Build Coastguard Worker << (FRACT_BITS - 1 - 3 - 2)); /* bsAttenuationScaling * 0.125; */
638*e5436536SAndroid Build Coastguard Worker bsAmplificationScaling = FDKreadBits(hBs, 4);
639*e5436536SAndroid Build Coastguard Worker amplificationScaling = (FIXP_SGL)(
640*e5436536SAndroid Build Coastguard Worker bsAmplificationScaling
641*e5436536SAndroid Build Coastguard Worker << (FRACT_BITS - 1 - 3 - 2)); /* bsAmplificationScaling * 0.125; */
642*e5436536SAndroid Build Coastguard Worker }
643*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 7); /* reserved */
644*e5436536SAndroid Build Coastguard Worker gainOffsetPresent = FDKreadBits(hBs, 1);
645*e5436536SAndroid Build Coastguard Worker if (gainOffsetPresent) {
646*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 2); /* reserved */
647*e5436536SAndroid Build Coastguard Worker sign = FDKreadBits(hBs, 1);
648*e5436536SAndroid Build Coastguard Worker bsGainOffset = FDKreadBits(hBs, 5);
649*e5436536SAndroid Build Coastguard Worker gainOffset =
650*e5436536SAndroid Build Coastguard Worker (FIXP_SGL)((1 + bsGainOffset) << (FRACT_BITS - 1 - 2 -
651*e5436536SAndroid Build Coastguard Worker 4)); /* (1+bsGainOffset) * 0.25; */
652*e5436536SAndroid Build Coastguard Worker if (sign) {
653*e5436536SAndroid Build Coastguard Worker gainOffset = -gainOffset;
654*e5436536SAndroid Build Coastguard Worker }
655*e5436536SAndroid Build Coastguard Worker }
656*e5436536SAndroid Build Coastguard Worker for (b = 0; b < 4; b++) {
657*e5436536SAndroid Build Coastguard Worker pGMod[b].targetCharacteristicLeftPresent = 0;
658*e5436536SAndroid Build Coastguard Worker pGMod[b].targetCharacteristicRightPresent = 0;
659*e5436536SAndroid Build Coastguard Worker pGMod[b].gainScalingPresent = gainScalingPresent;
660*e5436536SAndroid Build Coastguard Worker pGMod[b].attenuationScaling = attenuationScaling;
661*e5436536SAndroid Build Coastguard Worker pGMod[b].amplificationScaling = amplificationScaling;
662*e5436536SAndroid Build Coastguard Worker pGMod[b].gainOffsetPresent = gainOffsetPresent;
663*e5436536SAndroid Build Coastguard Worker pGMod[b].gainOffset = gainOffset;
664*e5436536SAndroid Build Coastguard Worker }
665*e5436536SAndroid Build Coastguard Worker }
666*e5436536SAndroid Build Coastguard Worker }
667*e5436536SAndroid Build Coastguard Worker
_readDrcCharacteristic(HANDLE_FDK_BITSTREAM hBs,const int version,DRC_CHARACTERISTIC * pDChar,int isBox)668*e5436536SAndroid Build Coastguard Worker static void _readDrcCharacteristic(HANDLE_FDK_BITSTREAM hBs, const int version,
669*e5436536SAndroid Build Coastguard Worker DRC_CHARACTERISTIC* pDChar, int isBox) {
670*e5436536SAndroid Build Coastguard Worker if (version == 0) {
671*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 1); /* reserved */
672*e5436536SAndroid Build Coastguard Worker pDChar->cicpIndex = FDKreadBits(hBs, 7);
673*e5436536SAndroid Build Coastguard Worker if (pDChar->cicpIndex > 0) {
674*e5436536SAndroid Build Coastguard Worker pDChar->present = 1;
675*e5436536SAndroid Build Coastguard Worker pDChar->isCICP = 1;
676*e5436536SAndroid Build Coastguard Worker } else {
677*e5436536SAndroid Build Coastguard Worker pDChar->present = 0;
678*e5436536SAndroid Build Coastguard Worker }
679*e5436536SAndroid Build Coastguard Worker } else {
680*e5436536SAndroid Build Coastguard Worker pDChar->present = FDKreadBits(hBs, 1);
681*e5436536SAndroid Build Coastguard Worker if (isBox) pDChar->isCICP = FDKreadBits(hBs, 1);
682*e5436536SAndroid Build Coastguard Worker if (pDChar->present) {
683*e5436536SAndroid Build Coastguard Worker if (!isBox) pDChar->isCICP = FDKreadBits(hBs, 1);
684*e5436536SAndroid Build Coastguard Worker if (pDChar->isCICP) {
685*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 1); /* reserved */
686*e5436536SAndroid Build Coastguard Worker pDChar->cicpIndex = FDKreadBits(hBs, 7);
687*e5436536SAndroid Build Coastguard Worker } else {
688*e5436536SAndroid Build Coastguard Worker pDChar->custom.left = FDKreadBits(hBs, 4);
689*e5436536SAndroid Build Coastguard Worker pDChar->custom.right = FDKreadBits(hBs, 4);
690*e5436536SAndroid Build Coastguard Worker }
691*e5436536SAndroid Build Coastguard Worker }
692*e5436536SAndroid Build Coastguard Worker }
693*e5436536SAndroid Build Coastguard Worker }
694*e5436536SAndroid Build Coastguard Worker
_readBandBorder(HANDLE_FDK_BITSTREAM hBs,BAND_BORDER * pBBord,int drcBandType,int isBox)695*e5436536SAndroid Build Coastguard Worker static void _readBandBorder(HANDLE_FDK_BITSTREAM hBs, BAND_BORDER* pBBord,
696*e5436536SAndroid Build Coastguard Worker int drcBandType, int isBox) {
697*e5436536SAndroid Build Coastguard Worker if (drcBandType) {
698*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 4); /* reserved */
699*e5436536SAndroid Build Coastguard Worker pBBord->crossoverFreqIndex = FDKreadBits(hBs, 4);
700*e5436536SAndroid Build Coastguard Worker } else {
701*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 6); /* reserved */
702*e5436536SAndroid Build Coastguard Worker pBBord->startSubBandIndex = FDKreadBits(hBs, 10);
703*e5436536SAndroid Build Coastguard Worker }
704*e5436536SAndroid Build Coastguard Worker }
705*e5436536SAndroid Build Coastguard Worker
_readGainSet(HANDLE_FDK_BITSTREAM hBs,const int version,int * gainSequenceIndex,GAIN_SET * pGSet,int isBox)706*e5436536SAndroid Build Coastguard Worker static DRC_ERROR _readGainSet(HANDLE_FDK_BITSTREAM hBs, const int version,
707*e5436536SAndroid Build Coastguard Worker int* gainSequenceIndex, GAIN_SET* pGSet,
708*e5436536SAndroid Build Coastguard Worker int isBox) {
709*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 2); /* reserved */
710*e5436536SAndroid Build Coastguard Worker pGSet->gainCodingProfile = FDKreadBits(hBs, 2);
711*e5436536SAndroid Build Coastguard Worker pGSet->gainInterpolationType = FDKreadBits(hBs, 1);
712*e5436536SAndroid Build Coastguard Worker pGSet->fullFrame = FDKreadBits(hBs, 1);
713*e5436536SAndroid Build Coastguard Worker pGSet->timeAlignment = FDKreadBits(hBs, 1);
714*e5436536SAndroid Build Coastguard Worker pGSet->timeDeltaMinPresent = FDKreadBits(hBs, 1);
715*e5436536SAndroid Build Coastguard Worker
716*e5436536SAndroid Build Coastguard Worker if (pGSet->timeDeltaMinPresent) {
717*e5436536SAndroid Build Coastguard Worker int bsTimeDeltaMin;
718*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 5); /* reserved */
719*e5436536SAndroid Build Coastguard Worker bsTimeDeltaMin = FDKreadBits(hBs, 11);
720*e5436536SAndroid Build Coastguard Worker pGSet->timeDeltaMin = bsTimeDeltaMin + 1;
721*e5436536SAndroid Build Coastguard Worker }
722*e5436536SAndroid Build Coastguard Worker
723*e5436536SAndroid Build Coastguard Worker if (pGSet->gainCodingProfile != GCP_CONSTANT) {
724*e5436536SAndroid Build Coastguard Worker int i;
725*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 3); /* reserved */
726*e5436536SAndroid Build Coastguard Worker pGSet->bandCount = FDKreadBits(hBs, 4);
727*e5436536SAndroid Build Coastguard Worker if (pGSet->bandCount > 4) return DE_MEMORY_ERROR;
728*e5436536SAndroid Build Coastguard Worker
729*e5436536SAndroid Build Coastguard Worker if ((pGSet->bandCount > 1) || isBox) {
730*e5436536SAndroid Build Coastguard Worker pGSet->drcBandType = FDKreadBits(hBs, 1);
731*e5436536SAndroid Build Coastguard Worker }
732*e5436536SAndroid Build Coastguard Worker
733*e5436536SAndroid Build Coastguard Worker for (i = 0; i < pGSet->bandCount; i++) {
734*e5436536SAndroid Build Coastguard Worker if (version == 0) {
735*e5436536SAndroid Build Coastguard Worker *gainSequenceIndex = (*gainSequenceIndex) + 1;
736*e5436536SAndroid Build Coastguard Worker } else {
737*e5436536SAndroid Build Coastguard Worker int indexPresent;
738*e5436536SAndroid Build Coastguard Worker indexPresent = (isBox) ? 1 : FDKreadBits(hBs, 1);
739*e5436536SAndroid Build Coastguard Worker if (indexPresent) {
740*e5436536SAndroid Build Coastguard Worker int bsIndex;
741*e5436536SAndroid Build Coastguard Worker bsIndex = FDKreadBits(hBs, 6);
742*e5436536SAndroid Build Coastguard Worker *gainSequenceIndex = bsIndex;
743*e5436536SAndroid Build Coastguard Worker } else {
744*e5436536SAndroid Build Coastguard Worker *gainSequenceIndex = (*gainSequenceIndex) + 1;
745*e5436536SAndroid Build Coastguard Worker }
746*e5436536SAndroid Build Coastguard Worker }
747*e5436536SAndroid Build Coastguard Worker pGSet->gainSequenceIndex[i] = *gainSequenceIndex;
748*e5436536SAndroid Build Coastguard Worker _readDrcCharacteristic(hBs, version, &(pGSet->drcCharacteristic[i]),
749*e5436536SAndroid Build Coastguard Worker isBox);
750*e5436536SAndroid Build Coastguard Worker }
751*e5436536SAndroid Build Coastguard Worker for (i = 1; i < pGSet->bandCount; i++) {
752*e5436536SAndroid Build Coastguard Worker _readBandBorder(hBs, &(pGSet->bandBorder[i]), pGSet->drcBandType, isBox);
753*e5436536SAndroid Build Coastguard Worker }
754*e5436536SAndroid Build Coastguard Worker } else {
755*e5436536SAndroid Build Coastguard Worker pGSet->bandCount = 1;
756*e5436536SAndroid Build Coastguard Worker *gainSequenceIndex = (*gainSequenceIndex) + 1;
757*e5436536SAndroid Build Coastguard Worker pGSet->gainSequenceIndex[0] = *gainSequenceIndex;
758*e5436536SAndroid Build Coastguard Worker }
759*e5436536SAndroid Build Coastguard Worker
760*e5436536SAndroid Build Coastguard Worker return DE_OK;
761*e5436536SAndroid Build Coastguard Worker }
762*e5436536SAndroid Build Coastguard Worker
_readCustomDrcCharacteristic(HANDLE_FDK_BITSTREAM hBs,const CHARACTERISTIC_SIDE side,UCHAR * pCharacteristicFormat,CUSTOM_DRC_CHAR * pCChar,int isBox)763*e5436536SAndroid Build Coastguard Worker static DRC_ERROR _readCustomDrcCharacteristic(HANDLE_FDK_BITSTREAM hBs,
764*e5436536SAndroid Build Coastguard Worker const CHARACTERISTIC_SIDE side,
765*e5436536SAndroid Build Coastguard Worker UCHAR* pCharacteristicFormat,
766*e5436536SAndroid Build Coastguard Worker CUSTOM_DRC_CHAR* pCChar,
767*e5436536SAndroid Build Coastguard Worker int isBox) {
768*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 7); /* reserved */
769*e5436536SAndroid Build Coastguard Worker *pCharacteristicFormat = FDKreadBits(hBs, 1);
770*e5436536SAndroid Build Coastguard Worker if (*pCharacteristicFormat == CF_SIGMOID) {
771*e5436536SAndroid Build Coastguard Worker int bsGain, bsIoRatio, bsExp;
772*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 1); /* reserved */
773*e5436536SAndroid Build Coastguard Worker bsGain = FDKreadBits(hBs, 6);
774*e5436536SAndroid Build Coastguard Worker if (side == CS_LEFT) {
775*e5436536SAndroid Build Coastguard Worker pCChar->sigmoid.gain = (FIXP_SGL)(bsGain << (FRACT_BITS - 1 - 6));
776*e5436536SAndroid Build Coastguard Worker } else {
777*e5436536SAndroid Build Coastguard Worker pCChar->sigmoid.gain = (FIXP_SGL)(-bsGain << (FRACT_BITS - 1 - 6));
778*e5436536SAndroid Build Coastguard Worker }
779*e5436536SAndroid Build Coastguard Worker bsIoRatio = FDKreadBits(hBs, 4);
780*e5436536SAndroid Build Coastguard Worker /* pCChar->sigmoid.ioRatio = 0.05 + 0.15 * bsIoRatio; */
781*e5436536SAndroid Build Coastguard Worker pCChar->sigmoid.ioRatio =
782*e5436536SAndroid Build Coastguard Worker FL2FXCONST_SGL(0.05f / (float)(1 << 2)) +
783*e5436536SAndroid Build Coastguard Worker (FIXP_SGL)((((3 * bsIoRatio) << (FRACT_BITS - 1)) / 5) >> 4);
784*e5436536SAndroid Build Coastguard Worker bsExp = FDKreadBits(hBs, 4);
785*e5436536SAndroid Build Coastguard Worker if (bsExp < 15) {
786*e5436536SAndroid Build Coastguard Worker pCChar->sigmoid.exp = (FIXP_SGL)((1 + 2 * bsExp) << (FRACT_BITS - 1 - 5));
787*e5436536SAndroid Build Coastguard Worker } else {
788*e5436536SAndroid Build Coastguard Worker pCChar->sigmoid.exp = (FIXP_SGL)MAXVAL_SGL; /* represents infinity */
789*e5436536SAndroid Build Coastguard Worker }
790*e5436536SAndroid Build Coastguard Worker pCChar->sigmoid.flipSign = FDKreadBits(hBs, 1);
791*e5436536SAndroid Build Coastguard Worker } else { /* CF_NODES */
792*e5436536SAndroid Build Coastguard Worker int i, bsCharacteristicNodeCount, bsNodeLevelDelta, bsNodeGain;
793*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 6); /* reserved */
794*e5436536SAndroid Build Coastguard Worker bsCharacteristicNodeCount = FDKreadBits(hBs, 2);
795*e5436536SAndroid Build Coastguard Worker pCChar->nodes.characteristicNodeCount = bsCharacteristicNodeCount + 1;
796*e5436536SAndroid Build Coastguard Worker if (pCChar->nodes.characteristicNodeCount > 4) return DE_MEMORY_ERROR;
797*e5436536SAndroid Build Coastguard Worker pCChar->nodes.nodeLevel[0] = DRC_INPUT_LOUDNESS_TARGET_SGL;
798*e5436536SAndroid Build Coastguard Worker pCChar->nodes.nodeGain[0] = (FIXP_SGL)0;
799*e5436536SAndroid Build Coastguard Worker for (i = 0; i < pCChar->nodes.characteristicNodeCount; i++) {
800*e5436536SAndroid Build Coastguard Worker if (isBox) FDKpushFor(hBs, 3); /* reserved */
801*e5436536SAndroid Build Coastguard Worker bsNodeLevelDelta = FDKreadBits(hBs, 5);
802*e5436536SAndroid Build Coastguard Worker if (side == CS_LEFT) {
803*e5436536SAndroid Build Coastguard Worker pCChar->nodes.nodeLevel[i + 1] =
804*e5436536SAndroid Build Coastguard Worker pCChar->nodes.nodeLevel[i] -
805*e5436536SAndroid Build Coastguard Worker (FIXP_SGL)((1 + bsNodeLevelDelta) << (FRACT_BITS - 1 - 7));
806*e5436536SAndroid Build Coastguard Worker } else {
807*e5436536SAndroid Build Coastguard Worker pCChar->nodes.nodeLevel[i + 1] =
808*e5436536SAndroid Build Coastguard Worker pCChar->nodes.nodeLevel[i] +
809*e5436536SAndroid Build Coastguard Worker (FIXP_SGL)((1 + bsNodeLevelDelta) << (FRACT_BITS - 1 - 7));
810*e5436536SAndroid Build Coastguard Worker }
811*e5436536SAndroid Build Coastguard Worker bsNodeGain = FDKreadBits(hBs, 8);
812*e5436536SAndroid Build Coastguard Worker pCChar->nodes.nodeGain[i + 1] = (FIXP_SGL)(
813*e5436536SAndroid Build Coastguard Worker (bsNodeGain - 128)
814*e5436536SAndroid Build Coastguard Worker << (FRACT_BITS - 1 - 1 - 7)); /* 0.5f * bsNodeGain - 64.0f; */
815*e5436536SAndroid Build Coastguard Worker }
816*e5436536SAndroid Build Coastguard Worker }
817*e5436536SAndroid Build Coastguard Worker return DE_OK;
818*e5436536SAndroid Build Coastguard Worker }
819*e5436536SAndroid Build Coastguard Worker
_skipLoudEqInstructions(HANDLE_FDK_BITSTREAM hBs)820*e5436536SAndroid Build Coastguard Worker static void _skipLoudEqInstructions(HANDLE_FDK_BITSTREAM hBs) {
821*e5436536SAndroid Build Coastguard Worker int i;
822*e5436536SAndroid Build Coastguard Worker int downmixIdPresent, additionalDownmixIdPresent,
823*e5436536SAndroid Build Coastguard Worker additionalDownmixIdCount = 0;
824*e5436536SAndroid Build Coastguard Worker int drcSetIdPresent, additionalDrcSetIdPresent, additionalDrcSetIdCount = 0;
825*e5436536SAndroid Build Coastguard Worker int eqSetIdPresent, additionalEqSetIdPresent, additionalEqSetIdCount = 0;
826*e5436536SAndroid Build Coastguard Worker int loudEqGainSequenceCount, drcCharacteristicFormatIsCICP;
827*e5436536SAndroid Build Coastguard Worker
828*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 4); /* loudEqSetId */
829*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 4); /* drcLocation */
830*e5436536SAndroid Build Coastguard Worker downmixIdPresent = FDKreadBits(hBs, 1);
831*e5436536SAndroid Build Coastguard Worker if (downmixIdPresent) {
832*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 7); /* downmixId */
833*e5436536SAndroid Build Coastguard Worker additionalDownmixIdPresent = FDKreadBits(hBs, 1);
834*e5436536SAndroid Build Coastguard Worker if (additionalDownmixIdPresent) {
835*e5436536SAndroid Build Coastguard Worker additionalDownmixIdCount = FDKreadBits(hBs, 7);
836*e5436536SAndroid Build Coastguard Worker for (i = 0; i < additionalDownmixIdCount; i++) {
837*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 7); /* additionalDownmixId */
838*e5436536SAndroid Build Coastguard Worker }
839*e5436536SAndroid Build Coastguard Worker }
840*e5436536SAndroid Build Coastguard Worker }
841*e5436536SAndroid Build Coastguard Worker
842*e5436536SAndroid Build Coastguard Worker drcSetIdPresent = FDKreadBits(hBs, 1);
843*e5436536SAndroid Build Coastguard Worker if (drcSetIdPresent) {
844*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 6); /* drcSetId */
845*e5436536SAndroid Build Coastguard Worker additionalDrcSetIdPresent = FDKreadBits(hBs, 1);
846*e5436536SAndroid Build Coastguard Worker if (additionalDrcSetIdPresent) {
847*e5436536SAndroid Build Coastguard Worker additionalDrcSetIdCount = FDKreadBits(hBs, 6);
848*e5436536SAndroid Build Coastguard Worker for (i = 0; i < additionalDrcSetIdCount; i++) {
849*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 6); /* additionalDrcSetId; */
850*e5436536SAndroid Build Coastguard Worker }
851*e5436536SAndroid Build Coastguard Worker }
852*e5436536SAndroid Build Coastguard Worker }
853*e5436536SAndroid Build Coastguard Worker
854*e5436536SAndroid Build Coastguard Worker eqSetIdPresent = FDKreadBits(hBs, 1);
855*e5436536SAndroid Build Coastguard Worker if (eqSetIdPresent) {
856*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 6); /* eqSetId */
857*e5436536SAndroid Build Coastguard Worker additionalEqSetIdPresent = FDKreadBits(hBs, 1);
858*e5436536SAndroid Build Coastguard Worker if (additionalEqSetIdPresent) {
859*e5436536SAndroid Build Coastguard Worker additionalEqSetIdCount = FDKreadBits(hBs, 6);
860*e5436536SAndroid Build Coastguard Worker for (i = 0; i < additionalEqSetIdCount; i++) {
861*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 6); /* additionalEqSetId; */
862*e5436536SAndroid Build Coastguard Worker }
863*e5436536SAndroid Build Coastguard Worker }
864*e5436536SAndroid Build Coastguard Worker }
865*e5436536SAndroid Build Coastguard Worker
866*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 1); /* loudnessAfterDrc */
867*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 1); /* loudnessAfterEq */
868*e5436536SAndroid Build Coastguard Worker loudEqGainSequenceCount = FDKreadBits(hBs, 6);
869*e5436536SAndroid Build Coastguard Worker for (i = 0; i < loudEqGainSequenceCount; i++) {
870*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 6); /* gainSequenceIndex */
871*e5436536SAndroid Build Coastguard Worker drcCharacteristicFormatIsCICP = FDKreadBits(hBs, 1);
872*e5436536SAndroid Build Coastguard Worker if (drcCharacteristicFormatIsCICP) {
873*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 7); /* drcCharacteristic */
874*e5436536SAndroid Build Coastguard Worker } else {
875*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 4); /* drcCharacteristicLeftIndex */
876*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 4); /* drcCharacteristicRightIndex */
877*e5436536SAndroid Build Coastguard Worker }
878*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 6); /* frequencyRangeIndex */
879*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 3); /* bsLoudEqScaling */
880*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 5); /* bsLoudEqOffset */
881*e5436536SAndroid Build Coastguard Worker }
882*e5436536SAndroid Build Coastguard Worker }
883*e5436536SAndroid Build Coastguard Worker
_skipEqSubbandGainSpline(HANDLE_FDK_BITSTREAM hBs)884*e5436536SAndroid Build Coastguard Worker static void _skipEqSubbandGainSpline(HANDLE_FDK_BITSTREAM hBs) {
885*e5436536SAndroid Build Coastguard Worker int nEqNodes, k, bits;
886*e5436536SAndroid Build Coastguard Worker nEqNodes = FDKreadBits(hBs, 5);
887*e5436536SAndroid Build Coastguard Worker nEqNodes += 2;
888*e5436536SAndroid Build Coastguard Worker for (k = 0; k < nEqNodes; k++) {
889*e5436536SAndroid Build Coastguard Worker bits = FDKreadBits(hBs, 1);
890*e5436536SAndroid Build Coastguard Worker if (!bits) {
891*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 4);
892*e5436536SAndroid Build Coastguard Worker }
893*e5436536SAndroid Build Coastguard Worker }
894*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 4 * (nEqNodes - 1));
895*e5436536SAndroid Build Coastguard Worker bits = FDKreadBits(hBs, 2);
896*e5436536SAndroid Build Coastguard Worker switch (bits) {
897*e5436536SAndroid Build Coastguard Worker case 0:
898*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 5);
899*e5436536SAndroid Build Coastguard Worker break;
900*e5436536SAndroid Build Coastguard Worker case 1:
901*e5436536SAndroid Build Coastguard Worker case 2:
902*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 4);
903*e5436536SAndroid Build Coastguard Worker break;
904*e5436536SAndroid Build Coastguard Worker case 3:
905*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 3);
906*e5436536SAndroid Build Coastguard Worker break;
907*e5436536SAndroid Build Coastguard Worker }
908*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 5 * (nEqNodes - 1));
909*e5436536SAndroid Build Coastguard Worker }
910*e5436536SAndroid Build Coastguard Worker
_skipEqCoefficients(HANDLE_FDK_BITSTREAM hBs)911*e5436536SAndroid Build Coastguard Worker static void _skipEqCoefficients(HANDLE_FDK_BITSTREAM hBs) {
912*e5436536SAndroid Build Coastguard Worker int j, k;
913*e5436536SAndroid Build Coastguard Worker int eqDelayMaxPresent;
914*e5436536SAndroid Build Coastguard Worker int uniqueFilterBlockCount, filterElementCount, filterElementGainPresent;
915*e5436536SAndroid Build Coastguard Worker int uniqueTdFilterElementCount, eqFilterFormat, bsRealZeroRadiusOneCount,
916*e5436536SAndroid Build Coastguard Worker realZeroCount, genericZeroCount, realPoleCount, complexPoleCount,
917*e5436536SAndroid Build Coastguard Worker firFilterOrder;
918*e5436536SAndroid Build Coastguard Worker int uniqueEqSubbandGainsCount, eqSubbandGainRepresentation,
919*e5436536SAndroid Build Coastguard Worker eqSubbandGainCount;
920*e5436536SAndroid Build Coastguard Worker int eqSubbandGainFormat;
921*e5436536SAndroid Build Coastguard Worker
922*e5436536SAndroid Build Coastguard Worker eqDelayMaxPresent = FDKreadBits(hBs, 1);
923*e5436536SAndroid Build Coastguard Worker if (eqDelayMaxPresent) {
924*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 8); /* bsEqDelayMax */
925*e5436536SAndroid Build Coastguard Worker }
926*e5436536SAndroid Build Coastguard Worker
927*e5436536SAndroid Build Coastguard Worker uniqueFilterBlockCount = FDKreadBits(hBs, 6);
928*e5436536SAndroid Build Coastguard Worker for (j = 0; j < uniqueFilterBlockCount; j++) {
929*e5436536SAndroid Build Coastguard Worker filterElementCount = FDKreadBits(hBs, 6);
930*e5436536SAndroid Build Coastguard Worker for (k = 0; k < filterElementCount; k++) {
931*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 6); /* filterElementIndex */
932*e5436536SAndroid Build Coastguard Worker filterElementGainPresent = FDKreadBits(hBs, 1);
933*e5436536SAndroid Build Coastguard Worker if (filterElementGainPresent) {
934*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 10); /* bsFilterElementGain */
935*e5436536SAndroid Build Coastguard Worker }
936*e5436536SAndroid Build Coastguard Worker }
937*e5436536SAndroid Build Coastguard Worker }
938*e5436536SAndroid Build Coastguard Worker uniqueTdFilterElementCount = FDKreadBits(hBs, 6);
939*e5436536SAndroid Build Coastguard Worker for (j = 0; j < uniqueTdFilterElementCount; j++) {
940*e5436536SAndroid Build Coastguard Worker eqFilterFormat = FDKreadBits(hBs, 1);
941*e5436536SAndroid Build Coastguard Worker if (eqFilterFormat == 0) { /* pole/zero */
942*e5436536SAndroid Build Coastguard Worker bsRealZeroRadiusOneCount = FDKreadBits(hBs, 3);
943*e5436536SAndroid Build Coastguard Worker realZeroCount = FDKreadBits(hBs, 6);
944*e5436536SAndroid Build Coastguard Worker genericZeroCount = FDKreadBits(hBs, 6);
945*e5436536SAndroid Build Coastguard Worker realPoleCount = FDKreadBits(hBs, 4);
946*e5436536SAndroid Build Coastguard Worker complexPoleCount = FDKreadBits(hBs, 4);
947*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 2 * bsRealZeroRadiusOneCount * 1);
948*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, realZeroCount * 8);
949*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, genericZeroCount * 14);
950*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, realPoleCount * 8);
951*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, complexPoleCount * 14);
952*e5436536SAndroid Build Coastguard Worker } else { /* FIR coefficients */
953*e5436536SAndroid Build Coastguard Worker firFilterOrder = FDKreadBits(hBs, 7);
954*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 1);
955*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, (firFilterOrder / 2 + 1) * 11);
956*e5436536SAndroid Build Coastguard Worker }
957*e5436536SAndroid Build Coastguard Worker }
958*e5436536SAndroid Build Coastguard Worker uniqueEqSubbandGainsCount = FDKreadBits(hBs, 6);
959*e5436536SAndroid Build Coastguard Worker if (uniqueEqSubbandGainsCount > 0) {
960*e5436536SAndroid Build Coastguard Worker eqSubbandGainRepresentation = FDKreadBits(hBs, 1);
961*e5436536SAndroid Build Coastguard Worker eqSubbandGainFormat = FDKreadBits(hBs, 4);
962*e5436536SAndroid Build Coastguard Worker switch (eqSubbandGainFormat) {
963*e5436536SAndroid Build Coastguard Worker case GF_QMF32:
964*e5436536SAndroid Build Coastguard Worker eqSubbandGainCount = 32;
965*e5436536SAndroid Build Coastguard Worker break;
966*e5436536SAndroid Build Coastguard Worker case GF_QMFHYBRID39:
967*e5436536SAndroid Build Coastguard Worker eqSubbandGainCount = 39;
968*e5436536SAndroid Build Coastguard Worker break;
969*e5436536SAndroid Build Coastguard Worker case GF_QMF64:
970*e5436536SAndroid Build Coastguard Worker eqSubbandGainCount = 64;
971*e5436536SAndroid Build Coastguard Worker break;
972*e5436536SAndroid Build Coastguard Worker case GF_QMFHYBRID71:
973*e5436536SAndroid Build Coastguard Worker eqSubbandGainCount = 71;
974*e5436536SAndroid Build Coastguard Worker break;
975*e5436536SAndroid Build Coastguard Worker case GF_QMF128:
976*e5436536SAndroid Build Coastguard Worker eqSubbandGainCount = 128;
977*e5436536SAndroid Build Coastguard Worker break;
978*e5436536SAndroid Build Coastguard Worker case GF_QMFHYBRID135:
979*e5436536SAndroid Build Coastguard Worker eqSubbandGainCount = 135;
980*e5436536SAndroid Build Coastguard Worker break;
981*e5436536SAndroid Build Coastguard Worker case GF_UNIFORM:
982*e5436536SAndroid Build Coastguard Worker default:
983*e5436536SAndroid Build Coastguard Worker eqSubbandGainCount = FDKreadBits(hBs, 8);
984*e5436536SAndroid Build Coastguard Worker eqSubbandGainCount++;
985*e5436536SAndroid Build Coastguard Worker break;
986*e5436536SAndroid Build Coastguard Worker }
987*e5436536SAndroid Build Coastguard Worker for (k = 0; k < uniqueEqSubbandGainsCount; k++) {
988*e5436536SAndroid Build Coastguard Worker if (eqSubbandGainRepresentation == 1) {
989*e5436536SAndroid Build Coastguard Worker _skipEqSubbandGainSpline(hBs);
990*e5436536SAndroid Build Coastguard Worker } else {
991*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, eqSubbandGainCount * 9);
992*e5436536SAndroid Build Coastguard Worker }
993*e5436536SAndroid Build Coastguard Worker }
994*e5436536SAndroid Build Coastguard Worker }
995*e5436536SAndroid Build Coastguard Worker }
996*e5436536SAndroid Build Coastguard Worker
_skipTdFilterCascade(HANDLE_FDK_BITSTREAM hBs,const int eqChannelGroupCount)997*e5436536SAndroid Build Coastguard Worker static void _skipTdFilterCascade(HANDLE_FDK_BITSTREAM hBs,
998*e5436536SAndroid Build Coastguard Worker const int eqChannelGroupCount) {
999*e5436536SAndroid Build Coastguard Worker int i, eqCascadeGainPresent, filterBlockCount, eqPhaseAlignmentPresent;
1000*e5436536SAndroid Build Coastguard Worker for (i = 0; i < eqChannelGroupCount; i++) {
1001*e5436536SAndroid Build Coastguard Worker eqCascadeGainPresent = FDKreadBits(hBs, 1);
1002*e5436536SAndroid Build Coastguard Worker if (eqCascadeGainPresent) {
1003*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 10); /* bsEqCascadeGain */
1004*e5436536SAndroid Build Coastguard Worker }
1005*e5436536SAndroid Build Coastguard Worker filterBlockCount = FDKreadBits(hBs, 4);
1006*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, filterBlockCount * 7); /* filterBlockIndex */
1007*e5436536SAndroid Build Coastguard Worker }
1008*e5436536SAndroid Build Coastguard Worker eqPhaseAlignmentPresent = FDKreadBits(hBs, 1);
1009*e5436536SAndroid Build Coastguard Worker {
1010*e5436536SAndroid Build Coastguard Worker if (eqPhaseAlignmentPresent) {
1011*e5436536SAndroid Build Coastguard Worker for (i = 0; i < eqChannelGroupCount; i++) {
1012*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, (eqChannelGroupCount - i - 1) * 1);
1013*e5436536SAndroid Build Coastguard Worker }
1014*e5436536SAndroid Build Coastguard Worker }
1015*e5436536SAndroid Build Coastguard Worker }
1016*e5436536SAndroid Build Coastguard Worker }
1017*e5436536SAndroid Build Coastguard Worker
_skipEqInstructions(HANDLE_FDK_BITSTREAM hBs,HANDLE_UNI_DRC_CONFIG hUniDrcConfig)1018*e5436536SAndroid Build Coastguard Worker static DRC_ERROR _skipEqInstructions(HANDLE_FDK_BITSTREAM hBs,
1019*e5436536SAndroid Build Coastguard Worker HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
1020*e5436536SAndroid Build Coastguard Worker DRC_ERROR err = DE_OK;
1021*e5436536SAndroid Build Coastguard Worker int c, i, k, channelCount;
1022*e5436536SAndroid Build Coastguard Worker int downmixIdPresent, downmixId, eqApplyToDownmix, additionalDownmixIdPresent,
1023*e5436536SAndroid Build Coastguard Worker additionalDownmixIdCount = 0;
1024*e5436536SAndroid Build Coastguard Worker int additionalDrcSetIdPresent, additionalDrcSetIdCount;
1025*e5436536SAndroid Build Coastguard Worker int dependsOnEqSetPresent, eqChannelGroupCount, tdFilterCascadePresent,
1026*e5436536SAndroid Build Coastguard Worker subbandGainsPresent, eqTransitionDurationPresent;
1027*e5436536SAndroid Build Coastguard Worker UCHAR eqChannelGroupForChannel[8];
1028*e5436536SAndroid Build Coastguard Worker
1029*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 6); /* eqSetId */
1030*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 4); /* eqSetComplexityLevel */
1031*e5436536SAndroid Build Coastguard Worker downmixIdPresent = FDKreadBits(hBs, 1);
1032*e5436536SAndroid Build Coastguard Worker if (downmixIdPresent) {
1033*e5436536SAndroid Build Coastguard Worker downmixId = FDKreadBits(hBs, 7);
1034*e5436536SAndroid Build Coastguard Worker eqApplyToDownmix = FDKreadBits(hBs, 1);
1035*e5436536SAndroid Build Coastguard Worker additionalDownmixIdPresent = FDKreadBits(hBs, 1);
1036*e5436536SAndroid Build Coastguard Worker if (additionalDownmixIdPresent) {
1037*e5436536SAndroid Build Coastguard Worker additionalDownmixIdCount = FDKreadBits(hBs, 7);
1038*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, additionalDownmixIdCount * 7); /* additionalDownmixId */
1039*e5436536SAndroid Build Coastguard Worker }
1040*e5436536SAndroid Build Coastguard Worker } else {
1041*e5436536SAndroid Build Coastguard Worker downmixId = 0;
1042*e5436536SAndroid Build Coastguard Worker eqApplyToDownmix = 0;
1043*e5436536SAndroid Build Coastguard Worker }
1044*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 6); /* drcSetId */
1045*e5436536SAndroid Build Coastguard Worker additionalDrcSetIdPresent = FDKreadBits(hBs, 1);
1046*e5436536SAndroid Build Coastguard Worker if (additionalDrcSetIdPresent) {
1047*e5436536SAndroid Build Coastguard Worker additionalDrcSetIdCount = FDKreadBits(hBs, 6);
1048*e5436536SAndroid Build Coastguard Worker for (i = 0; i < additionalDrcSetIdCount; i++) {
1049*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 6); /* additionalDrcSetId */
1050*e5436536SAndroid Build Coastguard Worker }
1051*e5436536SAndroid Build Coastguard Worker }
1052*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 16); /* eqSetPurpose */
1053*e5436536SAndroid Build Coastguard Worker dependsOnEqSetPresent = FDKreadBits(hBs, 1);
1054*e5436536SAndroid Build Coastguard Worker if (dependsOnEqSetPresent) {
1055*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 6); /* dependsOnEqSet */
1056*e5436536SAndroid Build Coastguard Worker } else {
1057*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 1); /* noIndependentEqUse */
1058*e5436536SAndroid Build Coastguard Worker }
1059*e5436536SAndroid Build Coastguard Worker
1060*e5436536SAndroid Build Coastguard Worker channelCount = hUniDrcConfig->channelLayout.baseChannelCount;
1061*e5436536SAndroid Build Coastguard Worker if ((downmixIdPresent == 1) && (eqApplyToDownmix == 1) && (downmixId != 0) &&
1062*e5436536SAndroid Build Coastguard Worker (downmixId != DOWNMIX_ID_ANY_DOWNMIX) &&
1063*e5436536SAndroid Build Coastguard Worker (additionalDownmixIdCount == 0)) {
1064*e5436536SAndroid Build Coastguard Worker DOWNMIX_INSTRUCTIONS* pDown =
1065*e5436536SAndroid Build Coastguard Worker selectDownmixInstructions(hUniDrcConfig, downmixId);
1066*e5436536SAndroid Build Coastguard Worker if (pDown == NULL) return DE_NOT_OK;
1067*e5436536SAndroid Build Coastguard Worker
1068*e5436536SAndroid Build Coastguard Worker channelCount =
1069*e5436536SAndroid Build Coastguard Worker pDown->targetChannelCount; /* targetChannelCountFromDownmixId*/
1070*e5436536SAndroid Build Coastguard Worker } else if ((downmixId == DOWNMIX_ID_ANY_DOWNMIX) ||
1071*e5436536SAndroid Build Coastguard Worker (additionalDownmixIdCount > 1)) {
1072*e5436536SAndroid Build Coastguard Worker channelCount = 1;
1073*e5436536SAndroid Build Coastguard Worker }
1074*e5436536SAndroid Build Coastguard Worker
1075*e5436536SAndroid Build Coastguard Worker eqChannelGroupCount = 0;
1076*e5436536SAndroid Build Coastguard Worker for (c = 0; c < channelCount; c++) {
1077*e5436536SAndroid Build Coastguard Worker int newGroup = 1;
1078*e5436536SAndroid Build Coastguard Worker if (c >= 8) return DE_MEMORY_ERROR;
1079*e5436536SAndroid Build Coastguard Worker eqChannelGroupForChannel[c] = FDKreadBits(hBs, 7);
1080*e5436536SAndroid Build Coastguard Worker for (k = 0; k < c; k++) {
1081*e5436536SAndroid Build Coastguard Worker if (eqChannelGroupForChannel[c] == eqChannelGroupForChannel[k]) {
1082*e5436536SAndroid Build Coastguard Worker newGroup = 0;
1083*e5436536SAndroid Build Coastguard Worker }
1084*e5436536SAndroid Build Coastguard Worker }
1085*e5436536SAndroid Build Coastguard Worker if (newGroup == 1) {
1086*e5436536SAndroid Build Coastguard Worker eqChannelGroupCount += 1;
1087*e5436536SAndroid Build Coastguard Worker }
1088*e5436536SAndroid Build Coastguard Worker }
1089*e5436536SAndroid Build Coastguard Worker tdFilterCascadePresent = FDKreadBits(hBs, 1);
1090*e5436536SAndroid Build Coastguard Worker if (tdFilterCascadePresent) {
1091*e5436536SAndroid Build Coastguard Worker _skipTdFilterCascade(hBs, eqChannelGroupCount);
1092*e5436536SAndroid Build Coastguard Worker }
1093*e5436536SAndroid Build Coastguard Worker subbandGainsPresent = FDKreadBits(hBs, 1);
1094*e5436536SAndroid Build Coastguard Worker if (subbandGainsPresent) {
1095*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, eqChannelGroupCount * 6); /* subbandGainsIndex */
1096*e5436536SAndroid Build Coastguard Worker }
1097*e5436536SAndroid Build Coastguard Worker eqTransitionDurationPresent = FDKreadBits(hBs, 1);
1098*e5436536SAndroid Build Coastguard Worker if (eqTransitionDurationPresent) {
1099*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 5); /* bsEqTransitionDuration */
1100*e5436536SAndroid Build Coastguard Worker }
1101*e5436536SAndroid Build Coastguard Worker return err;
1102*e5436536SAndroid Build Coastguard Worker }
1103*e5436536SAndroid Build Coastguard Worker
_skipDrcCoefficientsBasic(HANDLE_FDK_BITSTREAM hBs)1104*e5436536SAndroid Build Coastguard Worker static void _skipDrcCoefficientsBasic(HANDLE_FDK_BITSTREAM hBs) {
1105*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 4); /* drcLocation */
1106*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 7); /* drcCharacteristic */
1107*e5436536SAndroid Build Coastguard Worker }
1108*e5436536SAndroid Build Coastguard Worker
_readDrcCoefficientsUniDrc(HANDLE_FDK_BITSTREAM hBs,const int version,DRC_COEFFICIENTS_UNI_DRC * pCoef)1109*e5436536SAndroid Build Coastguard Worker static DRC_ERROR _readDrcCoefficientsUniDrc(HANDLE_FDK_BITSTREAM hBs,
1110*e5436536SAndroid Build Coastguard Worker const int version,
1111*e5436536SAndroid Build Coastguard Worker DRC_COEFFICIENTS_UNI_DRC* pCoef) {
1112*e5436536SAndroid Build Coastguard Worker DRC_ERROR err = DE_OK;
1113*e5436536SAndroid Build Coastguard Worker int i, bsDrcFrameSize;
1114*e5436536SAndroid Build Coastguard Worker int gainSequenceIndex = -1;
1115*e5436536SAndroid Build Coastguard Worker
1116*e5436536SAndroid Build Coastguard Worker pCoef->drcLocation = FDKreadBits(hBs, 4);
1117*e5436536SAndroid Build Coastguard Worker pCoef->drcFrameSizePresent = FDKreadBits(hBs, 1);
1118*e5436536SAndroid Build Coastguard Worker
1119*e5436536SAndroid Build Coastguard Worker if (pCoef->drcFrameSizePresent == 1) {
1120*e5436536SAndroid Build Coastguard Worker bsDrcFrameSize = FDKreadBits(hBs, 15);
1121*e5436536SAndroid Build Coastguard Worker pCoef->drcFrameSize = bsDrcFrameSize + 1;
1122*e5436536SAndroid Build Coastguard Worker }
1123*e5436536SAndroid Build Coastguard Worker if (version == 0) {
1124*e5436536SAndroid Build Coastguard Worker int gainSequenceCount = 0, gainSetCount;
1125*e5436536SAndroid Build Coastguard Worker pCoef->characteristicLeftCount = 0;
1126*e5436536SAndroid Build Coastguard Worker pCoef->characteristicRightCount = 0;
1127*e5436536SAndroid Build Coastguard Worker gainSetCount = FDKreadBits(hBs, 6);
1128*e5436536SAndroid Build Coastguard Worker pCoef->gainSetCount = fMin(gainSetCount, 12);
1129*e5436536SAndroid Build Coastguard Worker for (i = 0; i < gainSetCount; i++) {
1130*e5436536SAndroid Build Coastguard Worker GAIN_SET tmpGset;
1131*e5436536SAndroid Build Coastguard Worker FDKmemclear(&tmpGset, sizeof(GAIN_SET));
1132*e5436536SAndroid Build Coastguard Worker err = _readGainSet(hBs, version, &gainSequenceIndex, &tmpGset, 0);
1133*e5436536SAndroid Build Coastguard Worker if (err) return err;
1134*e5436536SAndroid Build Coastguard Worker gainSequenceCount += tmpGset.bandCount;
1135*e5436536SAndroid Build Coastguard Worker
1136*e5436536SAndroid Build Coastguard Worker if (i >= 12) continue;
1137*e5436536SAndroid Build Coastguard Worker pCoef->gainSet[i] = tmpGset;
1138*e5436536SAndroid Build Coastguard Worker }
1139*e5436536SAndroid Build Coastguard Worker pCoef->gainSequenceCount = gainSequenceCount;
1140*e5436536SAndroid Build Coastguard Worker } else { /* (version == 1) */
1141*e5436536SAndroid Build Coastguard Worker UCHAR drcCharacteristicLeftPresent, drcCharacteristicRightPresent;
1142*e5436536SAndroid Build Coastguard Worker UCHAR shapeFiltersPresent, shapeFilterCount, tmpPresent;
1143*e5436536SAndroid Build Coastguard Worker int gainSetCount;
1144*e5436536SAndroid Build Coastguard Worker drcCharacteristicLeftPresent = FDKreadBits(hBs, 1);
1145*e5436536SAndroid Build Coastguard Worker if (drcCharacteristicLeftPresent) {
1146*e5436536SAndroid Build Coastguard Worker pCoef->characteristicLeftCount = FDKreadBits(hBs, 4);
1147*e5436536SAndroid Build Coastguard Worker if ((pCoef->characteristicLeftCount + 1) > 16) return DE_MEMORY_ERROR;
1148*e5436536SAndroid Build Coastguard Worker for (i = 0; i < pCoef->characteristicLeftCount; i++) {
1149*e5436536SAndroid Build Coastguard Worker err = _readCustomDrcCharacteristic(
1150*e5436536SAndroid Build Coastguard Worker hBs, CS_LEFT, &(pCoef->characteristicLeftFormat[i + 1]),
1151*e5436536SAndroid Build Coastguard Worker &(pCoef->customCharacteristicLeft[i + 1]), 0);
1152*e5436536SAndroid Build Coastguard Worker if (err) return err;
1153*e5436536SAndroid Build Coastguard Worker }
1154*e5436536SAndroid Build Coastguard Worker }
1155*e5436536SAndroid Build Coastguard Worker drcCharacteristicRightPresent = FDKreadBits(hBs, 1);
1156*e5436536SAndroid Build Coastguard Worker if (drcCharacteristicRightPresent) {
1157*e5436536SAndroid Build Coastguard Worker pCoef->characteristicRightCount = FDKreadBits(hBs, 4);
1158*e5436536SAndroid Build Coastguard Worker if ((pCoef->characteristicRightCount + 1) > 16) return DE_MEMORY_ERROR;
1159*e5436536SAndroid Build Coastguard Worker for (i = 0; i < pCoef->characteristicRightCount; i++) {
1160*e5436536SAndroid Build Coastguard Worker err = _readCustomDrcCharacteristic(
1161*e5436536SAndroid Build Coastguard Worker hBs, CS_RIGHT, &(pCoef->characteristicRightFormat[i + 1]),
1162*e5436536SAndroid Build Coastguard Worker &(pCoef->customCharacteristicRight[i + 1]), 0);
1163*e5436536SAndroid Build Coastguard Worker if (err) return err;
1164*e5436536SAndroid Build Coastguard Worker }
1165*e5436536SAndroid Build Coastguard Worker }
1166*e5436536SAndroid Build Coastguard Worker shapeFiltersPresent = FDKreadBits(hBs, 1);
1167*e5436536SAndroid Build Coastguard Worker if (shapeFiltersPresent) {
1168*e5436536SAndroid Build Coastguard Worker shapeFilterCount = FDKreadBits(hBs, 4);
1169*e5436536SAndroid Build Coastguard Worker for (i = 0; i < shapeFilterCount; i++) {
1170*e5436536SAndroid Build Coastguard Worker tmpPresent = FDKreadBits(hBs, 1);
1171*e5436536SAndroid Build Coastguard Worker if (tmpPresent) /* lfCutParams */
1172*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 5);
1173*e5436536SAndroid Build Coastguard Worker
1174*e5436536SAndroid Build Coastguard Worker tmpPresent = FDKreadBits(hBs, 1);
1175*e5436536SAndroid Build Coastguard Worker if (tmpPresent) /* lfBoostParams */
1176*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 5);
1177*e5436536SAndroid Build Coastguard Worker
1178*e5436536SAndroid Build Coastguard Worker tmpPresent = FDKreadBits(hBs, 1);
1179*e5436536SAndroid Build Coastguard Worker if (tmpPresent) /* hfCutParams */
1180*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 5);
1181*e5436536SAndroid Build Coastguard Worker
1182*e5436536SAndroid Build Coastguard Worker tmpPresent = FDKreadBits(hBs, 1);
1183*e5436536SAndroid Build Coastguard Worker if (tmpPresent) /* hfBoostParams */
1184*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 5);
1185*e5436536SAndroid Build Coastguard Worker }
1186*e5436536SAndroid Build Coastguard Worker }
1187*e5436536SAndroid Build Coastguard Worker pCoef->gainSequenceCount = FDKreadBits(hBs, 6);
1188*e5436536SAndroid Build Coastguard Worker gainSetCount = FDKreadBits(hBs, 6);
1189*e5436536SAndroid Build Coastguard Worker pCoef->gainSetCount = fMin(gainSetCount, 12);
1190*e5436536SAndroid Build Coastguard Worker for (i = 0; i < gainSetCount; i++) {
1191*e5436536SAndroid Build Coastguard Worker GAIN_SET tmpGset;
1192*e5436536SAndroid Build Coastguard Worker FDKmemclear(&tmpGset, sizeof(GAIN_SET));
1193*e5436536SAndroid Build Coastguard Worker err = _readGainSet(hBs, version, &gainSequenceIndex, &tmpGset, 0);
1194*e5436536SAndroid Build Coastguard Worker if (err) return err;
1195*e5436536SAndroid Build Coastguard Worker
1196*e5436536SAndroid Build Coastguard Worker if (i >= 12) continue;
1197*e5436536SAndroid Build Coastguard Worker pCoef->gainSet[i] = tmpGset;
1198*e5436536SAndroid Build Coastguard Worker }
1199*e5436536SAndroid Build Coastguard Worker }
1200*e5436536SAndroid Build Coastguard Worker for (i = 0; i < 12; i++) {
1201*e5436536SAndroid Build Coastguard Worker pCoef->gainSetIndexForGainSequence[i] = 255;
1202*e5436536SAndroid Build Coastguard Worker }
1203*e5436536SAndroid Build Coastguard Worker for (i = 0; i < pCoef->gainSetCount; i++) {
1204*e5436536SAndroid Build Coastguard Worker int b;
1205*e5436536SAndroid Build Coastguard Worker for (b = 0; b < pCoef->gainSet[i].bandCount; b++) {
1206*e5436536SAndroid Build Coastguard Worker if (pCoef->gainSet[i].gainSequenceIndex[b] >= 12) continue;
1207*e5436536SAndroid Build Coastguard Worker pCoef->gainSetIndexForGainSequence[pCoef->gainSet[i]
1208*e5436536SAndroid Build Coastguard Worker .gainSequenceIndex[b]] = i;
1209*e5436536SAndroid Build Coastguard Worker }
1210*e5436536SAndroid Build Coastguard Worker }
1211*e5436536SAndroid Build Coastguard Worker
1212*e5436536SAndroid Build Coastguard Worker return err;
1213*e5436536SAndroid Build Coastguard Worker }
1214*e5436536SAndroid Build Coastguard Worker
_skipDrcInstructionsBasic(HANDLE_FDK_BITSTREAM hBs)1215*e5436536SAndroid Build Coastguard Worker static void _skipDrcInstructionsBasic(HANDLE_FDK_BITSTREAM hBs) {
1216*e5436536SAndroid Build Coastguard Worker int drcSetEffect;
1217*e5436536SAndroid Build Coastguard Worker int additionalDownmixIdPresent, additionalDownmixIdCount,
1218*e5436536SAndroid Build Coastguard Worker limiterPeakTargetPresent;
1219*e5436536SAndroid Build Coastguard Worker int drcSetTargetLoudnessPresent, drcSetTargetLoudnessValueLowerPresent;
1220*e5436536SAndroid Build Coastguard Worker
1221*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 6); /* drcSetId */
1222*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 4); /* drcLocation */
1223*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 7); /* downmixId */
1224*e5436536SAndroid Build Coastguard Worker additionalDownmixIdPresent = FDKreadBits(hBs, 1);
1225*e5436536SAndroid Build Coastguard Worker if (additionalDownmixIdPresent) {
1226*e5436536SAndroid Build Coastguard Worker additionalDownmixIdCount = FDKreadBits(hBs, 3);
1227*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 7 * additionalDownmixIdCount); /* additionalDownmixId */
1228*e5436536SAndroid Build Coastguard Worker }
1229*e5436536SAndroid Build Coastguard Worker
1230*e5436536SAndroid Build Coastguard Worker drcSetEffect = FDKreadBits(hBs, 16);
1231*e5436536SAndroid Build Coastguard Worker if (!(drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF))) {
1232*e5436536SAndroid Build Coastguard Worker limiterPeakTargetPresent = FDKreadBits(hBs, 1);
1233*e5436536SAndroid Build Coastguard Worker if (limiterPeakTargetPresent) {
1234*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 8); /* bsLimiterPeakTarget */
1235*e5436536SAndroid Build Coastguard Worker }
1236*e5436536SAndroid Build Coastguard Worker }
1237*e5436536SAndroid Build Coastguard Worker
1238*e5436536SAndroid Build Coastguard Worker drcSetTargetLoudnessPresent = FDKreadBits(hBs, 1);
1239*e5436536SAndroid Build Coastguard Worker if (drcSetTargetLoudnessPresent) {
1240*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 6); /* bsDrcSetTargetLoudnessValueUpper */
1241*e5436536SAndroid Build Coastguard Worker drcSetTargetLoudnessValueLowerPresent = FDKreadBits(hBs, 1);
1242*e5436536SAndroid Build Coastguard Worker if (drcSetTargetLoudnessValueLowerPresent) {
1243*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 6); /* bsDrcSetTargetLoudnessValueLower */
1244*e5436536SAndroid Build Coastguard Worker }
1245*e5436536SAndroid Build Coastguard Worker }
1246*e5436536SAndroid Build Coastguard Worker }
1247*e5436536SAndroid Build Coastguard Worker
_readDrcInstructionsUniDrc(HANDLE_FDK_BITSTREAM hBs,const int version,HANDLE_UNI_DRC_CONFIG hUniDrcConfig,DRC_INSTRUCTIONS_UNI_DRC * pInst)1248*e5436536SAndroid Build Coastguard Worker static DRC_ERROR _readDrcInstructionsUniDrc(HANDLE_FDK_BITSTREAM hBs,
1249*e5436536SAndroid Build Coastguard Worker const int version,
1250*e5436536SAndroid Build Coastguard Worker HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
1251*e5436536SAndroid Build Coastguard Worker DRC_INSTRUCTIONS_UNI_DRC* pInst) {
1252*e5436536SAndroid Build Coastguard Worker DRC_ERROR err = DE_OK;
1253*e5436536SAndroid Build Coastguard Worker int i, g, c;
1254*e5436536SAndroid Build Coastguard Worker int downmixIdPresent, additionalDownmixIdPresent, additionalDownmixIdCount;
1255*e5436536SAndroid Build Coastguard Worker int bsLimiterPeakTarget, channelCount;
1256*e5436536SAndroid Build Coastguard Worker DRC_COEFFICIENTS_UNI_DRC* pCoef = NULL;
1257*e5436536SAndroid Build Coastguard Worker int repeatParameters, bsRepeatParametersCount;
1258*e5436536SAndroid Build Coastguard Worker int repeatSequenceIndex, bsRepeatSequenceCount;
1259*e5436536SAndroid Build Coastguard Worker SCHAR* gainSetIndex = pInst->gainSetIndex;
1260*e5436536SAndroid Build Coastguard Worker SCHAR channelGroupForChannel[8];
1261*e5436536SAndroid Build Coastguard Worker DUCKING_MODIFICATION duckingModificationForChannelGroup[8];
1262*e5436536SAndroid Build Coastguard Worker
1263*e5436536SAndroid Build Coastguard Worker pInst->drcSetId = FDKreadBits(hBs, 6);
1264*e5436536SAndroid Build Coastguard Worker if (version == 0) {
1265*e5436536SAndroid Build Coastguard Worker /* Assume all v0 DRC sets to be manageable in terms of complexity */
1266*e5436536SAndroid Build Coastguard Worker pInst->drcSetComplexityLevel = 2;
1267*e5436536SAndroid Build Coastguard Worker } else {
1268*e5436536SAndroid Build Coastguard Worker pInst->drcSetComplexityLevel = FDKreadBits(hBs, 4);
1269*e5436536SAndroid Build Coastguard Worker }
1270*e5436536SAndroid Build Coastguard Worker pInst->drcLocation = FDKreadBits(hBs, 4);
1271*e5436536SAndroid Build Coastguard Worker if (version == 0) {
1272*e5436536SAndroid Build Coastguard Worker downmixIdPresent = 1;
1273*e5436536SAndroid Build Coastguard Worker } else {
1274*e5436536SAndroid Build Coastguard Worker downmixIdPresent = FDKreadBits(hBs, 1);
1275*e5436536SAndroid Build Coastguard Worker }
1276*e5436536SAndroid Build Coastguard Worker if (downmixIdPresent) {
1277*e5436536SAndroid Build Coastguard Worker pInst->downmixId[0] = FDKreadBits(hBs, 7);
1278*e5436536SAndroid Build Coastguard Worker if (version == 0) {
1279*e5436536SAndroid Build Coastguard Worker if (pInst->downmixId[0] == 0)
1280*e5436536SAndroid Build Coastguard Worker pInst->drcApplyToDownmix = 0;
1281*e5436536SAndroid Build Coastguard Worker else
1282*e5436536SAndroid Build Coastguard Worker pInst->drcApplyToDownmix = 1;
1283*e5436536SAndroid Build Coastguard Worker } else {
1284*e5436536SAndroid Build Coastguard Worker pInst->drcApplyToDownmix = FDKreadBits(hBs, 1);
1285*e5436536SAndroid Build Coastguard Worker }
1286*e5436536SAndroid Build Coastguard Worker
1287*e5436536SAndroid Build Coastguard Worker additionalDownmixIdPresent = FDKreadBits(hBs, 1);
1288*e5436536SAndroid Build Coastguard Worker if (additionalDownmixIdPresent) {
1289*e5436536SAndroid Build Coastguard Worker additionalDownmixIdCount = FDKreadBits(hBs, 3);
1290*e5436536SAndroid Build Coastguard Worker if ((1 + additionalDownmixIdCount) > 8) return DE_MEMORY_ERROR;
1291*e5436536SAndroid Build Coastguard Worker for (i = 0; i < additionalDownmixIdCount; i++) {
1292*e5436536SAndroid Build Coastguard Worker pInst->downmixId[i + 1] = FDKreadBits(hBs, 7);
1293*e5436536SAndroid Build Coastguard Worker }
1294*e5436536SAndroid Build Coastguard Worker pInst->downmixIdCount = 1 + additionalDownmixIdCount;
1295*e5436536SAndroid Build Coastguard Worker } else {
1296*e5436536SAndroid Build Coastguard Worker pInst->downmixIdCount = 1;
1297*e5436536SAndroid Build Coastguard Worker }
1298*e5436536SAndroid Build Coastguard Worker } else {
1299*e5436536SAndroid Build Coastguard Worker pInst->downmixId[0] = 0;
1300*e5436536SAndroid Build Coastguard Worker pInst->downmixIdCount = 1;
1301*e5436536SAndroid Build Coastguard Worker }
1302*e5436536SAndroid Build Coastguard Worker
1303*e5436536SAndroid Build Coastguard Worker pInst->drcSetEffect = FDKreadBits(hBs, 16);
1304*e5436536SAndroid Build Coastguard Worker
1305*e5436536SAndroid Build Coastguard Worker if ((pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) == 0) {
1306*e5436536SAndroid Build Coastguard Worker pInst->limiterPeakTargetPresent = FDKreadBits(hBs, 1);
1307*e5436536SAndroid Build Coastguard Worker if (pInst->limiterPeakTargetPresent) {
1308*e5436536SAndroid Build Coastguard Worker bsLimiterPeakTarget = FDKreadBits(hBs, 8);
1309*e5436536SAndroid Build Coastguard Worker pInst->limiterPeakTarget = -(FIXP_SGL)(
1310*e5436536SAndroid Build Coastguard Worker bsLimiterPeakTarget
1311*e5436536SAndroid Build Coastguard Worker << (FRACT_BITS - 1 - 3 - 5)); /* - bsLimiterPeakTarget * 0.125; */
1312*e5436536SAndroid Build Coastguard Worker }
1313*e5436536SAndroid Build Coastguard Worker }
1314*e5436536SAndroid Build Coastguard Worker
1315*e5436536SAndroid Build Coastguard Worker pInst->drcSetTargetLoudnessPresent = FDKreadBits(hBs, 1);
1316*e5436536SAndroid Build Coastguard Worker
1317*e5436536SAndroid Build Coastguard Worker /* set default values */
1318*e5436536SAndroid Build Coastguard Worker pInst->drcSetTargetLoudnessValueUpper = 0;
1319*e5436536SAndroid Build Coastguard Worker pInst->drcSetTargetLoudnessValueLower = -63;
1320*e5436536SAndroid Build Coastguard Worker
1321*e5436536SAndroid Build Coastguard Worker if (pInst->drcSetTargetLoudnessPresent == 1) {
1322*e5436536SAndroid Build Coastguard Worker int bsDrcSetTargetLoudnessValueUpper, bsDrcSetTargetLoudnessValueLower;
1323*e5436536SAndroid Build Coastguard Worker int drcSetTargetLoudnessValueLowerPresent;
1324*e5436536SAndroid Build Coastguard Worker bsDrcSetTargetLoudnessValueUpper = FDKreadBits(hBs, 6);
1325*e5436536SAndroid Build Coastguard Worker pInst->drcSetTargetLoudnessValueUpper =
1326*e5436536SAndroid Build Coastguard Worker bsDrcSetTargetLoudnessValueUpper - 63;
1327*e5436536SAndroid Build Coastguard Worker drcSetTargetLoudnessValueLowerPresent = FDKreadBits(hBs, 1);
1328*e5436536SAndroid Build Coastguard Worker if (drcSetTargetLoudnessValueLowerPresent == 1) {
1329*e5436536SAndroid Build Coastguard Worker bsDrcSetTargetLoudnessValueLower = FDKreadBits(hBs, 6);
1330*e5436536SAndroid Build Coastguard Worker pInst->drcSetTargetLoudnessValueLower =
1331*e5436536SAndroid Build Coastguard Worker bsDrcSetTargetLoudnessValueLower - 63;
1332*e5436536SAndroid Build Coastguard Worker }
1333*e5436536SAndroid Build Coastguard Worker }
1334*e5436536SAndroid Build Coastguard Worker
1335*e5436536SAndroid Build Coastguard Worker pInst->dependsOnDrcSetPresent = FDKreadBits(hBs, 1);
1336*e5436536SAndroid Build Coastguard Worker
1337*e5436536SAndroid Build Coastguard Worker pInst->noIndependentUse = 0;
1338*e5436536SAndroid Build Coastguard Worker if (pInst->dependsOnDrcSetPresent) {
1339*e5436536SAndroid Build Coastguard Worker pInst->dependsOnDrcSet = FDKreadBits(hBs, 6);
1340*e5436536SAndroid Build Coastguard Worker } else {
1341*e5436536SAndroid Build Coastguard Worker pInst->noIndependentUse = FDKreadBits(hBs, 1);
1342*e5436536SAndroid Build Coastguard Worker }
1343*e5436536SAndroid Build Coastguard Worker
1344*e5436536SAndroid Build Coastguard Worker if (version == 0) {
1345*e5436536SAndroid Build Coastguard Worker pInst->requiresEq = 0;
1346*e5436536SAndroid Build Coastguard Worker } else {
1347*e5436536SAndroid Build Coastguard Worker pInst->requiresEq = FDKreadBits(hBs, 1);
1348*e5436536SAndroid Build Coastguard Worker }
1349*e5436536SAndroid Build Coastguard Worker
1350*e5436536SAndroid Build Coastguard Worker pCoef = selectDrcCoefficients(hUniDrcConfig, pInst->drcLocation);
1351*e5436536SAndroid Build Coastguard Worker
1352*e5436536SAndroid Build Coastguard Worker pInst->drcChannelCount = channelCount =
1353*e5436536SAndroid Build Coastguard Worker hUniDrcConfig->channelLayout.baseChannelCount;
1354*e5436536SAndroid Build Coastguard Worker
1355*e5436536SAndroid Build Coastguard Worker if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
1356*e5436536SAndroid Build Coastguard Worker DUCKING_MODIFICATION* pDModForChannel =
1357*e5436536SAndroid Build Coastguard Worker pInst->duckingModificationForChannel;
1358*e5436536SAndroid Build Coastguard Worker c = 0;
1359*e5436536SAndroid Build Coastguard Worker while (c < channelCount) {
1360*e5436536SAndroid Build Coastguard Worker int bsGainSetIndex;
1361*e5436536SAndroid Build Coastguard Worker bsGainSetIndex = FDKreadBits(hBs, 6);
1362*e5436536SAndroid Build Coastguard Worker if (c >= 8) return DE_MEMORY_ERROR;
1363*e5436536SAndroid Build Coastguard Worker gainSetIndex[c] = bsGainSetIndex - 1;
1364*e5436536SAndroid Build Coastguard Worker _decodeDuckingModification(hBs, &(pDModForChannel[c]), 0);
1365*e5436536SAndroid Build Coastguard Worker
1366*e5436536SAndroid Build Coastguard Worker c++;
1367*e5436536SAndroid Build Coastguard Worker repeatParameters = FDKreadBits(hBs, 1);
1368*e5436536SAndroid Build Coastguard Worker if (repeatParameters == 1) {
1369*e5436536SAndroid Build Coastguard Worker bsRepeatParametersCount = FDKreadBits(hBs, 5);
1370*e5436536SAndroid Build Coastguard Worker bsRepeatParametersCount += 1;
1371*e5436536SAndroid Build Coastguard Worker for (i = 0; i < bsRepeatParametersCount; i++) {
1372*e5436536SAndroid Build Coastguard Worker if (c >= 8) return DE_MEMORY_ERROR;
1373*e5436536SAndroid Build Coastguard Worker gainSetIndex[c] = gainSetIndex[c - 1];
1374*e5436536SAndroid Build Coastguard Worker pDModForChannel[c] = pDModForChannel[c - 1];
1375*e5436536SAndroid Build Coastguard Worker c++;
1376*e5436536SAndroid Build Coastguard Worker }
1377*e5436536SAndroid Build Coastguard Worker }
1378*e5436536SAndroid Build Coastguard Worker }
1379*e5436536SAndroid Build Coastguard Worker if (c > channelCount) {
1380*e5436536SAndroid Build Coastguard Worker return DE_NOT_OK;
1381*e5436536SAndroid Build Coastguard Worker }
1382*e5436536SAndroid Build Coastguard Worker
1383*e5436536SAndroid Build Coastguard Worker err = deriveDrcChannelGroups(
1384*e5436536SAndroid Build Coastguard Worker pInst->drcSetEffect, pInst->drcChannelCount, gainSetIndex,
1385*e5436536SAndroid Build Coastguard Worker pDModForChannel, &pInst->nDrcChannelGroups,
1386*e5436536SAndroid Build Coastguard Worker pInst->gainSetIndexForChannelGroup, channelGroupForChannel,
1387*e5436536SAndroid Build Coastguard Worker duckingModificationForChannelGroup);
1388*e5436536SAndroid Build Coastguard Worker if (err) return (err);
1389*e5436536SAndroid Build Coastguard Worker } else {
1390*e5436536SAndroid Build Coastguard Worker int deriveChannelCount = 0;
1391*e5436536SAndroid Build Coastguard Worker if (((version == 0) || (pInst->drcApplyToDownmix != 0)) &&
1392*e5436536SAndroid Build Coastguard Worker (pInst->downmixId[0] != DOWNMIX_ID_BASE_LAYOUT) &&
1393*e5436536SAndroid Build Coastguard Worker (pInst->downmixId[0] != DOWNMIX_ID_ANY_DOWNMIX) &&
1394*e5436536SAndroid Build Coastguard Worker (pInst->downmixIdCount == 1)) {
1395*e5436536SAndroid Build Coastguard Worker if (hUniDrcConfig->downmixInstructionsCount != 0) {
1396*e5436536SAndroid Build Coastguard Worker DOWNMIX_INSTRUCTIONS* pDown =
1397*e5436536SAndroid Build Coastguard Worker selectDownmixInstructions(hUniDrcConfig, pInst->downmixId[0]);
1398*e5436536SAndroid Build Coastguard Worker if (pDown == NULL) return DE_NOT_OK;
1399*e5436536SAndroid Build Coastguard Worker pInst->drcChannelCount = channelCount =
1400*e5436536SAndroid Build Coastguard Worker pDown->targetChannelCount; /* targetChannelCountFromDownmixId*/
1401*e5436536SAndroid Build Coastguard Worker } else {
1402*e5436536SAndroid Build Coastguard Worker deriveChannelCount = 1;
1403*e5436536SAndroid Build Coastguard Worker channelCount = 1;
1404*e5436536SAndroid Build Coastguard Worker }
1405*e5436536SAndroid Build Coastguard Worker } else if (((version == 0) || (pInst->drcApplyToDownmix != 0)) &&
1406*e5436536SAndroid Build Coastguard Worker ((pInst->downmixId[0] == DOWNMIX_ID_ANY_DOWNMIX) ||
1407*e5436536SAndroid Build Coastguard Worker (pInst->downmixIdCount > 1))) {
1408*e5436536SAndroid Build Coastguard Worker /* Set maximum channel count as upper border. The effective channel count
1409*e5436536SAndroid Build Coastguard Worker * is set at the process function. */
1410*e5436536SAndroid Build Coastguard Worker pInst->drcChannelCount = 8;
1411*e5436536SAndroid Build Coastguard Worker channelCount = 1;
1412*e5436536SAndroid Build Coastguard Worker }
1413*e5436536SAndroid Build Coastguard Worker
1414*e5436536SAndroid Build Coastguard Worker c = 0;
1415*e5436536SAndroid Build Coastguard Worker while (c < channelCount) {
1416*e5436536SAndroid Build Coastguard Worker int bsGainSetIndex;
1417*e5436536SAndroid Build Coastguard Worker bsGainSetIndex = FDKreadBits(hBs, 6);
1418*e5436536SAndroid Build Coastguard Worker if (c >= 8) return DE_MEMORY_ERROR;
1419*e5436536SAndroid Build Coastguard Worker gainSetIndex[c] = bsGainSetIndex - 1;
1420*e5436536SAndroid Build Coastguard Worker c++;
1421*e5436536SAndroid Build Coastguard Worker repeatSequenceIndex = FDKreadBits(hBs, 1);
1422*e5436536SAndroid Build Coastguard Worker
1423*e5436536SAndroid Build Coastguard Worker if (repeatSequenceIndex == 1) {
1424*e5436536SAndroid Build Coastguard Worker bsRepeatSequenceCount = FDKreadBits(hBs, 5);
1425*e5436536SAndroid Build Coastguard Worker bsRepeatSequenceCount += 1;
1426*e5436536SAndroid Build Coastguard Worker if (deriveChannelCount) {
1427*e5436536SAndroid Build Coastguard Worker channelCount = 1 + bsRepeatSequenceCount;
1428*e5436536SAndroid Build Coastguard Worker }
1429*e5436536SAndroid Build Coastguard Worker for (i = 0; i < bsRepeatSequenceCount; i++) {
1430*e5436536SAndroid Build Coastguard Worker if (c >= 8) return DE_MEMORY_ERROR;
1431*e5436536SAndroid Build Coastguard Worker gainSetIndex[c] = bsGainSetIndex - 1;
1432*e5436536SAndroid Build Coastguard Worker c++;
1433*e5436536SAndroid Build Coastguard Worker }
1434*e5436536SAndroid Build Coastguard Worker }
1435*e5436536SAndroid Build Coastguard Worker }
1436*e5436536SAndroid Build Coastguard Worker if (c > channelCount) {
1437*e5436536SAndroid Build Coastguard Worker return DE_NOT_OK;
1438*e5436536SAndroid Build Coastguard Worker }
1439*e5436536SAndroid Build Coastguard Worker if (deriveChannelCount) {
1440*e5436536SAndroid Build Coastguard Worker pInst->drcChannelCount = channelCount;
1441*e5436536SAndroid Build Coastguard Worker }
1442*e5436536SAndroid Build Coastguard Worker
1443*e5436536SAndroid Build Coastguard Worker /* DOWNMIX_ID_ANY_DOWNMIX: channelCount is 1. Distribute gainSetIndex to all
1444*e5436536SAndroid Build Coastguard Worker * channels. */
1445*e5436536SAndroid Build Coastguard Worker if ((pInst->downmixId[0] == DOWNMIX_ID_ANY_DOWNMIX) ||
1446*e5436536SAndroid Build Coastguard Worker (pInst->downmixIdCount > 1)) {
1447*e5436536SAndroid Build Coastguard Worker for (c = 1; c < pInst->drcChannelCount; c++) {
1448*e5436536SAndroid Build Coastguard Worker gainSetIndex[c] = gainSetIndex[0];
1449*e5436536SAndroid Build Coastguard Worker }
1450*e5436536SAndroid Build Coastguard Worker }
1451*e5436536SAndroid Build Coastguard Worker
1452*e5436536SAndroid Build Coastguard Worker err = deriveDrcChannelGroups(pInst->drcSetEffect, pInst->drcChannelCount,
1453*e5436536SAndroid Build Coastguard Worker gainSetIndex, NULL, &pInst->nDrcChannelGroups,
1454*e5436536SAndroid Build Coastguard Worker pInst->gainSetIndexForChannelGroup,
1455*e5436536SAndroid Build Coastguard Worker channelGroupForChannel, NULL);
1456*e5436536SAndroid Build Coastguard Worker if (err) return (err);
1457*e5436536SAndroid Build Coastguard Worker
1458*e5436536SAndroid Build Coastguard Worker for (g = 0; g < pInst->nDrcChannelGroups; g++) {
1459*e5436536SAndroid Build Coastguard Worker int set, bandCount;
1460*e5436536SAndroid Build Coastguard Worker set = pInst->gainSetIndexForChannelGroup[g];
1461*e5436536SAndroid Build Coastguard Worker
1462*e5436536SAndroid Build Coastguard Worker /* get bandCount */
1463*e5436536SAndroid Build Coastguard Worker if (pCoef != NULL && set < pCoef->gainSetCount) {
1464*e5436536SAndroid Build Coastguard Worker bandCount = pCoef->gainSet[set].bandCount;
1465*e5436536SAndroid Build Coastguard Worker } else {
1466*e5436536SAndroid Build Coastguard Worker bandCount = 1;
1467*e5436536SAndroid Build Coastguard Worker }
1468*e5436536SAndroid Build Coastguard Worker
1469*e5436536SAndroid Build Coastguard Worker _decodeGainModification(hBs, version, bandCount,
1470*e5436536SAndroid Build Coastguard Worker pInst->gainModificationForChannelGroup[g], 0);
1471*e5436536SAndroid Build Coastguard Worker }
1472*e5436536SAndroid Build Coastguard Worker }
1473*e5436536SAndroid Build Coastguard Worker
1474*e5436536SAndroid Build Coastguard Worker return err;
1475*e5436536SAndroid Build Coastguard Worker }
1476*e5436536SAndroid Build Coastguard Worker
_readChannelLayout(HANDLE_FDK_BITSTREAM hBs,CHANNEL_LAYOUT * pChan)1477*e5436536SAndroid Build Coastguard Worker static DRC_ERROR _readChannelLayout(HANDLE_FDK_BITSTREAM hBs,
1478*e5436536SAndroid Build Coastguard Worker CHANNEL_LAYOUT* pChan) {
1479*e5436536SAndroid Build Coastguard Worker DRC_ERROR err = DE_OK;
1480*e5436536SAndroid Build Coastguard Worker
1481*e5436536SAndroid Build Coastguard Worker pChan->baseChannelCount = FDKreadBits(hBs, 7);
1482*e5436536SAndroid Build Coastguard Worker
1483*e5436536SAndroid Build Coastguard Worker if (pChan->baseChannelCount > 8) return DE_NOT_OK;
1484*e5436536SAndroid Build Coastguard Worker
1485*e5436536SAndroid Build Coastguard Worker pChan->layoutSignalingPresent = FDKreadBits(hBs, 1);
1486*e5436536SAndroid Build Coastguard Worker
1487*e5436536SAndroid Build Coastguard Worker if (pChan->layoutSignalingPresent) {
1488*e5436536SAndroid Build Coastguard Worker pChan->definedLayout = FDKreadBits(hBs, 8);
1489*e5436536SAndroid Build Coastguard Worker
1490*e5436536SAndroid Build Coastguard Worker if (pChan->definedLayout == 0) {
1491*e5436536SAndroid Build Coastguard Worker int i;
1492*e5436536SAndroid Build Coastguard Worker for (i = 0; i < pChan->baseChannelCount; i++) {
1493*e5436536SAndroid Build Coastguard Worker if (i < 8) {
1494*e5436536SAndroid Build Coastguard Worker pChan->speakerPosition[i] = FDKreadBits(hBs, 7);
1495*e5436536SAndroid Build Coastguard Worker } else {
1496*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, 7);
1497*e5436536SAndroid Build Coastguard Worker }
1498*e5436536SAndroid Build Coastguard Worker }
1499*e5436536SAndroid Build Coastguard Worker }
1500*e5436536SAndroid Build Coastguard Worker }
1501*e5436536SAndroid Build Coastguard Worker return err;
1502*e5436536SAndroid Build Coastguard Worker }
1503*e5436536SAndroid Build Coastguard Worker
_readDownmixInstructions(HANDLE_FDK_BITSTREAM hBs,const int version,CHANNEL_LAYOUT * pChan,DOWNMIX_INSTRUCTIONS * pDown)1504*e5436536SAndroid Build Coastguard Worker static DRC_ERROR _readDownmixInstructions(HANDLE_FDK_BITSTREAM hBs,
1505*e5436536SAndroid Build Coastguard Worker const int version,
1506*e5436536SAndroid Build Coastguard Worker CHANNEL_LAYOUT* pChan,
1507*e5436536SAndroid Build Coastguard Worker DOWNMIX_INSTRUCTIONS* pDown) {
1508*e5436536SAndroid Build Coastguard Worker DRC_ERROR err = DE_OK;
1509*e5436536SAndroid Build Coastguard Worker
1510*e5436536SAndroid Build Coastguard Worker pDown->downmixId = FDKreadBits(hBs, 7);
1511*e5436536SAndroid Build Coastguard Worker pDown->targetChannelCount = FDKreadBits(hBs, 7);
1512*e5436536SAndroid Build Coastguard Worker pDown->targetLayout = FDKreadBits(hBs, 8);
1513*e5436536SAndroid Build Coastguard Worker pDown->downmixCoefficientsPresent = FDKreadBits(hBs, 1);
1514*e5436536SAndroid Build Coastguard Worker
1515*e5436536SAndroid Build Coastguard Worker if (pDown->downmixCoefficientsPresent) {
1516*e5436536SAndroid Build Coastguard Worker int nDownmixCoeffs = pDown->targetChannelCount * pChan->baseChannelCount;
1517*e5436536SAndroid Build Coastguard Worker int i;
1518*e5436536SAndroid Build Coastguard Worker if (nDownmixCoeffs > 8 * 8) return DE_NOT_OK;
1519*e5436536SAndroid Build Coastguard Worker if (version == 0) {
1520*e5436536SAndroid Build Coastguard Worker pDown->bsDownmixOffset = 0;
1521*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nDownmixCoeffs; i++) {
1522*e5436536SAndroid Build Coastguard Worker /* LFE downmix coefficients are not supported. */
1523*e5436536SAndroid Build Coastguard Worker pDown->downmixCoefficient[i] = downmixCoeff[FDKreadBits(hBs, 4)];
1524*e5436536SAndroid Build Coastguard Worker }
1525*e5436536SAndroid Build Coastguard Worker } else {
1526*e5436536SAndroid Build Coastguard Worker pDown->bsDownmixOffset = FDKreadBits(hBs, 4);
1527*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nDownmixCoeffs; i++) {
1528*e5436536SAndroid Build Coastguard Worker pDown->downmixCoefficient[i] = downmixCoeffV1[FDKreadBits(hBs, 5)];
1529*e5436536SAndroid Build Coastguard Worker }
1530*e5436536SAndroid Build Coastguard Worker }
1531*e5436536SAndroid Build Coastguard Worker }
1532*e5436536SAndroid Build Coastguard Worker return err;
1533*e5436536SAndroid Build Coastguard Worker }
1534*e5436536SAndroid Build Coastguard Worker
_readDrcExtensionV1(HANDLE_FDK_BITSTREAM hBs,HANDLE_UNI_DRC_CONFIG hUniDrcConfig)1535*e5436536SAndroid Build Coastguard Worker static DRC_ERROR _readDrcExtensionV1(HANDLE_FDK_BITSTREAM hBs,
1536*e5436536SAndroid Build Coastguard Worker HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
1537*e5436536SAndroid Build Coastguard Worker DRC_ERROR err = DE_OK;
1538*e5436536SAndroid Build Coastguard Worker int downmixInstructionsV1Present;
1539*e5436536SAndroid Build Coastguard Worker int drcCoeffsAndInstructionsUniDrcV1Present;
1540*e5436536SAndroid Build Coastguard Worker int loudEqInstructionsPresent, loudEqInstructionsCount;
1541*e5436536SAndroid Build Coastguard Worker int eqPresent, eqInstructionsCount;
1542*e5436536SAndroid Build Coastguard Worker int i, offset;
1543*e5436536SAndroid Build Coastguard Worker int diff = hUniDrcConfig->diff;
1544*e5436536SAndroid Build Coastguard Worker
1545*e5436536SAndroid Build Coastguard Worker downmixInstructionsV1Present = FDKreadBits(hBs, 1);
1546*e5436536SAndroid Build Coastguard Worker if (downmixInstructionsV1Present == 1) {
1547*e5436536SAndroid Build Coastguard Worker diff |= _compAssign(&hUniDrcConfig->downmixInstructionsCountV1,
1548*e5436536SAndroid Build Coastguard Worker FDKreadBits(hBs, 7));
1549*e5436536SAndroid Build Coastguard Worker offset = hUniDrcConfig->downmixInstructionsCountV0;
1550*e5436536SAndroid Build Coastguard Worker hUniDrcConfig->downmixInstructionsCount = fMin(
1551*e5436536SAndroid Build Coastguard Worker (UCHAR)(offset + hUniDrcConfig->downmixInstructionsCountV1), (UCHAR)6);
1552*e5436536SAndroid Build Coastguard Worker for (i = 0; i < hUniDrcConfig->downmixInstructionsCountV1; i++) {
1553*e5436536SAndroid Build Coastguard Worker DOWNMIX_INSTRUCTIONS tmpDown;
1554*e5436536SAndroid Build Coastguard Worker FDKmemclear(&tmpDown, sizeof(DOWNMIX_INSTRUCTIONS));
1555*e5436536SAndroid Build Coastguard Worker err = _readDownmixInstructions(hBs, 1, &hUniDrcConfig->channelLayout,
1556*e5436536SAndroid Build Coastguard Worker &tmpDown);
1557*e5436536SAndroid Build Coastguard Worker if (err) return err;
1558*e5436536SAndroid Build Coastguard Worker if ((offset + i) >= 6) continue;
1559*e5436536SAndroid Build Coastguard Worker if (!diff)
1560*e5436536SAndroid Build Coastguard Worker diff |= (FDKmemcmp(&tmpDown,
1561*e5436536SAndroid Build Coastguard Worker &(hUniDrcConfig->downmixInstructions[offset + i]),
1562*e5436536SAndroid Build Coastguard Worker sizeof(DOWNMIX_INSTRUCTIONS)) != 0);
1563*e5436536SAndroid Build Coastguard Worker hUniDrcConfig->downmixInstructions[offset + i] = tmpDown;
1564*e5436536SAndroid Build Coastguard Worker }
1565*e5436536SAndroid Build Coastguard Worker } else {
1566*e5436536SAndroid Build Coastguard Worker diff |= _compAssign(&hUniDrcConfig->downmixInstructionsCountV1, 0);
1567*e5436536SAndroid Build Coastguard Worker }
1568*e5436536SAndroid Build Coastguard Worker
1569*e5436536SAndroid Build Coastguard Worker drcCoeffsAndInstructionsUniDrcV1Present = FDKreadBits(hBs, 1);
1570*e5436536SAndroid Build Coastguard Worker if (drcCoeffsAndInstructionsUniDrcV1Present == 1) {
1571*e5436536SAndroid Build Coastguard Worker diff |= _compAssign(&hUniDrcConfig->drcCoefficientsUniDrcCountV1,
1572*e5436536SAndroid Build Coastguard Worker FDKreadBits(hBs, 3));
1573*e5436536SAndroid Build Coastguard Worker offset = hUniDrcConfig->drcCoefficientsUniDrcCountV0;
1574*e5436536SAndroid Build Coastguard Worker hUniDrcConfig->drcCoefficientsUniDrcCount =
1575*e5436536SAndroid Build Coastguard Worker fMin((UCHAR)(offset + hUniDrcConfig->drcCoefficientsUniDrcCountV1),
1576*e5436536SAndroid Build Coastguard Worker (UCHAR)2);
1577*e5436536SAndroid Build Coastguard Worker for (i = 0; i < hUniDrcConfig->drcCoefficientsUniDrcCountV1; i++) {
1578*e5436536SAndroid Build Coastguard Worker DRC_COEFFICIENTS_UNI_DRC tmpCoef;
1579*e5436536SAndroid Build Coastguard Worker FDKmemclear(&tmpCoef, sizeof(DRC_COEFFICIENTS_UNI_DRC));
1580*e5436536SAndroid Build Coastguard Worker err = _readDrcCoefficientsUniDrc(hBs, 1, &tmpCoef);
1581*e5436536SAndroid Build Coastguard Worker if (err) return err;
1582*e5436536SAndroid Build Coastguard Worker if ((offset + i) >= 2) continue;
1583*e5436536SAndroid Build Coastguard Worker if (!diff)
1584*e5436536SAndroid Build Coastguard Worker diff |= (FDKmemcmp(&tmpCoef,
1585*e5436536SAndroid Build Coastguard Worker &(hUniDrcConfig->drcCoefficientsUniDrc[offset + i]),
1586*e5436536SAndroid Build Coastguard Worker sizeof(DRC_COEFFICIENTS_UNI_DRC)) != 0);
1587*e5436536SAndroid Build Coastguard Worker hUniDrcConfig->drcCoefficientsUniDrc[offset + i] = tmpCoef;
1588*e5436536SAndroid Build Coastguard Worker }
1589*e5436536SAndroid Build Coastguard Worker
1590*e5436536SAndroid Build Coastguard Worker diff |= _compAssign(&hUniDrcConfig->drcInstructionsUniDrcCountV1,
1591*e5436536SAndroid Build Coastguard Worker FDKreadBits(hBs, 6));
1592*e5436536SAndroid Build Coastguard Worker offset = hUniDrcConfig->drcInstructionsUniDrcCount;
1593*e5436536SAndroid Build Coastguard Worker hUniDrcConfig->drcInstructionsUniDrcCount =
1594*e5436536SAndroid Build Coastguard Worker fMin((UCHAR)(offset + hUniDrcConfig->drcInstructionsUniDrcCountV1),
1595*e5436536SAndroid Build Coastguard Worker (UCHAR)12);
1596*e5436536SAndroid Build Coastguard Worker for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
1597*e5436536SAndroid Build Coastguard Worker DRC_INSTRUCTIONS_UNI_DRC tmpInst;
1598*e5436536SAndroid Build Coastguard Worker FDKmemclear(&tmpInst, sizeof(DRC_INSTRUCTIONS_UNI_DRC));
1599*e5436536SAndroid Build Coastguard Worker err = _readDrcInstructionsUniDrc(hBs, 1, hUniDrcConfig, &tmpInst);
1600*e5436536SAndroid Build Coastguard Worker if (err) return err;
1601*e5436536SAndroid Build Coastguard Worker if ((offset + i) >= 12) continue;
1602*e5436536SAndroid Build Coastguard Worker if (!diff)
1603*e5436536SAndroid Build Coastguard Worker diff |= (FDKmemcmp(&tmpInst,
1604*e5436536SAndroid Build Coastguard Worker &(hUniDrcConfig->drcInstructionsUniDrc[offset + i]),
1605*e5436536SAndroid Build Coastguard Worker sizeof(DRC_INSTRUCTIONS_UNI_DRC)) != 0);
1606*e5436536SAndroid Build Coastguard Worker hUniDrcConfig->drcInstructionsUniDrc[offset + i] = tmpInst;
1607*e5436536SAndroid Build Coastguard Worker }
1608*e5436536SAndroid Build Coastguard Worker } else {
1609*e5436536SAndroid Build Coastguard Worker diff |= _compAssign(&hUniDrcConfig->drcCoefficientsUniDrcCountV1, 0);
1610*e5436536SAndroid Build Coastguard Worker diff |= _compAssign(&hUniDrcConfig->drcInstructionsUniDrcCountV1, 0);
1611*e5436536SAndroid Build Coastguard Worker }
1612*e5436536SAndroid Build Coastguard Worker
1613*e5436536SAndroid Build Coastguard Worker loudEqInstructionsPresent = FDKreadBits(hBs, 1);
1614*e5436536SAndroid Build Coastguard Worker if (loudEqInstructionsPresent == 1) {
1615*e5436536SAndroid Build Coastguard Worker loudEqInstructionsCount = FDKreadBits(hBs, 4);
1616*e5436536SAndroid Build Coastguard Worker for (i = 0; i < loudEqInstructionsCount; i++) {
1617*e5436536SAndroid Build Coastguard Worker _skipLoudEqInstructions(hBs);
1618*e5436536SAndroid Build Coastguard Worker }
1619*e5436536SAndroid Build Coastguard Worker }
1620*e5436536SAndroid Build Coastguard Worker
1621*e5436536SAndroid Build Coastguard Worker eqPresent = FDKreadBits(hBs, 1);
1622*e5436536SAndroid Build Coastguard Worker if (eqPresent == 1) {
1623*e5436536SAndroid Build Coastguard Worker _skipEqCoefficients(hBs);
1624*e5436536SAndroid Build Coastguard Worker eqInstructionsCount = FDKreadBits(hBs, 4);
1625*e5436536SAndroid Build Coastguard Worker for (i = 0; i < eqInstructionsCount; i++) {
1626*e5436536SAndroid Build Coastguard Worker _skipEqInstructions(hBs, hUniDrcConfig);
1627*e5436536SAndroid Build Coastguard Worker }
1628*e5436536SAndroid Build Coastguard Worker }
1629*e5436536SAndroid Build Coastguard Worker
1630*e5436536SAndroid Build Coastguard Worker hUniDrcConfig->diff = diff;
1631*e5436536SAndroid Build Coastguard Worker
1632*e5436536SAndroid Build Coastguard Worker return err;
1633*e5436536SAndroid Build Coastguard Worker }
1634*e5436536SAndroid Build Coastguard Worker
_readUniDrcConfigExtension(HANDLE_FDK_BITSTREAM hBs,HANDLE_UNI_DRC_CONFIG hUniDrcConfig)1635*e5436536SAndroid Build Coastguard Worker static DRC_ERROR _readUniDrcConfigExtension(
1636*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM hBs, HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
1637*e5436536SAndroid Build Coastguard Worker DRC_ERROR err = DE_OK;
1638*e5436536SAndroid Build Coastguard Worker int k, bitSizeLen, extSizeBits, bitSize;
1639*e5436536SAndroid Build Coastguard Worker INT nBitsRemaining;
1640*e5436536SAndroid Build Coastguard Worker UNI_DRC_CONFIG_EXTENSION* pExt = &(hUniDrcConfig->uniDrcConfigExt);
1641*e5436536SAndroid Build Coastguard Worker
1642*e5436536SAndroid Build Coastguard Worker k = 0;
1643*e5436536SAndroid Build Coastguard Worker pExt->uniDrcConfigExtType[k] = FDKreadBits(hBs, 4);
1644*e5436536SAndroid Build Coastguard Worker while (pExt->uniDrcConfigExtType[k] != UNIDRCCONFEXT_TERM) {
1645*e5436536SAndroid Build Coastguard Worker if (k >= (8 - 1)) return DE_MEMORY_ERROR;
1646*e5436536SAndroid Build Coastguard Worker bitSizeLen = FDKreadBits(hBs, 4);
1647*e5436536SAndroid Build Coastguard Worker extSizeBits = bitSizeLen + 4;
1648*e5436536SAndroid Build Coastguard Worker
1649*e5436536SAndroid Build Coastguard Worker bitSize = FDKreadBits(hBs, extSizeBits);
1650*e5436536SAndroid Build Coastguard Worker pExt->extBitSize[k] = bitSize + 1;
1651*e5436536SAndroid Build Coastguard Worker nBitsRemaining = (INT)FDKgetValidBits(hBs);
1652*e5436536SAndroid Build Coastguard Worker
1653*e5436536SAndroid Build Coastguard Worker switch (pExt->uniDrcConfigExtType[k]) {
1654*e5436536SAndroid Build Coastguard Worker case UNIDRCCONFEXT_V1:
1655*e5436536SAndroid Build Coastguard Worker err = _readDrcExtensionV1(hBs, hUniDrcConfig);
1656*e5436536SAndroid Build Coastguard Worker if (err) return err;
1657*e5436536SAndroid Build Coastguard Worker if (nBitsRemaining !=
1658*e5436536SAndroid Build Coastguard Worker ((INT)pExt->extBitSize[k] + (INT)FDKgetValidBits(hBs)))
1659*e5436536SAndroid Build Coastguard Worker return DE_NOT_OK;
1660*e5436536SAndroid Build Coastguard Worker break;
1661*e5436536SAndroid Build Coastguard Worker case UNIDRCCONFEXT_PARAM_DRC:
1662*e5436536SAndroid Build Coastguard Worker /* add future extensions here */
1663*e5436536SAndroid Build Coastguard Worker default:
1664*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, pExt->extBitSize[k]);
1665*e5436536SAndroid Build Coastguard Worker break;
1666*e5436536SAndroid Build Coastguard Worker }
1667*e5436536SAndroid Build Coastguard Worker k++;
1668*e5436536SAndroid Build Coastguard Worker pExt->uniDrcConfigExtType[k] = FDKreadBits(hBs, 4);
1669*e5436536SAndroid Build Coastguard Worker }
1670*e5436536SAndroid Build Coastguard Worker
1671*e5436536SAndroid Build Coastguard Worker return err;
1672*e5436536SAndroid Build Coastguard Worker }
1673*e5436536SAndroid Build Coastguard Worker
1674*e5436536SAndroid Build Coastguard Worker DRC_ERROR
drcDec_readUniDrcConfig(HANDLE_FDK_BITSTREAM hBs,HANDLE_UNI_DRC_CONFIG hUniDrcConfig)1675*e5436536SAndroid Build Coastguard Worker drcDec_readUniDrcConfig(HANDLE_FDK_BITSTREAM hBs,
1676*e5436536SAndroid Build Coastguard Worker HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
1677*e5436536SAndroid Build Coastguard Worker DRC_ERROR err = DE_OK;
1678*e5436536SAndroid Build Coastguard Worker int i, diff = 0;
1679*e5436536SAndroid Build Coastguard Worker int drcDescriptionBasicPresent, drcCoefficientsBasicCount,
1680*e5436536SAndroid Build Coastguard Worker drcInstructionsBasicCount;
1681*e5436536SAndroid Build Coastguard Worker CHANNEL_LAYOUT tmpChan;
1682*e5436536SAndroid Build Coastguard Worker FDKmemclear(&tmpChan, sizeof(CHANNEL_LAYOUT));
1683*e5436536SAndroid Build Coastguard Worker if (hUniDrcConfig == NULL) return DE_NOT_OK;
1684*e5436536SAndroid Build Coastguard Worker
1685*e5436536SAndroid Build Coastguard Worker diff |= _compAssign(&hUniDrcConfig->sampleRatePresent, FDKreadBits(hBs, 1));
1686*e5436536SAndroid Build Coastguard Worker
1687*e5436536SAndroid Build Coastguard Worker if (hUniDrcConfig->sampleRatePresent == 1) {
1688*e5436536SAndroid Build Coastguard Worker diff |=
1689*e5436536SAndroid Build Coastguard Worker _compAssign(&hUniDrcConfig->sampleRate, FDKreadBits(hBs, 18) + 1000);
1690*e5436536SAndroid Build Coastguard Worker }
1691*e5436536SAndroid Build Coastguard Worker
1692*e5436536SAndroid Build Coastguard Worker diff |= _compAssign(&hUniDrcConfig->downmixInstructionsCountV0,
1693*e5436536SAndroid Build Coastguard Worker FDKreadBits(hBs, 7));
1694*e5436536SAndroid Build Coastguard Worker
1695*e5436536SAndroid Build Coastguard Worker drcDescriptionBasicPresent = FDKreadBits(hBs, 1);
1696*e5436536SAndroid Build Coastguard Worker if (drcDescriptionBasicPresent == 1) {
1697*e5436536SAndroid Build Coastguard Worker drcCoefficientsBasicCount = FDKreadBits(hBs, 3);
1698*e5436536SAndroid Build Coastguard Worker drcInstructionsBasicCount = FDKreadBits(hBs, 4);
1699*e5436536SAndroid Build Coastguard Worker } else {
1700*e5436536SAndroid Build Coastguard Worker drcCoefficientsBasicCount = 0;
1701*e5436536SAndroid Build Coastguard Worker drcInstructionsBasicCount = 0;
1702*e5436536SAndroid Build Coastguard Worker }
1703*e5436536SAndroid Build Coastguard Worker
1704*e5436536SAndroid Build Coastguard Worker diff |= _compAssign(&hUniDrcConfig->drcCoefficientsUniDrcCountV0,
1705*e5436536SAndroid Build Coastguard Worker FDKreadBits(hBs, 3));
1706*e5436536SAndroid Build Coastguard Worker diff |= _compAssign(&hUniDrcConfig->drcInstructionsUniDrcCountV0,
1707*e5436536SAndroid Build Coastguard Worker FDKreadBits(hBs, 6));
1708*e5436536SAndroid Build Coastguard Worker
1709*e5436536SAndroid Build Coastguard Worker err = _readChannelLayout(hBs, &tmpChan);
1710*e5436536SAndroid Build Coastguard Worker if (err) return err;
1711*e5436536SAndroid Build Coastguard Worker
1712*e5436536SAndroid Build Coastguard Worker if (!diff)
1713*e5436536SAndroid Build Coastguard Worker diff |= (FDKmemcmp(&tmpChan, &hUniDrcConfig->channelLayout,
1714*e5436536SAndroid Build Coastguard Worker sizeof(CHANNEL_LAYOUT)) != 0);
1715*e5436536SAndroid Build Coastguard Worker hUniDrcConfig->channelLayout = tmpChan;
1716*e5436536SAndroid Build Coastguard Worker
1717*e5436536SAndroid Build Coastguard Worker hUniDrcConfig->downmixInstructionsCount =
1718*e5436536SAndroid Build Coastguard Worker fMin(hUniDrcConfig->downmixInstructionsCountV0, (UCHAR)6);
1719*e5436536SAndroid Build Coastguard Worker for (i = 0; i < hUniDrcConfig->downmixInstructionsCountV0; i++) {
1720*e5436536SAndroid Build Coastguard Worker DOWNMIX_INSTRUCTIONS tmpDown;
1721*e5436536SAndroid Build Coastguard Worker FDKmemclear(&tmpDown, sizeof(DOWNMIX_INSTRUCTIONS));
1722*e5436536SAndroid Build Coastguard Worker err = _readDownmixInstructions(hBs, 0, &hUniDrcConfig->channelLayout,
1723*e5436536SAndroid Build Coastguard Worker &tmpDown);
1724*e5436536SAndroid Build Coastguard Worker if (err) return err;
1725*e5436536SAndroid Build Coastguard Worker if (i >= 6) continue;
1726*e5436536SAndroid Build Coastguard Worker if (!diff)
1727*e5436536SAndroid Build Coastguard Worker diff |= (FDKmemcmp(&tmpDown, &(hUniDrcConfig->downmixInstructions[i]),
1728*e5436536SAndroid Build Coastguard Worker sizeof(DOWNMIX_INSTRUCTIONS)) != 0);
1729*e5436536SAndroid Build Coastguard Worker hUniDrcConfig->downmixInstructions[i] = tmpDown;
1730*e5436536SAndroid Build Coastguard Worker }
1731*e5436536SAndroid Build Coastguard Worker
1732*e5436536SAndroid Build Coastguard Worker for (i = 0; i < drcCoefficientsBasicCount; i++) {
1733*e5436536SAndroid Build Coastguard Worker _skipDrcCoefficientsBasic(hBs);
1734*e5436536SAndroid Build Coastguard Worker }
1735*e5436536SAndroid Build Coastguard Worker for (i = 0; i < drcInstructionsBasicCount; i++) {
1736*e5436536SAndroid Build Coastguard Worker _skipDrcInstructionsBasic(hBs);
1737*e5436536SAndroid Build Coastguard Worker }
1738*e5436536SAndroid Build Coastguard Worker
1739*e5436536SAndroid Build Coastguard Worker hUniDrcConfig->drcCoefficientsUniDrcCount =
1740*e5436536SAndroid Build Coastguard Worker fMin(hUniDrcConfig->drcCoefficientsUniDrcCountV0, (UCHAR)2);
1741*e5436536SAndroid Build Coastguard Worker for (i = 0; i < hUniDrcConfig->drcCoefficientsUniDrcCountV0; i++) {
1742*e5436536SAndroid Build Coastguard Worker DRC_COEFFICIENTS_UNI_DRC tmpCoef;
1743*e5436536SAndroid Build Coastguard Worker FDKmemclear(&tmpCoef, sizeof(DRC_COEFFICIENTS_UNI_DRC));
1744*e5436536SAndroid Build Coastguard Worker err = _readDrcCoefficientsUniDrc(hBs, 0, &tmpCoef);
1745*e5436536SAndroid Build Coastguard Worker if (err) return err;
1746*e5436536SAndroid Build Coastguard Worker if (i >= 2) continue;
1747*e5436536SAndroid Build Coastguard Worker if (!diff)
1748*e5436536SAndroid Build Coastguard Worker diff |= (FDKmemcmp(&tmpCoef, &(hUniDrcConfig->drcCoefficientsUniDrc[i]),
1749*e5436536SAndroid Build Coastguard Worker sizeof(DRC_COEFFICIENTS_UNI_DRC)) != 0);
1750*e5436536SAndroid Build Coastguard Worker hUniDrcConfig->drcCoefficientsUniDrc[i] = tmpCoef;
1751*e5436536SAndroid Build Coastguard Worker }
1752*e5436536SAndroid Build Coastguard Worker
1753*e5436536SAndroid Build Coastguard Worker hUniDrcConfig->drcInstructionsUniDrcCount =
1754*e5436536SAndroid Build Coastguard Worker fMin(hUniDrcConfig->drcInstructionsUniDrcCountV0, (UCHAR)12);
1755*e5436536SAndroid Build Coastguard Worker for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCountV0; i++) {
1756*e5436536SAndroid Build Coastguard Worker DRC_INSTRUCTIONS_UNI_DRC tmpInst;
1757*e5436536SAndroid Build Coastguard Worker FDKmemclear(&tmpInst, sizeof(DRC_INSTRUCTIONS_UNI_DRC));
1758*e5436536SAndroid Build Coastguard Worker err = _readDrcInstructionsUniDrc(hBs, 0, hUniDrcConfig, &tmpInst);
1759*e5436536SAndroid Build Coastguard Worker if (err) return err;
1760*e5436536SAndroid Build Coastguard Worker if (i >= 12) continue;
1761*e5436536SAndroid Build Coastguard Worker if (!diff)
1762*e5436536SAndroid Build Coastguard Worker diff |= (FDKmemcmp(&tmpInst, &(hUniDrcConfig->drcInstructionsUniDrc[i]),
1763*e5436536SAndroid Build Coastguard Worker sizeof(DRC_INSTRUCTIONS_UNI_DRC)) != 0);
1764*e5436536SAndroid Build Coastguard Worker hUniDrcConfig->drcInstructionsUniDrc[i] = tmpInst;
1765*e5436536SAndroid Build Coastguard Worker }
1766*e5436536SAndroid Build Coastguard Worker
1767*e5436536SAndroid Build Coastguard Worker diff |=
1768*e5436536SAndroid Build Coastguard Worker _compAssign(&hUniDrcConfig->uniDrcConfigExtPresent, FDKreadBits(hBs, 1));
1769*e5436536SAndroid Build Coastguard Worker hUniDrcConfig->diff = diff;
1770*e5436536SAndroid Build Coastguard Worker
1771*e5436536SAndroid Build Coastguard Worker if (hUniDrcConfig->uniDrcConfigExtPresent == 1) {
1772*e5436536SAndroid Build Coastguard Worker err = _readUniDrcConfigExtension(hBs, hUniDrcConfig);
1773*e5436536SAndroid Build Coastguard Worker if (err) return err;
1774*e5436536SAndroid Build Coastguard Worker }
1775*e5436536SAndroid Build Coastguard Worker
1776*e5436536SAndroid Build Coastguard Worker return err;
1777*e5436536SAndroid Build Coastguard Worker }
1778*e5436536SAndroid Build Coastguard Worker
1779*e5436536SAndroid Build Coastguard Worker /*******************/
1780*e5436536SAndroid Build Coastguard Worker /* loudnessInfoSet */
1781*e5436536SAndroid Build Coastguard Worker /*******************/
1782*e5436536SAndroid Build Coastguard Worker
_decodeMethodValue(HANDLE_FDK_BITSTREAM hBs,const UCHAR methodDefinition,FIXP_DBL * methodValue,INT isBox)1783*e5436536SAndroid Build Coastguard Worker static DRC_ERROR _decodeMethodValue(HANDLE_FDK_BITSTREAM hBs,
1784*e5436536SAndroid Build Coastguard Worker const UCHAR methodDefinition,
1785*e5436536SAndroid Build Coastguard Worker FIXP_DBL* methodValue, INT isBox) {
1786*e5436536SAndroid Build Coastguard Worker int tmp;
1787*e5436536SAndroid Build Coastguard Worker FIXP_DBL val;
1788*e5436536SAndroid Build Coastguard Worker switch (methodDefinition) {
1789*e5436536SAndroid Build Coastguard Worker case MD_UNKNOWN_OTHER:
1790*e5436536SAndroid Build Coastguard Worker case MD_PROGRAM_LOUDNESS:
1791*e5436536SAndroid Build Coastguard Worker case MD_ANCHOR_LOUDNESS:
1792*e5436536SAndroid Build Coastguard Worker case MD_MAX_OF_LOUDNESS_RANGE:
1793*e5436536SAndroid Build Coastguard Worker case MD_MOMENTARY_LOUDNESS_MAX:
1794*e5436536SAndroid Build Coastguard Worker case MD_SHORT_TERM_LOUDNESS_MAX:
1795*e5436536SAndroid Build Coastguard Worker tmp = FDKreadBits(hBs, 8);
1796*e5436536SAndroid Build Coastguard Worker val = FL2FXCONST_DBL(-57.75f / (float)(1 << 7)) +
1797*e5436536SAndroid Build Coastguard Worker (FIXP_DBL)(
1798*e5436536SAndroid Build Coastguard Worker tmp << (DFRACT_BITS - 1 - 2 - 7)); /* -57.75 + tmp * 0.25; */
1799*e5436536SAndroid Build Coastguard Worker break;
1800*e5436536SAndroid Build Coastguard Worker case MD_LOUDNESS_RANGE:
1801*e5436536SAndroid Build Coastguard Worker tmp = FDKreadBits(hBs, 8);
1802*e5436536SAndroid Build Coastguard Worker if (tmp == 0)
1803*e5436536SAndroid Build Coastguard Worker val = (FIXP_DBL)0;
1804*e5436536SAndroid Build Coastguard Worker else if (tmp <= 128)
1805*e5436536SAndroid Build Coastguard Worker val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 2 - 7)); /* tmp * 0.25; */
1806*e5436536SAndroid Build Coastguard Worker else if (tmp <= 204) {
1807*e5436536SAndroid Build Coastguard Worker val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 1 - 7)) -
1808*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(32.0f / (float)(1 << 7)); /* 0.5 * tmp - 32.0f; */
1809*e5436536SAndroid Build Coastguard Worker } else {
1810*e5436536SAndroid Build Coastguard Worker /* downscale by 1 more bit to prevent overflow at intermediate result */
1811*e5436536SAndroid Build Coastguard Worker val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 8)) -
1812*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(134.0f / (float)(1 << 8)); /* tmp - 134.0; */
1813*e5436536SAndroid Build Coastguard Worker val <<= 1;
1814*e5436536SAndroid Build Coastguard Worker }
1815*e5436536SAndroid Build Coastguard Worker break;
1816*e5436536SAndroid Build Coastguard Worker case MD_MIXING_LEVEL:
1817*e5436536SAndroid Build Coastguard Worker tmp = FDKreadBits(hBs, isBox ? 8 : 5);
1818*e5436536SAndroid Build Coastguard Worker val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 7)) +
1819*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(80.0f / (float)(1 << 7)); /* tmp + 80.0; */
1820*e5436536SAndroid Build Coastguard Worker break;
1821*e5436536SAndroid Build Coastguard Worker case MD_ROOM_TYPE:
1822*e5436536SAndroid Build Coastguard Worker tmp = FDKreadBits(hBs, isBox ? 8 : 2);
1823*e5436536SAndroid Build Coastguard Worker val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 7)); /* tmp; */
1824*e5436536SAndroid Build Coastguard Worker break;
1825*e5436536SAndroid Build Coastguard Worker case MD_SHORT_TERM_LOUDNESS:
1826*e5436536SAndroid Build Coastguard Worker tmp = FDKreadBits(hBs, 8);
1827*e5436536SAndroid Build Coastguard Worker val = FL2FXCONST_DBL(-116.0f / (float)(1 << 7)) +
1828*e5436536SAndroid Build Coastguard Worker (FIXP_DBL)(
1829*e5436536SAndroid Build Coastguard Worker tmp << (DFRACT_BITS - 1 - 1 - 7)); /* -116.0 + tmp * 0.5; */
1830*e5436536SAndroid Build Coastguard Worker break;
1831*e5436536SAndroid Build Coastguard Worker default:
1832*e5436536SAndroid Build Coastguard Worker return DE_NOT_OK; /* invalid methodDefinition value */
1833*e5436536SAndroid Build Coastguard Worker }
1834*e5436536SAndroid Build Coastguard Worker *methodValue = val;
1835*e5436536SAndroid Build Coastguard Worker return DE_OK;
1836*e5436536SAndroid Build Coastguard Worker }
1837*e5436536SAndroid Build Coastguard Worker
_readLoudnessMeasurement(HANDLE_FDK_BITSTREAM hBs,LOUDNESS_MEASUREMENT * pMeas)1838*e5436536SAndroid Build Coastguard Worker static DRC_ERROR _readLoudnessMeasurement(HANDLE_FDK_BITSTREAM hBs,
1839*e5436536SAndroid Build Coastguard Worker LOUDNESS_MEASUREMENT* pMeas) {
1840*e5436536SAndroid Build Coastguard Worker DRC_ERROR err = DE_OK;
1841*e5436536SAndroid Build Coastguard Worker
1842*e5436536SAndroid Build Coastguard Worker pMeas->methodDefinition = FDKreadBits(hBs, 4);
1843*e5436536SAndroid Build Coastguard Worker err =
1844*e5436536SAndroid Build Coastguard Worker _decodeMethodValue(hBs, pMeas->methodDefinition, &pMeas->methodValue, 0);
1845*e5436536SAndroid Build Coastguard Worker if (err) return err;
1846*e5436536SAndroid Build Coastguard Worker pMeas->measurementSystem = FDKreadBits(hBs, 4);
1847*e5436536SAndroid Build Coastguard Worker pMeas->reliability = FDKreadBits(hBs, 2);
1848*e5436536SAndroid Build Coastguard Worker
1849*e5436536SAndroid Build Coastguard Worker return err;
1850*e5436536SAndroid Build Coastguard Worker }
1851*e5436536SAndroid Build Coastguard Worker
_readLoudnessInfo(HANDLE_FDK_BITSTREAM hBs,const int version,LOUDNESS_INFO * loudnessInfo)1852*e5436536SAndroid Build Coastguard Worker static DRC_ERROR _readLoudnessInfo(HANDLE_FDK_BITSTREAM hBs, const int version,
1853*e5436536SAndroid Build Coastguard Worker LOUDNESS_INFO* loudnessInfo) {
1854*e5436536SAndroid Build Coastguard Worker DRC_ERROR err = DE_OK;
1855*e5436536SAndroid Build Coastguard Worker int bsSamplePeakLevel, bsTruePeakLevel, i;
1856*e5436536SAndroid Build Coastguard Worker int measurementCount;
1857*e5436536SAndroid Build Coastguard Worker
1858*e5436536SAndroid Build Coastguard Worker loudnessInfo->drcSetId = FDKreadBits(hBs, 6);
1859*e5436536SAndroid Build Coastguard Worker if (version >= 1) {
1860*e5436536SAndroid Build Coastguard Worker loudnessInfo->eqSetId = FDKreadBits(hBs, 6);
1861*e5436536SAndroid Build Coastguard Worker } else {
1862*e5436536SAndroid Build Coastguard Worker loudnessInfo->eqSetId = 0;
1863*e5436536SAndroid Build Coastguard Worker }
1864*e5436536SAndroid Build Coastguard Worker loudnessInfo->downmixId = FDKreadBits(hBs, 7);
1865*e5436536SAndroid Build Coastguard Worker
1866*e5436536SAndroid Build Coastguard Worker loudnessInfo->samplePeakLevelPresent = FDKreadBits(hBs, 1);
1867*e5436536SAndroid Build Coastguard Worker if (loudnessInfo->samplePeakLevelPresent) {
1868*e5436536SAndroid Build Coastguard Worker bsSamplePeakLevel = FDKreadBits(hBs, 12);
1869*e5436536SAndroid Build Coastguard Worker if (bsSamplePeakLevel == 0) {
1870*e5436536SAndroid Build Coastguard Worker loudnessInfo->samplePeakLevelPresent = 0;
1871*e5436536SAndroid Build Coastguard Worker loudnessInfo->samplePeakLevel = (FIXP_DBL)0;
1872*e5436536SAndroid Build Coastguard Worker } else { /* 20.0 - bsSamplePeakLevel * 0.03125; */
1873*e5436536SAndroid Build Coastguard Worker loudnessInfo->samplePeakLevel =
1874*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(20.0f / (float)(1 << 7)) -
1875*e5436536SAndroid Build Coastguard Worker (FIXP_DBL)(bsSamplePeakLevel << (DFRACT_BITS - 1 - 5 - 7));
1876*e5436536SAndroid Build Coastguard Worker }
1877*e5436536SAndroid Build Coastguard Worker }
1878*e5436536SAndroid Build Coastguard Worker
1879*e5436536SAndroid Build Coastguard Worker loudnessInfo->truePeakLevelPresent = FDKreadBits(hBs, 1);
1880*e5436536SAndroid Build Coastguard Worker if (loudnessInfo->truePeakLevelPresent) {
1881*e5436536SAndroid Build Coastguard Worker bsTruePeakLevel = FDKreadBits(hBs, 12);
1882*e5436536SAndroid Build Coastguard Worker if (bsTruePeakLevel == 0) {
1883*e5436536SAndroid Build Coastguard Worker loudnessInfo->truePeakLevelPresent = 0;
1884*e5436536SAndroid Build Coastguard Worker loudnessInfo->truePeakLevel = (FIXP_DBL)0;
1885*e5436536SAndroid Build Coastguard Worker } else {
1886*e5436536SAndroid Build Coastguard Worker loudnessInfo->truePeakLevel =
1887*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(20.0f / (float)(1 << 7)) -
1888*e5436536SAndroid Build Coastguard Worker (FIXP_DBL)(bsTruePeakLevel << (DFRACT_BITS - 1 - 5 - 7));
1889*e5436536SAndroid Build Coastguard Worker }
1890*e5436536SAndroid Build Coastguard Worker loudnessInfo->truePeakLevelMeasurementSystem = FDKreadBits(hBs, 4);
1891*e5436536SAndroid Build Coastguard Worker loudnessInfo->truePeakLevelReliability = FDKreadBits(hBs, 2);
1892*e5436536SAndroid Build Coastguard Worker }
1893*e5436536SAndroid Build Coastguard Worker
1894*e5436536SAndroid Build Coastguard Worker measurementCount = FDKreadBits(hBs, 4);
1895*e5436536SAndroid Build Coastguard Worker loudnessInfo->measurementCount = fMin(measurementCount, 8);
1896*e5436536SAndroid Build Coastguard Worker for (i = 0; i < measurementCount; i++) {
1897*e5436536SAndroid Build Coastguard Worker LOUDNESS_MEASUREMENT tmpMeas;
1898*e5436536SAndroid Build Coastguard Worker FDKmemclear(&tmpMeas, sizeof(LOUDNESS_MEASUREMENT));
1899*e5436536SAndroid Build Coastguard Worker err = _readLoudnessMeasurement(hBs, &tmpMeas);
1900*e5436536SAndroid Build Coastguard Worker if (err) return err;
1901*e5436536SAndroid Build Coastguard Worker if (i >= 8) continue;
1902*e5436536SAndroid Build Coastguard Worker loudnessInfo->loudnessMeasurement[i] = tmpMeas;
1903*e5436536SAndroid Build Coastguard Worker }
1904*e5436536SAndroid Build Coastguard Worker
1905*e5436536SAndroid Build Coastguard Worker return err;
1906*e5436536SAndroid Build Coastguard Worker }
1907*e5436536SAndroid Build Coastguard Worker
_readLoudnessInfoSetExtEq(HANDLE_FDK_BITSTREAM hBs,HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet)1908*e5436536SAndroid Build Coastguard Worker static DRC_ERROR _readLoudnessInfoSetExtEq(
1909*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM hBs, HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet) {
1910*e5436536SAndroid Build Coastguard Worker DRC_ERROR err = DE_OK;
1911*e5436536SAndroid Build Coastguard Worker int i, offset;
1912*e5436536SAndroid Build Coastguard Worker int diff = hLoudnessInfoSet->diff;
1913*e5436536SAndroid Build Coastguard Worker
1914*e5436536SAndroid Build Coastguard Worker diff |= _compAssign(&hLoudnessInfoSet->loudnessInfoAlbumCountV1,
1915*e5436536SAndroid Build Coastguard Worker FDKreadBits(hBs, 6));
1916*e5436536SAndroid Build Coastguard Worker diff |=
1917*e5436536SAndroid Build Coastguard Worker _compAssign(&hLoudnessInfoSet->loudnessInfoCountV1, FDKreadBits(hBs, 6));
1918*e5436536SAndroid Build Coastguard Worker
1919*e5436536SAndroid Build Coastguard Worker offset = hLoudnessInfoSet->loudnessInfoAlbumCountV0;
1920*e5436536SAndroid Build Coastguard Worker hLoudnessInfoSet->loudnessInfoAlbumCount = fMin(
1921*e5436536SAndroid Build Coastguard Worker (UCHAR)(offset + hLoudnessInfoSet->loudnessInfoAlbumCountV1), (UCHAR)12);
1922*e5436536SAndroid Build Coastguard Worker for (i = 0; i < hLoudnessInfoSet->loudnessInfoAlbumCountV1; i++) {
1923*e5436536SAndroid Build Coastguard Worker LOUDNESS_INFO tmpLoud;
1924*e5436536SAndroid Build Coastguard Worker FDKmemclear(&tmpLoud, sizeof(LOUDNESS_INFO));
1925*e5436536SAndroid Build Coastguard Worker err = _readLoudnessInfo(hBs, 1, &tmpLoud);
1926*e5436536SAndroid Build Coastguard Worker if (err) return err;
1927*e5436536SAndroid Build Coastguard Worker if ((offset + i) >= 12) continue;
1928*e5436536SAndroid Build Coastguard Worker if (!diff)
1929*e5436536SAndroid Build Coastguard Worker diff |= (FDKmemcmp(&tmpLoud,
1930*e5436536SAndroid Build Coastguard Worker &(hLoudnessInfoSet->loudnessInfoAlbum[offset + i]),
1931*e5436536SAndroid Build Coastguard Worker sizeof(LOUDNESS_INFO)) != 0);
1932*e5436536SAndroid Build Coastguard Worker hLoudnessInfoSet->loudnessInfoAlbum[offset + i] = tmpLoud;
1933*e5436536SAndroid Build Coastguard Worker }
1934*e5436536SAndroid Build Coastguard Worker
1935*e5436536SAndroid Build Coastguard Worker offset = hLoudnessInfoSet->loudnessInfoCountV0;
1936*e5436536SAndroid Build Coastguard Worker hLoudnessInfoSet->loudnessInfoCount =
1937*e5436536SAndroid Build Coastguard Worker fMin((UCHAR)(offset + hLoudnessInfoSet->loudnessInfoCountV1), (UCHAR)12);
1938*e5436536SAndroid Build Coastguard Worker for (i = 0; i < hLoudnessInfoSet->loudnessInfoCountV1; i++) {
1939*e5436536SAndroid Build Coastguard Worker LOUDNESS_INFO tmpLoud;
1940*e5436536SAndroid Build Coastguard Worker FDKmemclear(&tmpLoud, sizeof(LOUDNESS_INFO));
1941*e5436536SAndroid Build Coastguard Worker err = _readLoudnessInfo(hBs, 1, &tmpLoud);
1942*e5436536SAndroid Build Coastguard Worker if (err) return err;
1943*e5436536SAndroid Build Coastguard Worker if ((offset + i) >= 12) continue;
1944*e5436536SAndroid Build Coastguard Worker if (!diff)
1945*e5436536SAndroid Build Coastguard Worker diff |=
1946*e5436536SAndroid Build Coastguard Worker (FDKmemcmp(&tmpLoud, &(hLoudnessInfoSet->loudnessInfo[offset + i]),
1947*e5436536SAndroid Build Coastguard Worker sizeof(LOUDNESS_INFO)) != 0);
1948*e5436536SAndroid Build Coastguard Worker hLoudnessInfoSet->loudnessInfo[offset + i] = tmpLoud;
1949*e5436536SAndroid Build Coastguard Worker }
1950*e5436536SAndroid Build Coastguard Worker hLoudnessInfoSet->diff = diff;
1951*e5436536SAndroid Build Coastguard Worker return err;
1952*e5436536SAndroid Build Coastguard Worker }
1953*e5436536SAndroid Build Coastguard Worker
_readLoudnessInfoSetExtension(HANDLE_FDK_BITSTREAM hBs,HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet)1954*e5436536SAndroid Build Coastguard Worker static DRC_ERROR _readLoudnessInfoSetExtension(
1955*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM hBs, HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet) {
1956*e5436536SAndroid Build Coastguard Worker DRC_ERROR err = DE_OK;
1957*e5436536SAndroid Build Coastguard Worker int k, bitSizeLen, extSizeBits, bitSize;
1958*e5436536SAndroid Build Coastguard Worker INT nBitsRemaining;
1959*e5436536SAndroid Build Coastguard Worker LOUDNESS_INFO_SET_EXTENSION* pExt = &(hLoudnessInfoSet->loudnessInfoSetExt);
1960*e5436536SAndroid Build Coastguard Worker
1961*e5436536SAndroid Build Coastguard Worker k = 0;
1962*e5436536SAndroid Build Coastguard Worker pExt->loudnessInfoSetExtType[k] = FDKreadBits(hBs, 4);
1963*e5436536SAndroid Build Coastguard Worker while (pExt->loudnessInfoSetExtType[k] != UNIDRCLOUDEXT_TERM) {
1964*e5436536SAndroid Build Coastguard Worker if (k >= (8 - 1)) return DE_MEMORY_ERROR;
1965*e5436536SAndroid Build Coastguard Worker bitSizeLen = FDKreadBits(hBs, 4);
1966*e5436536SAndroid Build Coastguard Worker extSizeBits = bitSizeLen + 4;
1967*e5436536SAndroid Build Coastguard Worker
1968*e5436536SAndroid Build Coastguard Worker bitSize = FDKreadBits(hBs, extSizeBits);
1969*e5436536SAndroid Build Coastguard Worker pExt->extBitSize[k] = bitSize + 1;
1970*e5436536SAndroid Build Coastguard Worker nBitsRemaining = (INT)FDKgetValidBits(hBs);
1971*e5436536SAndroid Build Coastguard Worker
1972*e5436536SAndroid Build Coastguard Worker switch (pExt->loudnessInfoSetExtType[k]) {
1973*e5436536SAndroid Build Coastguard Worker case UNIDRCLOUDEXT_EQ:
1974*e5436536SAndroid Build Coastguard Worker err = _readLoudnessInfoSetExtEq(hBs, hLoudnessInfoSet);
1975*e5436536SAndroid Build Coastguard Worker if (err) return err;
1976*e5436536SAndroid Build Coastguard Worker if (nBitsRemaining !=
1977*e5436536SAndroid Build Coastguard Worker ((INT)pExt->extBitSize[k] + (INT)FDKgetValidBits(hBs)))
1978*e5436536SAndroid Build Coastguard Worker return DE_NOT_OK;
1979*e5436536SAndroid Build Coastguard Worker break;
1980*e5436536SAndroid Build Coastguard Worker /* add future extensions here */
1981*e5436536SAndroid Build Coastguard Worker default:
1982*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, pExt->extBitSize[k]);
1983*e5436536SAndroid Build Coastguard Worker break;
1984*e5436536SAndroid Build Coastguard Worker }
1985*e5436536SAndroid Build Coastguard Worker k++;
1986*e5436536SAndroid Build Coastguard Worker pExt->loudnessInfoSetExtType[k] = FDKreadBits(hBs, 4);
1987*e5436536SAndroid Build Coastguard Worker }
1988*e5436536SAndroid Build Coastguard Worker
1989*e5436536SAndroid Build Coastguard Worker return err;
1990*e5436536SAndroid Build Coastguard Worker }
1991*e5436536SAndroid Build Coastguard Worker
1992*e5436536SAndroid Build Coastguard Worker /* Parser for loundessInfoSet() */
1993*e5436536SAndroid Build Coastguard Worker DRC_ERROR
drcDec_readLoudnessInfoSet(HANDLE_FDK_BITSTREAM hBs,HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet)1994*e5436536SAndroid Build Coastguard Worker drcDec_readLoudnessInfoSet(HANDLE_FDK_BITSTREAM hBs,
1995*e5436536SAndroid Build Coastguard Worker HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet) {
1996*e5436536SAndroid Build Coastguard Worker DRC_ERROR err = DE_OK;
1997*e5436536SAndroid Build Coastguard Worker int i, diff = 0;
1998*e5436536SAndroid Build Coastguard Worker if (hLoudnessInfoSet == NULL) return DE_NOT_OK;
1999*e5436536SAndroid Build Coastguard Worker
2000*e5436536SAndroid Build Coastguard Worker diff |= _compAssign(&hLoudnessInfoSet->loudnessInfoAlbumCountV0,
2001*e5436536SAndroid Build Coastguard Worker FDKreadBits(hBs, 6));
2002*e5436536SAndroid Build Coastguard Worker diff |=
2003*e5436536SAndroid Build Coastguard Worker _compAssign(&hLoudnessInfoSet->loudnessInfoCountV0, FDKreadBits(hBs, 6));
2004*e5436536SAndroid Build Coastguard Worker
2005*e5436536SAndroid Build Coastguard Worker hLoudnessInfoSet->loudnessInfoAlbumCount =
2006*e5436536SAndroid Build Coastguard Worker fMin(hLoudnessInfoSet->loudnessInfoAlbumCountV0, (UCHAR)12);
2007*e5436536SAndroid Build Coastguard Worker for (i = 0; i < hLoudnessInfoSet->loudnessInfoAlbumCountV0; i++) {
2008*e5436536SAndroid Build Coastguard Worker LOUDNESS_INFO tmpLoud;
2009*e5436536SAndroid Build Coastguard Worker FDKmemclear(&tmpLoud, sizeof(LOUDNESS_INFO));
2010*e5436536SAndroid Build Coastguard Worker err = _readLoudnessInfo(hBs, 0, &tmpLoud);
2011*e5436536SAndroid Build Coastguard Worker if (err) return err;
2012*e5436536SAndroid Build Coastguard Worker if (i >= 12) continue;
2013*e5436536SAndroid Build Coastguard Worker if (!diff)
2014*e5436536SAndroid Build Coastguard Worker diff |= (FDKmemcmp(&tmpLoud, &(hLoudnessInfoSet->loudnessInfoAlbum[i]),
2015*e5436536SAndroid Build Coastguard Worker sizeof(LOUDNESS_INFO)) != 0);
2016*e5436536SAndroid Build Coastguard Worker hLoudnessInfoSet->loudnessInfoAlbum[i] = tmpLoud;
2017*e5436536SAndroid Build Coastguard Worker }
2018*e5436536SAndroid Build Coastguard Worker
2019*e5436536SAndroid Build Coastguard Worker hLoudnessInfoSet->loudnessInfoCount =
2020*e5436536SAndroid Build Coastguard Worker fMin(hLoudnessInfoSet->loudnessInfoCountV0, (UCHAR)12);
2021*e5436536SAndroid Build Coastguard Worker for (i = 0; i < hLoudnessInfoSet->loudnessInfoCountV0; i++) {
2022*e5436536SAndroid Build Coastguard Worker LOUDNESS_INFO tmpLoud;
2023*e5436536SAndroid Build Coastguard Worker FDKmemclear(&tmpLoud, sizeof(LOUDNESS_INFO));
2024*e5436536SAndroid Build Coastguard Worker err = _readLoudnessInfo(hBs, 0, &tmpLoud);
2025*e5436536SAndroid Build Coastguard Worker if (err) return err;
2026*e5436536SAndroid Build Coastguard Worker if (i >= 12) continue;
2027*e5436536SAndroid Build Coastguard Worker if (!diff)
2028*e5436536SAndroid Build Coastguard Worker diff |= (FDKmemcmp(&tmpLoud, &(hLoudnessInfoSet->loudnessInfo[i]),
2029*e5436536SAndroid Build Coastguard Worker sizeof(LOUDNESS_INFO)) != 0);
2030*e5436536SAndroid Build Coastguard Worker hLoudnessInfoSet->loudnessInfo[i] = tmpLoud;
2031*e5436536SAndroid Build Coastguard Worker }
2032*e5436536SAndroid Build Coastguard Worker
2033*e5436536SAndroid Build Coastguard Worker diff |= _compAssign(&hLoudnessInfoSet->loudnessInfoSetExtPresent,
2034*e5436536SAndroid Build Coastguard Worker FDKreadBits(hBs, 1));
2035*e5436536SAndroid Build Coastguard Worker hLoudnessInfoSet->diff = diff;
2036*e5436536SAndroid Build Coastguard Worker
2037*e5436536SAndroid Build Coastguard Worker if (hLoudnessInfoSet->loudnessInfoSetExtPresent) {
2038*e5436536SAndroid Build Coastguard Worker err = _readLoudnessInfoSetExtension(hBs, hLoudnessInfoSet);
2039*e5436536SAndroid Build Coastguard Worker if (err) return err;
2040*e5436536SAndroid Build Coastguard Worker }
2041*e5436536SAndroid Build Coastguard Worker
2042*e5436536SAndroid Build Coastguard Worker return err;
2043*e5436536SAndroid Build Coastguard Worker }
2044