• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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