/src/aac/libDRCdec/src/drcGainDec_init.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* ----------------------------------------------------------------------------- |
2 | | Software License for The Fraunhofer FDK AAC Codec Library for Android |
3 | | |
4 | | © Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten |
5 | | Forschung e.V. All rights reserved. |
6 | | |
7 | | 1. INTRODUCTION |
8 | | The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software |
9 | | that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding |
10 | | scheme for digital audio. This FDK AAC Codec software is intended to be used on |
11 | | a wide variety of Android devices. |
12 | | |
13 | | AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient |
14 | | general perceptual audio codecs. AAC-ELD is considered the best-performing |
15 | | full-bandwidth communications codec by independent studies and is widely |
16 | | deployed. AAC has been standardized by ISO and IEC as part of the MPEG |
17 | | specifications. |
18 | | |
19 | | Patent licenses for necessary patent claims for the FDK AAC Codec (including |
20 | | those of Fraunhofer) may be obtained through Via Licensing |
21 | | (www.vialicensing.com) or through the respective patent owners individually for |
22 | | the purpose of encoding or decoding bit streams in products that are compliant |
23 | | with the ISO/IEC MPEG audio standards. Please note that most manufacturers of |
24 | | Android devices already license these patent claims through Via Licensing or |
25 | | directly from the patent owners, and therefore FDK AAC Codec software may |
26 | | already be covered under those patent licenses when it is used for those |
27 | | licensed purposes only. |
28 | | |
29 | | Commercially-licensed AAC software libraries, including floating-point versions |
30 | | with enhanced sound quality, are also available from Fraunhofer. Users are |
31 | | encouraged to check the Fraunhofer website for additional applications |
32 | | information and documentation. |
33 | | |
34 | | 2. COPYRIGHT LICENSE |
35 | | |
36 | | Redistribution and use in source and binary forms, with or without modification, |
37 | | are permitted without payment of copyright license fees provided that you |
38 | | satisfy the following conditions: |
39 | | |
40 | | You must retain the complete text of this software license in redistributions of |
41 | | the FDK AAC Codec or your modifications thereto in source code form. |
42 | | |
43 | | You must retain the complete text of this software license in the documentation |
44 | | and/or other materials provided with redistributions of the FDK AAC Codec or |
45 | | your modifications thereto in binary form. You must make available free of |
46 | | charge copies of the complete source code of the FDK AAC Codec and your |
47 | | modifications thereto to recipients of copies in binary form. |
48 | | |
49 | | The name of Fraunhofer may not be used to endorse or promote products derived |
50 | | from this library without prior written permission. |
51 | | |
52 | | You may not charge copyright license fees for anyone to use, copy or distribute |
53 | | the FDK AAC Codec software or your modifications thereto. |
54 | | |
55 | | Your modified versions of the FDK AAC Codec must carry prominent notices stating |
56 | | that you changed the software and the date of any change. For modified versions |
57 | | of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" |
58 | | must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK |
59 | | AAC Codec Library for Android." |
60 | | |
61 | | 3. NO PATENT LICENSE |
62 | | |
63 | | NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without |
64 | | limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. |
65 | | Fraunhofer provides no warranty of patent non-infringement with respect to this |
66 | | software. |
67 | | |
68 | | You may use this FDK AAC Codec software or modifications thereto only for |
69 | | purposes that are authorized by appropriate patent licenses. |
70 | | |
71 | | 4. DISCLAIMER |
72 | | |
73 | | This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright |
74 | | holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, |
75 | | including but not limited to the implied warranties of merchantability and |
76 | | fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
77 | | CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, |
78 | | or consequential damages, including but not limited to procurement of substitute |
79 | | goods or services; loss of use, data, or profits, or business interruption, |
80 | | however caused and on any theory of liability, whether in contract, strict |
81 | | liability, or tort (including negligence), arising in any way out of the use of |
82 | | this software, even if advised of the possibility of such damage. |
83 | | |
84 | | 5. CONTACT INFORMATION |
85 | | |
86 | | Fraunhofer Institute for Integrated Circuits IIS |
87 | | Attention: Audio and Multimedia Departments - FDK AAC LL |
88 | | Am Wolfsmantel 33 |
89 | | 91058 Erlangen, Germany |
90 | | |
91 | | www.iis.fraunhofer.de/amm |
92 | | amm-info@iis.fraunhofer.de |
93 | | ----------------------------------------------------------------------------- */ |
94 | | |
95 | | /************************* MPEG-D DRC decoder library ************************** |
96 | | |
97 | | Author(s): |
98 | | |
99 | | Description: |
100 | | |
101 | | *******************************************************************************/ |
102 | | |
103 | | #include "drcDec_types.h" |
104 | | #include "drcDec_tools.h" |
105 | | #include "drcDec_gainDecoder.h" |
106 | | #include "drcGainDec_init.h" |
107 | | |
108 | | static DRC_ERROR _generateDrcInstructionsDerivedData( |
109 | | HANDLE_DRC_GAIN_DECODER hGainDec, HANDLE_UNI_DRC_CONFIG hUniDrcConfig, |
110 | | DRC_INSTRUCTIONS_UNI_DRC* pInst, DRC_COEFFICIENTS_UNI_DRC* pCoef, |
111 | 16.2k | ACTIVE_DRC* pActiveDrc) { |
112 | 16.2k | DRC_ERROR err = DE_OK; |
113 | 16.2k | int g; |
114 | 16.2k | int gainElementCount = 0; |
115 | 16.2k | UCHAR nDrcChannelGroups = 0; |
116 | 16.2k | SCHAR gainSetIndexForChannelGroup[8]; |
117 | | |
118 | 16.2k | err = deriveDrcChannelGroups( |
119 | 16.2k | pInst->drcSetEffect, pInst->drcChannelCount, pInst->gainSetIndex, |
120 | 16.2k | pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF) |
121 | 16.2k | ? pInst->duckingModificationForChannel |
122 | 16.2k | : NULL, |
123 | 16.2k | &nDrcChannelGroups, gainSetIndexForChannelGroup, |
124 | 16.2k | pActiveDrc->channelGroupForChannel, |
125 | 16.2k | pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF) |
126 | 16.2k | ? pActiveDrc->duckingModificationForChannelGroup |
127 | 16.2k | : NULL); |
128 | 16.2k | if (err) return (err); |
129 | | |
130 | | /* sanity check */ |
131 | 16.2k | if (nDrcChannelGroups != pInst->nDrcChannelGroups) return DE_NOT_OK; |
132 | 47.6k | for (g = 0; g < pInst->nDrcChannelGroups; g++) { |
133 | 31.4k | if (gainSetIndexForChannelGroup[g] != pInst->gainSetIndexForChannelGroup[g]) |
134 | 0 | return DE_NOT_OK; |
135 | 31.4k | } |
136 | | |
137 | 47.6k | for (g = 0; g < pInst->nDrcChannelGroups; g++) { |
138 | 31.4k | int seq = pInst->gainSetIndexForChannelGroup[g]; |
139 | 31.4k | if (seq != -1 && (hUniDrcConfig->drcCoefficientsUniDrcCount == 0 || |
140 | 31.4k | seq >= pCoef->gainSetCount)) { |
141 | 25.9k | pActiveDrc->channelGroupIsParametricDrc[g] = 1; |
142 | 25.9k | } else { |
143 | 5.46k | pActiveDrc->channelGroupIsParametricDrc[g] = 0; |
144 | 5.46k | if (seq >= pCoef->gainSetCount) { |
145 | 0 | return DE_NOT_OK; |
146 | 0 | } |
147 | 5.46k | } |
148 | 31.4k | } |
149 | | |
150 | | /* gainElementCount */ |
151 | 16.2k | if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) { |
152 | 30.8k | for (g = 0; g < pInst->nDrcChannelGroups; g++) { |
153 | 24.3k | pActiveDrc->bandCountForChannelGroup[g] = 1; |
154 | 24.3k | } |
155 | 6.51k | pActiveDrc->gainElementCount = |
156 | 6.51k | pInst->nDrcChannelGroups; /* one gain element per channel group */ |
157 | 9.73k | } else { |
158 | 16.8k | for (g = 0; g < pInst->nDrcChannelGroups; g++) { |
159 | 7.13k | if (pActiveDrc->channelGroupIsParametricDrc[g]) { |
160 | 1.80k | gainElementCount++; |
161 | 1.80k | pActiveDrc->bandCountForChannelGroup[g] = 1; |
162 | 5.32k | } else { |
163 | 5.32k | int seq, bandCount; |
164 | 5.32k | seq = pInst->gainSetIndexForChannelGroup[g]; |
165 | 5.32k | bandCount = pCoef->gainSet[seq].bandCount; |
166 | 5.32k | pActiveDrc->bandCountForChannelGroup[g] = bandCount; |
167 | 5.32k | gainElementCount += bandCount; |
168 | 5.32k | } |
169 | 7.13k | } |
170 | 9.73k | pActiveDrc->gainElementCount = gainElementCount; |
171 | 9.73k | } |
172 | | |
173 | | /* prepare gainElementForGroup (cumulated sum of bandCountForChannelGroup) */ |
174 | 16.2k | pActiveDrc->gainElementForGroup[0] = 0; |
175 | 37.3k | for (g = 1; g < pInst->nDrcChannelGroups; g++) { |
176 | 21.1k | pActiveDrc->gainElementForGroup[g] = |
177 | 21.1k | pActiveDrc->gainElementForGroup[g - 1] + |
178 | 21.1k | pActiveDrc->bandCountForChannelGroup[g - 1]; /* index of first gain |
179 | | sequence in channel |
180 | | group */ |
181 | 21.1k | } |
182 | | |
183 | 16.2k | return DE_OK; |
184 | 16.2k | } |
185 | | |
186 | | DRC_ERROR |
187 | 86.5k | initGainDec(HANDLE_DRC_GAIN_DECODER hGainDec) { |
188 | 86.5k | int i, j, k; |
189 | | |
190 | | /* sanity check */ |
191 | 86.5k | if (hGainDec->deltaTminDefault > hGainDec->frameSize) return DE_NOT_OK; |
192 | | |
193 | 346k | for (i = 0; i < MAX_ACTIVE_DRCS; i++) { |
194 | 2.33M | for (j = 0; j < 8; j++) { |
195 | | /* use startup node at the beginning */ |
196 | 2.07M | hGainDec->activeDrc[i].lnbIndexForChannel[j][0] = 0; |
197 | 10.3M | for (k = 1; k < NUM_LNB_FRAMES; k++) { |
198 | 8.30M | hGainDec->activeDrc[i].lnbIndexForChannel[j][k] = -1; |
199 | 8.30M | } |
200 | 2.07M | } |
201 | 259k | } |
202 | | |
203 | 778k | for (j = 0; j < 8; j++) { |
204 | 692k | hGainDec->channelGain[j] = FL2FXCONST_DBL(1.0f / (float)(1 << 8)); |
205 | 692k | } |
206 | | |
207 | 1.47M | for (i = 0; i < 4 * 1024 / 256; i++) { |
208 | 1.38M | hGainDec->dummySubbandGains[i] = FL2FXCONST_DBL(1.0f / (float)(1 << 7)); |
209 | 1.38M | } |
210 | | |
211 | 86.5k | hGainDec->status = 0; /* startup */ |
212 | | |
213 | 86.5k | return DE_OK; |
214 | 86.5k | } |
215 | | |
216 | 86.5k | void initDrcGainBuffers(const int frameSize, DRC_GAIN_BUFFERS* drcGainBuffers) { |
217 | 86.5k | int i, c, j; |
218 | | /* prepare 12 instances of node buffers */ |
219 | 1.12M | for (i = 0; i < 12; i++) { |
220 | 6.22M | for (j = 0; j < NUM_LNB_FRAMES; j++) { |
221 | 5.19M | drcGainBuffers->linearNodeBuffer[i].nNodes[j] = 1; |
222 | 5.19M | drcGainBuffers->linearNodeBuffer[i].linearNode[j][0].gainLin = |
223 | 5.19M | FL2FXCONST_DBL(1.0f / (float)(1 << 7)); |
224 | 5.19M | if (j == 0) { |
225 | 1.03M | drcGainBuffers->linearNodeBuffer[i].linearNode[j][0].time = |
226 | 1.03M | 0; /* initialize last node with startup node */ |
227 | 4.15M | } else { |
228 | 4.15M | drcGainBuffers->linearNodeBuffer[i].linearNode[j][0].time = |
229 | 4.15M | frameSize - 1; |
230 | 4.15M | } |
231 | 5.19M | } |
232 | 1.03M | } |
233 | | |
234 | | /* prepare dummyLnb, a linearNodeBuffer containing a constant gain of 0 dB, |
235 | | * for the "no DRC processing" case */ |
236 | 86.5k | drcGainBuffers->dummyLnb.gainInterpolationType = GIT_LINEAR; |
237 | 519k | for (i = 0; i < NUM_LNB_FRAMES; i++) { |
238 | 432k | drcGainBuffers->dummyLnb.nNodes[i] = 1; |
239 | 432k | drcGainBuffers->dummyLnb.linearNode[i][0].gainLin = |
240 | 432k | FL2FXCONST_DBL(1.0f / (float)(1 << 7)); |
241 | 432k | drcGainBuffers->dummyLnb.linearNode[i][0].time = frameSize - 1; |
242 | 432k | } |
243 | | |
244 | | /* prepare channelGain delay line */ |
245 | 778k | for (c = 0; c < 8; c++) { |
246 | 4.15M | for (i = 0; i < NUM_LNB_FRAMES; i++) { |
247 | 3.46M | drcGainBuffers->channelGain[c][i] = |
248 | 3.46M | FL2FXCONST_DBL(1.0f / (float)(1 << 8)); |
249 | 3.46M | } |
250 | 692k | } |
251 | | |
252 | 86.5k | drcGainBuffers->lnbPointer = 0; |
253 | 86.5k | } |
254 | | |
255 | | DRC_ERROR |
256 | | initActiveDrc(HANDLE_DRC_GAIN_DECODER hGainDec, |
257 | | HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int drcSetIdSelected, |
258 | 165k | const int downmixIdSelected) { |
259 | 165k | int g, isMultiband = 0; |
260 | 165k | DRC_ERROR err = DE_OK; |
261 | 165k | DRC_INSTRUCTIONS_UNI_DRC* pInst = NULL; |
262 | 165k | DRC_COEFFICIENTS_UNI_DRC* pCoef = NULL; |
263 | | |
264 | 165k | pInst = selectDrcInstructions(hUniDrcConfig, drcSetIdSelected); |
265 | 165k | if (pInst == NULL) { |
266 | 0 | return DE_NOT_OK; |
267 | 0 | } |
268 | | |
269 | 165k | if (pInst->drcSetId >= 0) { |
270 | 17.0k | pCoef = selectDrcCoefficients(hUniDrcConfig, pInst->drcLocation); |
271 | 17.0k | if (pCoef == NULL) { |
272 | 0 | return DE_NOT_OK; |
273 | 0 | } |
274 | | |
275 | 17.0k | if (pCoef->drcFrameSizePresent) { |
276 | 1.44k | if (pCoef->drcFrameSize != hGainDec->frameSize) { |
277 | 761 | return DE_NOT_OK; |
278 | 761 | } |
279 | 1.44k | } |
280 | | |
281 | 16.2k | err = _generateDrcInstructionsDerivedData( |
282 | 16.2k | hGainDec, hUniDrcConfig, pInst, pCoef, |
283 | 16.2k | &(hGainDec->activeDrc[hGainDec->nActiveDrcs])); |
284 | 16.2k | if (err) return err; |
285 | 16.2k | } |
286 | | |
287 | 165k | hGainDec->activeDrc[hGainDec->nActiveDrcs].pInst = pInst; |
288 | 165k | hGainDec->activeDrc[hGainDec->nActiveDrcs].pCoef = pCoef; |
289 | | |
290 | 194k | for (g = 0; g < pInst->nDrcChannelGroups; g++) { |
291 | 31.4k | if (hGainDec->activeDrc[hGainDec->nActiveDrcs].bandCountForChannelGroup[g] > |
292 | 31.4k | 1) { |
293 | 5.26k | if (hGainDec->multiBandActiveDrcIndex != -1) { |
294 | 1.85k | return DE_NOT_OK; |
295 | 1.85k | } |
296 | 3.41k | isMultiband = 1; |
297 | 3.41k | } |
298 | 31.4k | } |
299 | | |
300 | 163k | if (isMultiband) { |
301 | | /* Keep activeDrc index of multiband DRC set */ |
302 | 3.40k | hGainDec->multiBandActiveDrcIndex = hGainDec->nActiveDrcs; |
303 | 3.40k | } |
304 | | |
305 | 163k | if ((hGainDec->channelGainActiveDrcIndex == -1) && |
306 | 163k | (downmixIdSelected == DOWNMIX_ID_BASE_LAYOUT) && |
307 | 163k | (hUniDrcConfig->drcInstructionsUniDrcCount > |
308 | 152k | 0)) { /* use this activeDrc to apply channelGains */ |
309 | 14.3k | hGainDec->channelGainActiveDrcIndex = hGainDec->nActiveDrcs; |
310 | 14.3k | } |
311 | | |
312 | 163k | hGainDec->nActiveDrcs++; |
313 | 163k | if (hGainDec->nActiveDrcs > MAX_ACTIVE_DRCS) return DE_NOT_OK; |
314 | | |
315 | 163k | return DE_OK; |
316 | 163k | } |
317 | | |
318 | | DRC_ERROR |
319 | 155k | initActiveDrcOffset(HANDLE_DRC_GAIN_DECODER hGainDec) { |
320 | 155k | int a, accGainElementCount; |
321 | | |
322 | 155k | accGainElementCount = 0; |
323 | 316k | for (a = 0; a < hGainDec->nActiveDrcs; a++) { |
324 | 161k | hGainDec->activeDrc[a].activeDrcOffset = accGainElementCount; |
325 | 161k | accGainElementCount += hGainDec->activeDrc[a].gainElementCount; |
326 | 161k | if (accGainElementCount > 12) { |
327 | 565 | hGainDec->nActiveDrcs = a; |
328 | 565 | return DE_NOT_OK; |
329 | 565 | } |
330 | 161k | } |
331 | | |
332 | 154k | return DE_OK; |
333 | 155k | } |