1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4 © Copyright 1995 - 2018 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 surround encoder library *************************
96
97 Author(s): Christian Goettlinger
98
99 Description: Encoder Library Interface
100 delay management of the encoder
101
102 *******************************************************************************/
103
104 /**************************************************************************/ /**
105 \file
106 This file contains all delay infrastructure
107 ******************************************************************************/
108
109 /* Includes ******************************************************************/
110 #include "sacenc_delay.h"
111 #include "sacenc_const.h"
112 #include "FDK_matrixCalloc.h"
113
114 /* Defines *******************************************************************/
115
116 /* Data Types ****************************************************************/
117 struct DELAY {
118 struct DELAY_CONFIG {
119 /* Routing Config Switches*/
120 INT bDmxAlign;
121 INT bTimeDomDmx;
122 INT bMinimizeDelay;
123 INT bSacTimeAlignmentDynamicOut;
124
125 /* Needed Input Variables*/
126 INT nQmfLen;
127 INT nFrameLen;
128 INT nSurroundDelay;
129 INT nArbDmxDelay;
130 INT nLimiterDelay;
131 INT nCoreCoderDelay;
132 INT nSacStreamMuxDelay;
133 INT nSacTimeAlignment; /* Overwritten, if bSacTimeAlignmentDynamicOut */
134 } config;
135
136 /* Variable Delaybuffers -> Delays */
137 INT nDmxAlignBuffer;
138 INT nSurroundAnalysisBuffer;
139 INT nArbDmxAnalysisBuffer;
140 INT nOutputAudioBuffer;
141 INT nBitstreamFrameBuffer;
142 INT nOutputAudioQmfFrameBuffer;
143 INT nDiscardOutFrames;
144
145 /* Variable Delaybuffers Computation Variables */
146 INT nBitstreamFrameBufferSize;
147
148 /* Output: Infos */
149 INT nInfoDmxDelay; /* Delay of the downmixed signal after the space encoder */
150 INT nInfoCodecDelay; /* Delay of the whole en-/decoder including CoreCoder */
151 INT nInfoDecoderDelay; /* Delay of the Mpeg Surround decoder */
152 };
153
154 /* Constants *****************************************************************/
155
156 /* Function / Class Declarations *********************************************/
157
158 /* Function / Class Definition ***********************************************/
159
160 /*-----------------------------------------------------------------------------
161 functionname: fdk_sacenc_delay_Open()
162 description: initializes Delays
163 returns: noError on success, an apropriate error code else
164 -----------------------------------------------------------------------------*/
fdk_sacenc_delay_Open(HANDLE_DELAY * phDelay)165 FDK_SACENC_ERROR fdk_sacenc_delay_Open(HANDLE_DELAY *phDelay) {
166 FDK_SACENC_ERROR error = SACENC_OK;
167
168 if (NULL == phDelay) {
169 error = SACENC_INVALID_HANDLE;
170 } else {
171 FDK_ALLOCATE_MEMORY_1D(*phDelay, 1, struct DELAY);
172 }
173 return error;
174
175 bail:
176 fdk_sacenc_delay_Close(phDelay);
177 return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
178 }
179
180 /*-----------------------------------------------------------------------------
181 functionname: fdk_sacenc_delay_Close()
182 description: destructs Delay
183 returns: noError on success, an apropriate error code else
184 -----------------------------------------------------------------------------*/
fdk_sacenc_delay_Close(HANDLE_DELAY * phDelay)185 FDK_SACENC_ERROR fdk_sacenc_delay_Close(HANDLE_DELAY *phDelay) {
186 FDK_SACENC_ERROR error = SACENC_OK;
187
188 if (NULL == phDelay) {
189 error = SACENC_INVALID_HANDLE;
190 } else {
191 if (NULL != *phDelay) {
192 FDK_FREE_MEMORY_1D(*phDelay);
193 }
194 }
195 return error;
196 }
197
fdk_sacenc_delay_Init(HANDLE_DELAY hDelay,const INT nQmfLen,const INT nFrameLen,const INT nCoreCoderDelay,const INT nSacStreamMuxDelay)198 FDK_SACENC_ERROR fdk_sacenc_delay_Init(HANDLE_DELAY hDelay, const INT nQmfLen,
199 const INT nFrameLen,
200 const INT nCoreCoderDelay,
201 const INT nSacStreamMuxDelay) {
202 FDK_SACENC_ERROR error = SACENC_OK;
203
204 if (NULL == hDelay) {
205 error = SACENC_INVALID_HANDLE;
206 } else {
207 /* Fill structure before calculation */
208 FDKmemclear(&hDelay->config, sizeof(hDelay->config));
209
210 hDelay->config.nQmfLen = nQmfLen;
211 hDelay->config.nFrameLen = nFrameLen;
212 hDelay->config.nCoreCoderDelay = nCoreCoderDelay;
213 hDelay->config.nSacStreamMuxDelay = nSacStreamMuxDelay;
214 }
215 return error;
216 }
217
218 /*-----------------------------------------------------------------------------
219 functionname: fdk_sacenc_delay_SubCalulateBufferDelays()
220 description: Calculates the Delays of the buffers
221 returns: Error Code
222 -----------------------------------------------------------------------------*/
fdk_sacenc_delay_SubCalulateBufferDelays(HANDLE_DELAY hDel)223 FDK_SACENC_ERROR fdk_sacenc_delay_SubCalulateBufferDelays(HANDLE_DELAY hDel) {
224 FDK_SACENC_ERROR error = SACENC_OK;
225
226 if (NULL == hDel) {
227 error = SACENC_INVALID_HANDLE;
228 } else {
229 int nEncoderAnDelay, nEncoderSynDelay, nEncoderWinDelay, nDecoderAnDelay,
230 nDecoderSynDelay, nResidualCoderFrameDelay,
231 nArbDmxResidualCoderFrameDelay;
232
233 if (hDel->config.bSacTimeAlignmentDynamicOut > 0) {
234 hDel->config.nSacTimeAlignment = 0;
235 }
236
237 {
238 nEncoderAnDelay =
239 2 * hDel->config.nQmfLen +
240 hDel->config.nQmfLen / 2; /* Only Ld-QMF Delay, no hybrid */
241 nEncoderSynDelay = 1 * hDel->config.nQmfLen + hDel->config.nQmfLen / 2;
242 nDecoderAnDelay = 2 * hDel->config.nQmfLen + hDel->config.nQmfLen / 2;
243 nDecoderSynDelay = 1 * hDel->config.nQmfLen + hDel->config.nQmfLen / 2;
244 nEncoderWinDelay =
245 hDel->config.nFrameLen / 2; /* WindowLookahead is just half a frame */
246 }
247
248 { nResidualCoderFrameDelay = 0; }
249
250 { nArbDmxResidualCoderFrameDelay = 0; }
251
252 /* Calculate variable Buffer-Delays */
253 if (hDel->config.bTimeDomDmx == 0) {
254 /* ArbitraryDmx and TdDmx off */
255 int tempDelay;
256
257 hDel->nSurroundAnalysisBuffer = 0;
258 hDel->nArbDmxAnalysisBuffer = 0;
259 tempDelay = nEncoderSynDelay + hDel->config.nLimiterDelay +
260 hDel->config.nCoreCoderDelay +
261 hDel->config.nSacTimeAlignment + nDecoderAnDelay;
262 tempDelay = (nResidualCoderFrameDelay * hDel->config.nFrameLen) +
263 hDel->config.nSacStreamMuxDelay - tempDelay;
264
265 if (tempDelay > 0) {
266 hDel->nBitstreamFrameBuffer = 0;
267 hDel->nOutputAudioBuffer = tempDelay;
268 } else {
269 tempDelay = -tempDelay;
270 hDel->nBitstreamFrameBuffer =
271 (tempDelay + hDel->config.nFrameLen - 1) / hDel->config.nFrameLen;
272 hDel->nOutputAudioBuffer =
273 (hDel->nBitstreamFrameBuffer * hDel->config.nFrameLen) - tempDelay;
274 }
275
276 hDel->nOutputAudioQmfFrameBuffer =
277 (hDel->nOutputAudioBuffer + (hDel->config.nQmfLen / 2) - 1) /
278 hDel->config.nQmfLen;
279
280 if (hDel->config.bDmxAlign > 0) {
281 tempDelay = nEncoderWinDelay + nEncoderAnDelay + nEncoderSynDelay +
282 hDel->nOutputAudioBuffer + hDel->config.nLimiterDelay +
283 hDel->config.nCoreCoderDelay;
284 hDel->nDiscardOutFrames =
285 (tempDelay + hDel->config.nFrameLen - 1) / hDel->config.nFrameLen;
286 hDel->nDmxAlignBuffer =
287 hDel->nDiscardOutFrames * hDel->config.nFrameLen - tempDelay;
288 } else {
289 hDel->nDiscardOutFrames = 0;
290 hDel->nDmxAlignBuffer = 0;
291 }
292
293 /* Output: Info-Variables */
294 hDel->nInfoDmxDelay = hDel->nSurroundAnalysisBuffer + nEncoderAnDelay +
295 nEncoderWinDelay + nEncoderSynDelay +
296 hDel->nOutputAudioBuffer +
297 hDel->config.nLimiterDelay;
298 hDel->nInfoCodecDelay =
299 hDel->nInfoDmxDelay + hDel->config.nCoreCoderDelay +
300 hDel->config.nSacTimeAlignment + nDecoderAnDelay + nDecoderSynDelay;
301
302 } else {
303 /* ArbitraryDmx or TdDmx on */
304 int tempDelay1, tempDelay2, tempDelay12, tempDelay3;
305
306 tempDelay1 = hDel->config.nArbDmxDelay - hDel->config.nSurroundDelay;
307
308 if (tempDelay1 >= 0) {
309 hDel->nSurroundAnalysisBuffer = tempDelay1;
310 hDel->nArbDmxAnalysisBuffer = 0;
311 } else {
312 hDel->nSurroundAnalysisBuffer = 0;
313 hDel->nArbDmxAnalysisBuffer = -tempDelay1;
314 }
315
316 tempDelay1 = nEncoderWinDelay + hDel->config.nSurroundDelay +
317 hDel->nSurroundAnalysisBuffer +
318 nEncoderAnDelay; /*Surround Path*/
319 tempDelay2 = nEncoderWinDelay + hDel->config.nArbDmxDelay +
320 hDel->nArbDmxAnalysisBuffer +
321 nEncoderAnDelay; /* ArbDmx Compare Path */
322 tempDelay3 = hDel->config.nArbDmxDelay + hDel->config.nLimiterDelay +
323 hDel->config.nCoreCoderDelay +
324 hDel->config.nSacTimeAlignment +
325 nDecoderAnDelay; /* ArbDmx Passthrough*/
326
327 tempDelay12 =
328 FDKmax(nResidualCoderFrameDelay, nArbDmxResidualCoderFrameDelay) *
329 hDel->config.nFrameLen;
330 tempDelay12 += hDel->config.nSacStreamMuxDelay;
331
332 if (tempDelay1 > tempDelay2) {
333 tempDelay12 += tempDelay1;
334 } else {
335 tempDelay12 += tempDelay2;
336 }
337
338 if (tempDelay3 > tempDelay12) {
339 if (hDel->config.bMinimizeDelay > 0) {
340 hDel->nBitstreamFrameBuffer =
341 (tempDelay3 - tempDelay12) / hDel->config.nFrameLen; /*floor*/
342 hDel->nOutputAudioBuffer = 0;
343 hDel->nSurroundAnalysisBuffer +=
344 (tempDelay3 - tempDelay12 -
345 (hDel->nBitstreamFrameBuffer * hDel->config.nFrameLen));
346 hDel->nArbDmxAnalysisBuffer +=
347 (tempDelay3 - tempDelay12 -
348 (hDel->nBitstreamFrameBuffer * hDel->config.nFrameLen));
349 } else {
350 hDel->nBitstreamFrameBuffer =
351 ((tempDelay3 - tempDelay12) + hDel->config.nFrameLen - 1) /
352 hDel->config.nFrameLen;
353 hDel->nOutputAudioBuffer =
354 hDel->nBitstreamFrameBuffer * hDel->config.nFrameLen +
355 tempDelay12 - tempDelay3;
356 }
357 } else {
358 hDel->nBitstreamFrameBuffer = 0;
359 hDel->nOutputAudioBuffer = tempDelay12 - tempDelay3;
360 }
361
362 if (hDel->config.bDmxAlign > 0) {
363 int tempDelay = hDel->config.nArbDmxDelay + hDel->nOutputAudioBuffer +
364 hDel->config.nLimiterDelay +
365 hDel->config.nCoreCoderDelay;
366 hDel->nDiscardOutFrames =
367 (tempDelay + hDel->config.nFrameLen - 1) / hDel->config.nFrameLen;
368 hDel->nDmxAlignBuffer =
369 hDel->nDiscardOutFrames * hDel->config.nFrameLen - tempDelay;
370 } else {
371 hDel->nDiscardOutFrames = 0;
372 hDel->nDmxAlignBuffer = 0;
373 }
374
375 /* Output: Info-Variables */
376 hDel->nInfoDmxDelay = hDel->config.nArbDmxDelay +
377 hDel->nOutputAudioBuffer +
378 hDel->config.nLimiterDelay;
379 hDel->nInfoCodecDelay =
380 hDel->nInfoDmxDelay + hDel->config.nCoreCoderDelay +
381 hDel->config.nSacTimeAlignment + nDecoderAnDelay + nDecoderSynDelay;
382 hDel->nInfoDecoderDelay = nDecoderAnDelay + nDecoderSynDelay;
383
384 } /* ArbitraryDmx or TdDmx on */
385
386 /* Additonal Variables needed for Computation Issues */
387 hDel->nBitstreamFrameBufferSize = hDel->nBitstreamFrameBuffer + 1;
388 }
389
390 return error;
391 }
392
assignParameterInRange(const INT startRange,const INT stopRange,const INT value,INT * const ptr)393 static FDK_SACENC_ERROR assignParameterInRange(
394 const INT startRange, /* including startRange */
395 const INT stopRange, /* including stopRange */
396 const INT value, /* value to write*/
397 INT *const ptr /* destination pointer*/
398 ) {
399 FDK_SACENC_ERROR error = SACENC_INVALID_CONFIG;
400
401 if ((startRange <= value) && (value <= stopRange)) {
402 *ptr = value;
403 error = SACENC_OK;
404 }
405
406 return error;
407 }
408
fdk_sacenc_delay_SetDmxAlign(HANDLE_DELAY hDelay,const INT bDmxAlignIn)409 FDK_SACENC_ERROR fdk_sacenc_delay_SetDmxAlign(HANDLE_DELAY hDelay,
410 const INT bDmxAlignIn) {
411 return (assignParameterInRange(0, 1, bDmxAlignIn, &hDelay->config.bDmxAlign));
412 }
413
fdk_sacenc_delay_SetTimeDomDmx(HANDLE_DELAY hDelay,const INT bTimeDomDmxIn)414 FDK_SACENC_ERROR fdk_sacenc_delay_SetTimeDomDmx(HANDLE_DELAY hDelay,
415 const INT bTimeDomDmxIn) {
416 return (
417 assignParameterInRange(0, 1, bTimeDomDmxIn, &hDelay->config.bTimeDomDmx));
418 }
419
fdk_sacenc_delay_SetSacTimeAlignmentDynamicOut(HANDLE_DELAY hDelay,const INT bSacTimeAlignmentDynamicOutIn)420 FDK_SACENC_ERROR fdk_sacenc_delay_SetSacTimeAlignmentDynamicOut(
421 HANDLE_DELAY hDelay, const INT bSacTimeAlignmentDynamicOutIn) {
422 return (assignParameterInRange(0, 1, bSacTimeAlignmentDynamicOutIn,
423 &hDelay->config.bSacTimeAlignmentDynamicOut));
424 }
425
fdk_sacenc_delay_SetNSacTimeAlignment(HANDLE_DELAY hDelay,const INT nSacTimeAlignmentIn)426 FDK_SACENC_ERROR fdk_sacenc_delay_SetNSacTimeAlignment(
427 HANDLE_DELAY hDelay, const INT nSacTimeAlignmentIn) {
428 return (assignParameterInRange(-32768, 32767, nSacTimeAlignmentIn,
429 &hDelay->config.nSacTimeAlignment));
430 }
431
fdk_sacenc_delay_SetMinimizeDelay(HANDLE_DELAY hDelay,const INT bMinimizeDelay)432 FDK_SACENC_ERROR fdk_sacenc_delay_SetMinimizeDelay(HANDLE_DELAY hDelay,
433 const INT bMinimizeDelay) {
434 return (assignParameterInRange(0, 1, bMinimizeDelay,
435 &hDelay->config.bMinimizeDelay));
436 }
437
fdk_sacenc_delay_GetOutputAudioBufferDelay(HANDLE_DELAY hDelay)438 INT fdk_sacenc_delay_GetOutputAudioBufferDelay(HANDLE_DELAY hDelay) {
439 return (hDelay->nOutputAudioBuffer);
440 }
441
fdk_sacenc_delay_GetSurroundAnalysisBufferDelay(HANDLE_DELAY hDelay)442 INT fdk_sacenc_delay_GetSurroundAnalysisBufferDelay(HANDLE_DELAY hDelay) {
443 return (hDelay->nSurroundAnalysisBuffer);
444 }
445
fdk_sacenc_delay_GetArbDmxAnalysisBufferDelay(HANDLE_DELAY hDelay)446 INT fdk_sacenc_delay_GetArbDmxAnalysisBufferDelay(HANDLE_DELAY hDelay) {
447 return (hDelay->nArbDmxAnalysisBuffer);
448 }
449
fdk_sacenc_delay_GetBitstreamFrameBufferSize(HANDLE_DELAY hDelay)450 INT fdk_sacenc_delay_GetBitstreamFrameBufferSize(HANDLE_DELAY hDelay) {
451 return (hDelay->nBitstreamFrameBufferSize);
452 }
453
fdk_sacenc_delay_GetDmxAlignBufferDelay(HANDLE_DELAY hDelay)454 INT fdk_sacenc_delay_GetDmxAlignBufferDelay(HANDLE_DELAY hDelay) {
455 return (hDelay->nDmxAlignBuffer);
456 }
457
fdk_sacenc_delay_GetDiscardOutFrames(HANDLE_DELAY hDelay)458 INT fdk_sacenc_delay_GetDiscardOutFrames(HANDLE_DELAY hDelay) {
459 return (hDelay->nDiscardOutFrames);
460 }
461
fdk_sacenc_delay_GetInfoDmxDelay(HANDLE_DELAY hDelay)462 INT fdk_sacenc_delay_GetInfoDmxDelay(HANDLE_DELAY hDelay) {
463 return (hDelay->nInfoDmxDelay);
464 }
465
fdk_sacenc_delay_GetInfoCodecDelay(HANDLE_DELAY hDelay)466 INT fdk_sacenc_delay_GetInfoCodecDelay(HANDLE_DELAY hDelay) {
467 return (hDelay->nInfoCodecDelay);
468 }
469
fdk_sacenc_delay_GetInfoDecoderDelay(HANDLE_DELAY hDelay)470 INT fdk_sacenc_delay_GetInfoDecoderDelay(HANDLE_DELAY hDelay) {
471 return (hDelay->nInfoDecoderDelay);
472 }
473