1 /* ----------------------------------------------------------------------------- 2 Software License for The Fraunhofer FDK AAC Codec Library for Android 3 4 Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Frderung 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 (at) 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 -----------------------------------------------------------------------------*/ 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 -----------------------------------------------------------------------------*/ 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 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 -----------------------------------------------------------------------------*/ 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 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 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 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 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 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 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 438 INT fdk_sacenc_delay_GetOutputAudioBufferDelay(HANDLE_DELAY hDelay) { 439 return (hDelay->nOutputAudioBuffer); 440 } 441 442 INT fdk_sacenc_delay_GetSurroundAnalysisBufferDelay(HANDLE_DELAY hDelay) { 443 return (hDelay->nSurroundAnalysisBuffer); 444 } 445 446 INT fdk_sacenc_delay_GetArbDmxAnalysisBufferDelay(HANDLE_DELAY hDelay) { 447 return (hDelay->nArbDmxAnalysisBuffer); 448 } 449 450 INT fdk_sacenc_delay_GetBitstreamFrameBufferSize(HANDLE_DELAY hDelay) { 451 return (hDelay->nBitstreamFrameBufferSize); 452 } 453 454 INT fdk_sacenc_delay_GetDmxAlignBufferDelay(HANDLE_DELAY hDelay) { 455 return (hDelay->nDmxAlignBuffer); 456 } 457 458 INT fdk_sacenc_delay_GetDiscardOutFrames(HANDLE_DELAY hDelay) { 459 return (hDelay->nDiscardOutFrames); 460 } 461 462 INT fdk_sacenc_delay_GetInfoDmxDelay(HANDLE_DELAY hDelay) { 463 return (hDelay->nInfoDmxDelay); 464 } 465 466 INT fdk_sacenc_delay_GetInfoCodecDelay(HANDLE_DELAY hDelay) { 467 return (hDelay->nInfoCodecDelay); 468 } 469 470 INT fdk_sacenc_delay_GetInfoDecoderDelay(HANDLE_DELAY hDelay) { 471 return (hDelay->nInfoDecoderDelay); 472 } 473