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): Max Neuendorf 98 99 Description: Encoder Library Interface 100 Interface to Spacial Audio Coding Encoder lib 101 102 *******************************************************************************/ 103 104 /**************************************************************************** 105 \file 106 Description of file contents 107 ******************************************************************************/ 108 109 /* Includes ******************************************************************/ 110 #include "sacenc_lib.h" 111 #include "sacenc_const.h" 112 #include "genericStds.h" 113 #include "FDK_core.h" 114 #include "sacenc_tree.h" 115 #include "sacenc_bitstream.h" 116 #include "sacenc_onsetdetect.h" 117 #include "sacenc_framewindowing.h" 118 #include "sacenc_filter.h" 119 #include "sacenc_paramextract.h" 120 #include "sacenc_staticgain.h" 121 #include "sacenc_delay.h" 122 #include "sacenc_dmx_tdom_enh.h" 123 #include "sacenc_vectorfunctions.h" 124 #include "qmf.h" 125 126 /* Defines *******************************************************************/ 127 128 /* Encoder library info */ 129 #define SACENC_LIB_VL0 2 130 #define SACENC_LIB_VL1 0 131 #define SACENC_LIB_VL2 0 132 #define SACENC_LIB_TITLE "MPEG Surround Encoder" 133 #ifdef __ANDROID__ 134 #define SACENC_LIB_BUILD_DATE "" 135 #define SACENC_LIB_BUILD_TIME "" 136 #else 137 #define SACENC_LIB_BUILD_DATE __DATE__ 138 #define SACENC_LIB_BUILD_TIME __TIME__ 139 #endif 140 141 #define MAX_MPEGS_BYTES (1 << 14) 142 #define MAX_SSC_BYTES (1 << 6) 143 144 #define MAX_SPACE_TREE_CHANNELS 2 145 #define NUM_KEEP_WINDOWS 3 146 147 /* Data Types ****************************************************************/ 148 typedef struct { 149 MP4SPACEENC_MODE encMode; 150 MP4SPACEENC_BANDS_CONFIG nParamBands; 151 MP4SPACEENC_QUANTMODE quantMode; 152 UCHAR bUseCoarseQuant; 153 UCHAR bLdMode; 154 UCHAR bTimeDomainDmx; 155 UINT sampleRate; 156 UINT frameTimeSlots; /* e.g. 32 when used with HE-AAC */ 157 UINT independencyFactor; /* how often should we set the independency flag */ 158 INT timeAlignment; /* additional delay for downmix */ 159 160 } MP4SPACEENC_SETUP, *HANDLE_MP4SPACEENC_SETUP; 161 162 struct ENC_CONFIG_SETUP { 163 UCHAR bEncMode_212; 164 UCHAR maxHybridInStaticSlots; 165 LONG maxSamplingrate; 166 INT maxAnalysisLengthTimeSlots; 167 INT maxHybridBands; 168 INT maxQmfBands; 169 INT maxChIn; 170 INT maxFrameTimeSlots; 171 INT maxFrameLength; 172 INT maxChOut; 173 INT maxChTotOut; 174 }; 175 176 struct MP4SPACE_ENCODER { 177 MP4SPACEENC_SETUP user; 178 179 ENC_CONFIG_SETUP setup; /* describe allocated instance */ 180 181 HANDLE_FRAMEWINDOW 182 hFrameWindow; /* Windowing, only created+updated, but not used */ 183 INT nSamplesValid; /* Input Buffer Handling */ 184 185 /* Routing Sensible Switches/Variables */ 186 MP4SPACEENC_BANDS_CONFIG nParamBands; 187 UCHAR useTimeDomDownmix; 188 189 /* not Routing Sensible Switches/Varibles - must be contained in Check */ 190 MP4SPACEENC_MODE encMode; 191 UCHAR bEncMode_212_only; 192 193 /* not Routing Sensible Switches/Varibles + lower Classes */ 194 UCHAR useFrameKeep; 195 UINT independencyFactor; 196 UINT nSampleRate; 197 UCHAR nInputChannels; 198 UCHAR nOutputChannels; 199 UCHAR nFrameTimeSlots; /* e.g. 32 when used with HE-AAC */ 200 UCHAR nQmfBands; 201 UCHAR nHybridBands; 202 UINT nFrameLength; /* number of output waveform samples/channel/frame */ 203 204 /* not Routing Sensible Switches/Varibles + lower Classes, secondary computed 205 */ 206 INT nSamplesNext; 207 INT nAnalysisLengthTimeSlots; 208 INT nAnalysisLookaheadTimeSlots; 209 INT nUpdateHybridPositionTimeSlots; 210 INT *pnOutputBits; 211 INT nInputDelay; 212 INT nOutputBufferDelay; 213 INT nSurroundAnalysisBufferDelay; 214 INT nBitstreamDelayBuffer; 215 INT nBitstreamBufferRead; 216 INT nBitstreamBufferWrite; 217 INT nDiscardOutFrames; 218 INT avoid_keep; 219 220 /* not Routing Sensible Switches/Varibles -> moved to lower Classes */ 221 UCHAR useCoarseQuantCld; /* Only Used in SpaceTreeSetup */ 222 UCHAR useCoarseQuantIcc; /* Only Used in SpaceTreeSetup */ 223 UCHAR useCoarseQuantCpc; /* Only Used in SpaceTreeSetup */ 224 UCHAR useCoarseQuantArbDmx; /* ArbitraryDmx,... not available yet */ 225 MP4SPACEENC_QUANTMODE 226 quantMode; /* Used for quanitzation and in bitstream writer */ 227 INT coreCoderDelay; /* Used in delay compensation */ 228 INT timeAlignment; /* Used in delay compensation */ 229 230 /* Local Processing Variables */ 231 INT independencyCount; 232 INT independencyFlag; 233 INT **ppTrCurrPos; /* belongs somehow to Onset Detection */ 234 INT trPrevPos[2 * MAX_NUM_TRANS]; /* belongs somehow to Onset Detection */ 235 236 FRAMEWIN_LIST frameWinList; 237 SPATIALFRAME saveFrame; 238 239 /* Module-Handles */ 240 SPACE_TREE_SETUP spaceTreeSetup; 241 MPEG4SPACEENC_SSCBUF sscBuf; 242 FIXP_WIN *pFrameWindowAna__FDK[MAX_NUM_PARAMS]; 243 HANDLE_QMF_FILTER_BANK *phQmfFiltIn__FDK; 244 HANDLE_DC_FILTER phDCFilterSigIn[SACENC_MAX_INPUT_CHANNELS]; 245 HANDLE_ONSET_DETECT phOnset[SACENC_MAX_INPUT_CHANNELS]; 246 HANDLE_SPACE_TREE hSpaceTree; 247 HANDLE_BSF_INSTANCE hBitstreamFormatter; 248 HANDLE_STATIC_GAIN_CONFIG hStaticGainConfig; 249 HANDLE_STATIC_GAIN hStaticGain; 250 HANDLE_DELAY hDelay; 251 252 /* enhanced time domain downmix (for stereo input) */ 253 HANDLE_ENHANCED_TIME_DOMAIN_DMX hEnhancedTimeDmx; 254 255 /* Data Buffers */ 256 INT_PCM **ppTimeSigIn__FDK; 257 INT_PCM **ppTimeSigDelayIn__FDK; 258 INT_PCM **ppTimeSigOut__FDK; 259 FIXP_DPK ***pppHybridIn__FDK; 260 FIXP_DPK ***pppHybridInStatic__FDK; 261 FIXP_DPK ***pppProcDataIn__FDK; 262 INT_PCM *pOutputDelayBuffer__FDK; 263 264 UCHAR **ppBitstreamDelayBuffer; 265 266 UCHAR *pParameterBand2HybridBandOffset; 267 INT staticGainScale; 268 269 INT *pEncoderInputChScale; 270 INT *staticTimeDomainDmxInScale; 271 }; 272 273 /* Constants *****************************************************************/ 274 static const UCHAR pValidBands_Ld[8] = {4, 5, 7, 9, 12, 15, 23, 40}; 275 276 static const UCHAR qmf2qmf[] = /* Bypass the HybridAnylyis/Synthesis*/ 277 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 278 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 279 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 280 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 281 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 282 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 283 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 284 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 285 120, 121, 122, 123, 124, 125, 126, 127}; 286 287 /* Function / Class Declarations *********************************************/ 288 static FDK_SACENC_ERROR mp4SpaceEnc_create( 289 HANDLE_MP4SPACE_ENCODER *phMp4SpaceEnc); 290 291 static FDK_SACENC_ERROR FillSpatialSpecificConfig( 292 const HANDLE_MP4SPACE_ENCODER hEnc, SPATIALSPECIFICCONFIG *const hSsc); 293 294 static FDK_SACENC_ERROR mp4SpaceEnc_FillSpaceTreeSetup( 295 const HANDLE_MP4SPACE_ENCODER hEnc, 296 SPACE_TREE_SETUP *const hSpaceTreeSetup); 297 298 static FDK_SACENC_ERROR mp4SpaceEnc_InitDelayCompensation( 299 HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc, const INT coreCoderDelay); 300 301 static FDK_SACENC_ERROR mp4SpaceEnc_InitDefault( 302 HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc); 303 304 static DECORRCONFIG mp4SpaceEnc_GetDecorrConfig(const MP4SPACEENC_MODE encMode); 305 306 static FDK_SACENC_ERROR mp4SpaceEnc_InitNumParamBands( 307 HANDLE_MP4SPACE_ENCODER hEnc, const MP4SPACEENC_BANDS_CONFIG nParamBands); 308 309 /* Function / Class Definition ***********************************************/ 310 static UINT mp4SpaceEnc_GetNumQmfBands(const UINT nSampleRate) { 311 UINT nQmfBands = 0; 312 313 if (nSampleRate < 27713) 314 nQmfBands = 32; 315 else if (nSampleRate < 55426) 316 nQmfBands = 64; 317 318 return nQmfBands; 319 } 320 321 static UINT updateQmfFlags(const UINT flags, const INT keepStates) { 322 UINT qmfFlags = flags; 323 324 qmfFlags = (qmfFlags & (~(UINT)QMF_FLAG_LP)); 325 qmfFlags = (qmfFlags | QMF_FLAG_MPSLDFB); 326 qmfFlags = (keepStates) ? (qmfFlags | QMF_FLAG_KEEP_STATES) 327 : (qmfFlags & (~(UINT)QMF_FLAG_KEEP_STATES)); 328 329 return qmfFlags; 330 } 331 332 static INT freq2HybridBand(const UINT nFrequency, const UINT nSampleRate, 333 const UINT nQmfBands) { 334 /* 335 nQmfSlotWidth = (nSampleRate/2) / nQmfBands; 336 nQmfBand = nFrequency / nQmfSlotWidth; 337 */ 338 int nHybridBand = -1; 339 int scale = 0; 340 const FIXP_DBL temp = fDivNorm((FIXP_DBL)(2 * nFrequency * nQmfBands), 341 (FIXP_DBL)nSampleRate, &scale); 342 const int nQmfBand = scaleValue(temp, scale - (DFRACT_BITS - 1)); 343 344 if ((nQmfBand > -1) && (nQmfBand < (int)nQmfBands)) { 345 nHybridBand = qmf2qmf[nQmfBand]; 346 } 347 348 return nHybridBand; 349 } 350 351 /* 352 * Examine buffer descriptor regarding choosen type. 353 * 354 * \param pBufDesc Pointer to buffer descriptor 355 * \param type Buffer type to look for. 356 357 * \return - Buffer descriptor index. 358 * -1, if there is no entry available. 359 */ 360 static INT getBufDescIdx(const FDK_bufDescr *pBufDesc, const UINT type) { 361 INT i, idx = -1; 362 363 for (i = 0; i < (int)pBufDesc->numBufs; i++) { 364 if (pBufDesc->pBufType[i] == type) { 365 idx = i; 366 break; 367 } 368 } 369 return idx; 370 } 371 372 FDK_SACENC_ERROR FDK_sacenc_open(HANDLE_MP4SPACE_ENCODER *phMp4SpaceEnc) { 373 return mp4SpaceEnc_create(phMp4SpaceEnc); 374 } 375 376 static FDK_SACENC_ERROR mp4SpaceEnc_create( 377 HANDLE_MP4SPACE_ENCODER *phMp4SpaceEnc) { 378 FDK_SACENC_ERROR error = SACENC_OK; 379 HANDLE_MP4SPACE_ENCODER hEnc = NULL; 380 ENC_CONFIG_SETUP setup; 381 382 if (NULL == phMp4SpaceEnc) { 383 error = SACENC_INVALID_HANDLE; 384 } else { 385 int i, ch; 386 FDKmemclear(&setup, sizeof(ENC_CONFIG_SETUP)); 387 388 /* Allocate Encoder Instance */ 389 FDK_ALLOCATE_MEMORY_1D(hEnc, 1, struct MP4SPACE_ENCODER); 390 391 /* Clear everything, also pointers. */ 392 if (NULL != hEnc) { 393 FDKmemclear(hEnc, sizeof(struct MP4SPACE_ENCODER)); 394 } 395 396 setup.maxSamplingrate = 48000; 397 setup.maxFrameTimeSlots = 16; 398 399 setup.maxAnalysisLengthTimeSlots = 3 * setup.maxFrameTimeSlots; 400 setup.maxQmfBands = mp4SpaceEnc_GetNumQmfBands(setup.maxSamplingrate); 401 ; 402 setup.maxHybridBands = setup.maxQmfBands; 403 setup.maxFrameLength = setup.maxQmfBands * setup.maxFrameTimeSlots; 404 405 setup.maxChIn = 2; 406 setup.maxChOut = 1; 407 setup.maxChTotOut = setup.maxChOut; 408 setup.bEncMode_212 = 1; 409 setup.maxHybridInStaticSlots = 24; 410 411 /* Open Static Gain*/ 412 if (SACENC_OK != 413 (error = fdk_sacenc_staticGain_OpenConfig(&hEnc->hStaticGainConfig))) { 414 goto bail; 415 } 416 417 /* enhanced time domain downmix (for stereo input) */ 418 if (SACENC_OK != (error = fdk_sacenc_open_enhancedTimeDomainDmx( 419 &hEnc->hEnhancedTimeDmx, setup.maxFrameLength))) { 420 goto bail; 421 } 422 423 FDK_ALLOCATE_MEMORY_1D(hEnc->pParameterBand2HybridBandOffset, 424 MAX_NUM_PARAM_BANDS, UCHAR); 425 426 /* Create Space Tree first, to get number of in-/output channels */ 427 if (SACENC_OK != (error = fdk_sacenc_spaceTree_Open(&hEnc->hSpaceTree))) { 428 goto bail; 429 } 430 431 FDK_ALLOCATE_MEMORY_1D(hEnc->pEncoderInputChScale, setup.maxChIn, INT); 432 FDK_ALLOCATE_MEMORY_1D(hEnc->staticTimeDomainDmxInScale, setup.maxChIn, 433 INT); 434 435 FDK_ALLOCATE_MEMORY_1D(hEnc->phQmfFiltIn__FDK, setup.maxChIn, 436 HANDLE_QMF_FILTER_BANK); 437 438 /* Allocate Analysis Filterbank Structs */ 439 for (ch = 0; ch < setup.maxChIn; ch++) { 440 FDK_ALLOCATE_MEMORY_1D_INT(hEnc->phQmfFiltIn__FDK[ch], 1, 441 struct QMF_FILTER_BANK, SECT_DATA_L2) 442 FDK_ALLOCATE_MEMORY_1D_INT(hEnc->phQmfFiltIn__FDK[ch]->FilterStates, 443 2 * 5 * setup.maxQmfBands, FIXP_QAS, 444 SECT_DATA_L2) 445 } 446 447 /* Allocate Synthesis Filterbank Structs for arbitrary downmix */ 448 449 /* Allocate DC Filter Struct for normal signal input */ 450 for (ch = 0; ch < setup.maxChIn; ch++) { 451 if (SACENC_OK != 452 (error = fdk_sacenc_createDCFilter(&hEnc->phDCFilterSigIn[ch]))) { 453 goto bail; 454 } 455 } 456 457 /* Open Onset Detection */ 458 for (ch = 0; ch < setup.maxChIn; ch++) { 459 if (SACENC_OK != (error = fdk_sacenc_onsetDetect_Open( 460 &hEnc->phOnset[ch], setup.maxFrameTimeSlots))) { 461 goto bail; 462 } 463 } 464 465 FDK_ALLOCATE_MEMORY_2D(hEnc->ppTrCurrPos, setup.maxChIn, MAX_NUM_TRANS, 466 INT); 467 468 /* Create Windowing */ 469 if (SACENC_OK != 470 (error = fdk_sacenc_frameWindow_Create(&hEnc->hFrameWindow))) { 471 goto bail; 472 } 473 474 /* Open static gain */ 475 if (SACENC_OK != (error = fdk_sacenc_staticGain_Open(&hEnc->hStaticGain))) { 476 goto bail; 477 } 478 479 /* create bitstream encoder */ 480 if (SACENC_OK != (error = fdk_sacenc_createSpatialBitstreamEncoder( 481 &hEnc->hBitstreamFormatter))) { 482 goto bail; 483 } 484 485 FDK_ALLOCATE_MEMORY_1D(hEnc->sscBuf.pSsc, MAX_SSC_BYTES, UCHAR); 486 487 { 488 FDK_ALLOCATE_MEMORY_2D(hEnc->ppTimeSigIn__FDK, setup.maxChIn, 489 setup.maxFrameLength + MAX_DELAY_SURROUND_ANALYSIS, 490 INT_PCM); 491 } 492 FDK_ALLOCATE_MEMORY_2D(hEnc->ppTimeSigDelayIn__FDK, setup.maxChIn, 493 MAX_DELAY_SURROUND_ANALYSIS, INT_PCM); 494 495 /* Create new buffers for several signals (including arbitrary downmix) */ 496 if (setup.bEncMode_212 == 0) { 497 /* pOutputDelayBuffer__FDK buffer is not needed for SACENC_212 mode */ 498 FDK_ALLOCATE_MEMORY_1D( 499 hEnc->pOutputDelayBuffer__FDK, 500 (setup.maxFrameLength + MAX_DELAY_OUTPUT) * setup.maxChOut, INT_PCM); 501 } 502 503 /* allocate buffers */ 504 if (setup.bEncMode_212 == 0) { 505 /* ppTimeSigOut__FDK buffer is not needed for SACENC_212 mode */ 506 FDK_ALLOCATE_MEMORY_2D(hEnc->ppTimeSigOut__FDK, setup.maxChTotOut, 507 setup.maxFrameLength, INT_PCM); 508 } 509 510 if (setup.bEncMode_212 == 1) { 511 /* pppHybridIn__FDK buffer can be reduced by maxFrameTimeSlots/2 slots for 512 * SACENC_212 mode */ 513 FDK_ALLOCATE_MEMORY_3D( 514 hEnc->pppHybridIn__FDK, setup.maxChIn, 515 setup.maxAnalysisLengthTimeSlots - (setup.maxFrameTimeSlots >> 1), 516 setup.maxHybridBands, FIXP_DPK); 517 FDK_ALLOCATE_MEMORY_3D(hEnc->pppHybridInStatic__FDK, setup.maxChIn, 518 setup.maxHybridInStaticSlots, setup.maxHybridBands, 519 FIXP_DPK); 520 } else { 521 FDK_ALLOCATE_MEMORY_3D(hEnc->pppHybridIn__FDK, setup.maxChIn, 522 setup.maxAnalysisLengthTimeSlots, 523 setup.maxHybridBands, FIXP_DPK); 524 } 525 526 if (setup.bEncMode_212 == 0) { 527 /* pppProcDataIn__FDK buffer is not needed for SACENC_212 mode */ 528 FDK_ALLOCATE_MEMORY_3D(hEnc->pppProcDataIn__FDK, MAX_SPACE_TREE_CHANNELS, 529 setup.maxAnalysisLengthTimeSlots, 530 setup.maxHybridBands, FIXP_DPK); 531 } 532 for (i = 0; i < MAX_NUM_PARAMS; i++) { 533 FDK_ALLOCATE_MEMORY_1D(hEnc->pFrameWindowAna__FDK[i], 534 setup.maxAnalysisLengthTimeSlots, FIXP_WIN); 535 } /* for i */ 536 537 if (SACENC_OK != (error = fdk_sacenc_delay_Open(&hEnc->hDelay))) { 538 goto bail; 539 } 540 541 if (setup.bEncMode_212 == 0) { 542 /* ppBitstreamDelayBuffer buffer is not needed for SACENC_212 mode */ 543 FDK_ALLOCATE_MEMORY_2D(hEnc->ppBitstreamDelayBuffer, MAX_BITSTREAM_DELAY, 544 MAX_MPEGS_BYTES, UCHAR); 545 } 546 FDK_ALLOCATE_MEMORY_1D(hEnc->pnOutputBits, MAX_BITSTREAM_DELAY, INT); 547 548 hEnc->setup = setup; /* save configuration used while encoder allocation. */ 549 mp4SpaceEnc_InitDefault(hEnc); 550 551 if (NULL != phMp4SpaceEnc) { 552 *phMp4SpaceEnc = hEnc; /* return encoder handle */ 553 } 554 555 } /* valid handle */ 556 557 return error; 558 559 bail: 560 if (NULL != hEnc) { 561 hEnc->setup = setup; 562 FDK_sacenc_close(&hEnc); 563 } 564 return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error); 565 } 566 567 static FDK_SACENC_ERROR mp4SpaceEnc_InitDefault(HANDLE_MP4SPACE_ENCODER hEnc) { 568 FDK_SACENC_ERROR err = SACENC_OK; 569 570 /* Get default static gain configuration. */ 571 if (SACENC_OK != (err = fdk_sacenc_staticGain_InitDefaultConfig( 572 hEnc->hStaticGainConfig))) { 573 goto bail; 574 } 575 576 bail: 577 return err; 578 } 579 580 static FDK_SACENC_ERROR FDK_sacenc_configure( 581 HANDLE_MP4SPACE_ENCODER hEnc, const HANDLE_MP4SPACEENC_SETUP hSetup) { 582 FDK_SACENC_ERROR error = SACENC_OK; 583 584 hEnc->nSampleRate = hSetup->sampleRate; 585 hEnc->encMode = hSetup->encMode; 586 hEnc->nQmfBands = mp4SpaceEnc_GetNumQmfBands(hEnc->nSampleRate); 587 588 /* Make sure that we have set time domain downmix for 212 */ 589 if (hSetup->encMode == SACENC_212 && hSetup->bTimeDomainDmx == 0) { 590 error = SACENC_INVALID_CONFIG; 591 } else { 592 hEnc->useTimeDomDownmix = hSetup->bTimeDomainDmx; 593 } 594 595 hEnc->timeAlignment = hSetup->timeAlignment; 596 hEnc->quantMode = hSetup->quantMode; 597 598 hEnc->useCoarseQuantCld = hSetup->bUseCoarseQuant; 599 hEnc->useCoarseQuantCpc = hSetup->bUseCoarseQuant; 600 hEnc->useFrameKeep = (hSetup->bLdMode == 2); 601 hEnc->useCoarseQuantIcc = 0; /* not available */ 602 hEnc->useCoarseQuantArbDmx = 0; /* not available for user right now */ 603 hEnc->independencyFactor = hSetup->independencyFactor; 604 hEnc->independencyCount = 0; 605 hEnc->independencyFlag = 1; 606 607 /* set number of Hybrid bands */ 608 hEnc->nHybridBands = hEnc->nQmfBands; 609 hEnc->nFrameTimeSlots = hSetup->frameTimeSlots; 610 mp4SpaceEnc_InitNumParamBands(hEnc, hSetup->nParamBands); 611 612 return error; 613 } 614 615 FDK_SACENC_ERROR FDK_sacenc_init(HANDLE_MP4SPACE_ENCODER hEnc, 616 const INT dmxDelay) { 617 FDK_SACENC_ERROR error = SACENC_OK; 618 619 /* Sanity Checks */ 620 if (NULL == hEnc) { 621 error = SACENC_INVALID_HANDLE; 622 } else { 623 const int initStatesFlag = 1; 624 625 int ch; /* loop counter */ 626 int nChInArbDmx; 627 628 if (SACENC_OK != (error = FDK_sacenc_configure(hEnc, &hEnc->user))) { 629 goto bail; 630 } 631 632 hEnc->bEncMode_212_only = hEnc->setup.bEncMode_212; 633 634 /* Slots per Frame and Frame Length */ 635 if (hEnc->nFrameTimeSlots < 1) { 636 error = SACENC_INVALID_CONFIG; 637 goto bail; 638 } 639 hEnc->nFrameLength = hEnc->nQmfBands * hEnc->nFrameTimeSlots; 640 641 if (hEnc->useFrameKeep == 1) { 642 hEnc->nAnalysisLengthTimeSlots = 3 * hEnc->nFrameTimeSlots; 643 hEnc->nUpdateHybridPositionTimeSlots = hEnc->nFrameTimeSlots; 644 } else { 645 hEnc->nAnalysisLengthTimeSlots = 2 * hEnc->nFrameTimeSlots; 646 hEnc->nUpdateHybridPositionTimeSlots = 0; 647 } 648 649 { 650 hEnc->nAnalysisLookaheadTimeSlots = 651 hEnc->nAnalysisLengthTimeSlots - 3 * hEnc->nFrameTimeSlots / 2; 652 } 653 654 /* init parameterBand2hybridBandOffset table */ 655 fdk_sacenc_calcParameterBand2HybridBandOffset( 656 (BOX_SUBBAND_CONFIG)hEnc->nParamBands, hEnc->nHybridBands, 657 hEnc->pParameterBand2HybridBandOffset); 658 659 /* Fill Setup structure for Space Tree */ 660 if (SACENC_OK != 661 (error = mp4SpaceEnc_FillSpaceTreeSetup(hEnc, &hEnc->spaceTreeSetup))) { 662 goto bail; 663 } 664 665 /* Init space tree configuration */ 666 if (SACENC_OK != 667 (error = fdk_sacenc_spaceTree_Init( 668 hEnc->hSpaceTree, &hEnc->spaceTreeSetup, 669 hEnc->pParameterBand2HybridBandOffset, hEnc->useFrameKeep))) { 670 goto bail; 671 } 672 673 /* Get space tree description and resulting number of input/output channels 674 */ 675 { 676 SPACE_TREE_DESCRIPTION spaceTreeDescription; 677 678 if (SACENC_OK != (error = fdk_sacenc_spaceTree_GetDescription( 679 hEnc->hSpaceTree, &spaceTreeDescription))) { 680 goto bail; 681 } 682 683 hEnc->nInputChannels = 684 spaceTreeDescription.nOutChannels; /* space tree description 685 describes decoder 686 configuration */ 687 hEnc->nOutputChannels = 688 spaceTreeDescription.nInChannels; /* space tree description 689 describes decoder 690 configuration */ 691 } 692 693 nChInArbDmx = 0; 694 695 /* INITIALIZATION */ 696 for (ch = 0; ch < hEnc->nInputChannels; ch++) { 697 /* scaling in analysis qmf filterbank (7) */ 698 hEnc->pEncoderInputChScale[ch] = 7; 699 700 { 701 /* additional scaling in qmf prototype filter for low delay */ 702 hEnc->pEncoderInputChScale[ch] += 1; 703 } 704 705 { hEnc->pEncoderInputChScale[ch] += DC_FILTER_SF; } 706 } /* nInputChannels */ 707 708 /* Init analysis filterbank */ 709 for (ch = 0; ch < hEnc->nInputChannels; ch++) { 710 hEnc->phQmfFiltIn__FDK[ch]->flags = 711 updateQmfFlags(hEnc->phQmfFiltIn__FDK[ch]->flags, !initStatesFlag); 712 713 if (0 != qmfInitAnalysisFilterBank( 714 hEnc->phQmfFiltIn__FDK[ch], 715 (FIXP_QAS *)hEnc->phQmfFiltIn__FDK[ch]->FilterStates, 1, 716 hEnc->nQmfBands, hEnc->nQmfBands, hEnc->nQmfBands, 717 hEnc->phQmfFiltIn__FDK[ch]->flags)) { 718 error = SACENC_INIT_ERROR; 719 goto bail; 720 } 721 } 722 723 /* Initialize DC Filter. */ 724 { 725 for (ch = 0; ch < hEnc->nInputChannels; ch++) { 726 if (SACENC_OK != (error = fdk_sacenc_initDCFilter( 727 hEnc->phDCFilterSigIn[ch], hEnc->nSampleRate))) { 728 goto bail; 729 } 730 } 731 } 732 733 /* Init onset detect. */ 734 { 735 /* init onset detect configuration struct */ 736 ONSET_DETECT_CONFIG onsetDetectConfig; 737 onsetDetectConfig.maxTimeSlots = hEnc->nFrameTimeSlots; 738 onsetDetectConfig.lowerBoundOnsetDetection = 739 freq2HybridBand(1725, hEnc->nSampleRate, hEnc->nQmfBands); 740 onsetDetectConfig.upperBoundOnsetDetection = hEnc->nHybridBands; 741 742 for (ch = 0; ch < hEnc->nInputChannels; ch++) { 743 if (SACENC_OK != (error = fdk_sacenc_onsetDetect_Init( 744 hEnc->phOnset[ch], &onsetDetectConfig, 1))) { 745 goto bail; 746 } 747 } 748 } 749 750 { 751 /* init windowing */ 752 FRAMEWINDOW_CONFIG framewindowConfig; 753 framewindowConfig.nTimeSlotsMax = hEnc->nFrameTimeSlots; 754 framewindowConfig.bFrameKeep = hEnc->useFrameKeep; 755 756 if (SACENC_OK != (error = fdk_sacenc_frameWindow_Init( 757 hEnc->hFrameWindow, &framewindowConfig))) { 758 goto bail; 759 } 760 } 761 762 /* Set encoder mode for static gain initialization. */ 763 if (SACENC_OK != (error = fdk_sacenc_staticGain_SetEncMode( 764 hEnc->hStaticGainConfig, hEnc->encMode))) { 765 goto bail; 766 } 767 768 /* Init static gain. */ 769 if (SACENC_OK != (error = fdk_sacenc_staticGain_Init( 770 hEnc->hStaticGain, hEnc->hStaticGainConfig, 771 &(hEnc->staticGainScale)))) { 772 goto bail; 773 } 774 775 for (ch = 0; ch < hEnc->nInputChannels; ch++) { 776 hEnc->pEncoderInputChScale[ch] += hEnc->staticGainScale; 777 } 778 779 /* enhanced downmix for stereo input*/ 780 if (hEnc->useTimeDomDownmix != 0) { 781 if (SACENC_OK != (error = fdk_sacenc_init_enhancedTimeDomainDmx( 782 hEnc->hEnhancedTimeDmx, 783 fdk_sacenc_getPreGainPtrFDK(hEnc->hStaticGain), 784 hEnc->staticGainScale, 785 fdk_sacenc_getPostGainFDK(hEnc->hStaticGain), 786 hEnc->staticGainScale, hEnc->nFrameLength))) { 787 goto bail; 788 } 789 } 790 791 /* Create config structure for bitstream formatter including arbitrary 792 * downmix residual */ 793 if (SACENC_OK != (error = fdk_sacenc_initSpatialBitstreamEncoder( 794 hEnc->hBitstreamFormatter))) { 795 goto bail; 796 } 797 798 if (SACENC_OK != (error = FillSpatialSpecificConfig( 799 hEnc, fdk_sacenc_getSpatialSpecificConfig( 800 hEnc->hBitstreamFormatter)))) { 801 goto bail; 802 } 803 804 if (SACENC_OK != 805 (error = fdk_sacenc_writeSpatialSpecificConfig( 806 fdk_sacenc_getSpatialSpecificConfig(hEnc->hBitstreamFormatter), 807 hEnc->sscBuf.pSsc, MAX_SSC_BYTES, &hEnc->sscBuf.nSscSizeBits))) { 808 goto bail; 809 } 810 811 /* init delay compensation with dmx core coder delay; if no core coder is 812 * used, many other buffers are initialized nevertheless */ 813 if (SACENC_OK != 814 (error = mp4SpaceEnc_InitDelayCompensation(hEnc, dmxDelay))) { 815 goto bail; 816 } 817 818 /* How much input do we need? */ 819 hEnc->nSamplesNext = 820 hEnc->nFrameLength * (hEnc->nInputChannels + nChInArbDmx); 821 hEnc->nSamplesValid = 0; 822 } /* valid handle */ 823 824 bail: 825 return error; 826 } 827 828 static INT getAnalysisLengthTimeSlots(FIXP_WIN *pFrameWindowAna, 829 INT nTimeSlots) { 830 int i; 831 for (i = nTimeSlots - 1; i >= 0; i--) { 832 if (pFrameWindowAna[i] != (FIXP_WIN)0) { 833 break; 834 } 835 } 836 nTimeSlots = i + 1; 837 return nTimeSlots; 838 } 839 840 static INT getAnalysisStartTimeSlot(FIXP_WIN *pFrameWindowAna, INT nTimeSlots) { 841 int startTimeSlot = 0; 842 int i; 843 for (i = 0; i < nTimeSlots; i++) { 844 if (pFrameWindowAna[i] != (FIXP_WIN)0) { 845 break; 846 } 847 } 848 startTimeSlot = i; 849 return startTimeSlot; 850 } 851 852 static FDK_SACENC_ERROR __FeedDeinterPreScale( 853 HANDLE_MP4SPACE_ENCODER hEnc, INT_PCM const *const pSamples, 854 INT_PCM *const pOutputSamples, INT const nSamples, 855 UINT const isInputInterleaved, UINT const inputBufferSizePerChannel, 856 UINT *const pnSamplesFed) { 857 FDK_SACENC_ERROR error = SACENC_OK; 858 859 if ((hEnc == NULL) || (pSamples == NULL) || (pnSamplesFed == NULL)) { 860 error = SACENC_INVALID_HANDLE; 861 } else if (nSamples == 0) { 862 error = SACENC_INVALID_CONFIG; /* Flushing not implemented */ 863 } else { 864 int ch; 865 const INT nChIn = hEnc->nInputChannels; 866 const INT nChInWithDmx = nChIn; 867 const INT samplesToFeed = 868 FDKmin(nSamples, hEnc->nSamplesNext - hEnc->nSamplesValid); 869 const INT nSamplesPerChannel = samplesToFeed / nChInWithDmx; 870 871 if ((samplesToFeed < 0) || (samplesToFeed % nChInWithDmx != 0) || 872 (samplesToFeed > nChInWithDmx * (INT)hEnc->nFrameLength)) { 873 error = SACENC_INVALID_CONFIG; 874 goto bail; 875 } 876 int i; 877 878 const INT_PCM *pInput__FDK; 879 const INT_PCM *pInput2__FDK; 880 881 { /* no dmx align = default*/ 882 pInput__FDK = pSamples; 883 pInput2__FDK = pSamples + (hEnc->nInputDelay * nChInWithDmx); 884 } 885 886 for (i = 0; i < hEnc->nInputChannels; i++) { 887 hEnc->staticTimeDomainDmxInScale[i] = hEnc->staticGainScale; 888 } 889 890 /***** N-channel-input *****/ 891 for (ch = 0; ch < nChIn; ch++) { 892 /* Write delayed time signal into time signal buffer */ 893 FDKmemcpy(&(hEnc->ppTimeSigIn__FDK[ch][0]), 894 &(hEnc->ppTimeSigDelayIn__FDK[ch][0]), 895 hEnc->nSurroundAnalysisBufferDelay * sizeof(INT_PCM)); 896 897 if (isInputInterleaved) { 898 /* Add the new frame de-interleaved. Apply nSurroundAnalysisBufferDelay. 899 */ 900 FDKmemcpy_flex( 901 &(hEnc->ppTimeSigIn__FDK[ch][hEnc->nSurroundAnalysisBufferDelay]), 902 1, pInput__FDK + ch, nChInWithDmx, hEnc->nInputDelay); 903 FDKmemcpy_flex( 904 &(hEnc->ppTimeSigIn__FDK[ch][hEnc->nSurroundAnalysisBufferDelay + 905 hEnc->nInputDelay]), 906 1, pInput2__FDK + ch, nChInWithDmx, 907 nSamplesPerChannel - hEnc->nInputDelay); 908 } else { 909 /* Input is already deinterleaved, just copy */ 910 FDKmemcpy( 911 &(hEnc->ppTimeSigIn__FDK[ch][hEnc->nSurroundAnalysisBufferDelay]), 912 pInput__FDK + ch * inputBufferSizePerChannel, 913 hEnc->nInputDelay * sizeof(INT_PCM)); 914 FDKmemcpy( 915 &(hEnc->ppTimeSigIn__FDK[ch][hEnc->nSurroundAnalysisBufferDelay + 916 hEnc->nInputDelay]), 917 pInput2__FDK + ch * inputBufferSizePerChannel, 918 (nSamplesPerChannel - hEnc->nInputDelay) * sizeof(INT_PCM)); 919 } 920 921 /* Update time signal delay buffer */ 922 FDKmemcpy(&(hEnc->ppTimeSigDelayIn__FDK[ch][0]), 923 &(hEnc->ppTimeSigIn__FDK[ch][hEnc->nFrameLength]), 924 hEnc->nSurroundAnalysisBufferDelay * sizeof(INT_PCM)); 925 } /* for ch */ 926 927 /***** No Arbitrary Downmix *****/ 928 /* "Crude TD Dmx": Time DomainDownmix + NO Arbitrary Downmix, Delay Added at 929 * pOutputBuffer */ 930 if ((hEnc->useTimeDomDownmix > 0)) { 931 if ((hEnc->useTimeDomDownmix == 1) || (hEnc->nInputChannels != 2)) { 932 error = SACENC_INVALID_CONFIG; 933 goto bail; 934 } else { 935 /* enhanced time domain downmix (for stereo input) */ 936 if (hEnc->encMode == SACENC_212) { 937 if (pOutputSamples == NULL) { 938 error = SACENC_INVALID_HANDLE; 939 goto bail; 940 } 941 942 fdk_sacenc_apply_enhancedTimeDomainDmx( 943 hEnc->hEnhancedTimeDmx, hEnc->ppTimeSigIn__FDK, pOutputSamples, 944 hEnc->nSurroundAnalysisBufferDelay); 945 } else { 946 if (&hEnc->ppTimeSigOut__FDK[0][0] == NULL) { 947 error = SACENC_INVALID_HANDLE; 948 goto bail; 949 } 950 951 fdk_sacenc_apply_enhancedTimeDomainDmx( 952 hEnc->hEnhancedTimeDmx, hEnc->ppTimeSigIn__FDK, 953 &hEnc->ppTimeSigOut__FDK[0][0], 954 hEnc->nSurroundAnalysisBufferDelay); 955 } 956 } 957 } 958 959 /* update number of samples still to process */ 960 hEnc->nSamplesValid += samplesToFeed; 961 962 /*return number of fed samples */ 963 *pnSamplesFed = samplesToFeed; 964 } 965 bail: 966 return error; 967 } 968 969 FDK_SACENC_ERROR FDK_sacenc_encode(const HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc, 970 const FDK_bufDescr *inBufDesc, 971 const FDK_bufDescr *outBufDesc, 972 const SACENC_InArgs *inargs, 973 SACENC_OutArgs *outargs) { 974 FDK_SACENC_ERROR error = SACENC_OK; 975 976 const INT_PCM *pInputSamples = 977 (const INT_PCM *)inBufDesc->ppBase[getBufDescIdx( 978 inBufDesc, (FDK_BUF_TYPE_INPUT | FDK_BUF_TYPE_PCM_DATA))]; 979 980 INT_PCM *const pOutputSamples = (INT_PCM *)outBufDesc->ppBase[getBufDescIdx( 981 outBufDesc, (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_PCM_DATA))]; 982 983 const int nOutputSamplesBufferSize = 984 outBufDesc->pBufSize[getBufDescIdx( 985 outBufDesc, (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_PCM_DATA))] / 986 outBufDesc->pEleSize[getBufDescIdx( 987 outBufDesc, (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_PCM_DATA))]; 988 989 if ((hMp4SpaceEnc == NULL) || (pInputSamples == NULL)) { 990 error = SACENC_INVALID_HANDLE; 991 } else { 992 int nOutputSamples; 993 int i, ch, ps, winCnt, ts, slot; 994 INT currTransPos = -1; 995 SPATIALFRAME *pFrameData = NULL; 996 997 /* Improve Code Readability */ 998 const int nChIn = hMp4SpaceEnc->nInputChannels; 999 const int nChInWithDmx = nChIn; 1000 const int nChOut = hMp4SpaceEnc->nOutputChannels; 1001 const int nSamplesPerChannel = inargs->nInputSamples / nChInWithDmx; 1002 const int nOutputSamplesMax = nSamplesPerChannel * nChOut; 1003 const int nFrameTimeSlots = hMp4SpaceEnc->nFrameTimeSlots; 1004 1005 INT encoderInputChScale[SACENC_MAX_INPUT_CHANNELS]; 1006 INT nFrameTimeSlotsReduction = 0; 1007 1008 if (hMp4SpaceEnc->encMode == SACENC_212) { 1009 nFrameTimeSlotsReduction = hMp4SpaceEnc->nFrameTimeSlots >> 1; 1010 } 1011 1012 for (i = 0; i < nChIn; i++) 1013 encoderInputChScale[i] = hMp4SpaceEnc->pEncoderInputChScale[i]; 1014 1015 /* Sanity Check */ 1016 if ((0 != inargs->nInputSamples % nChInWithDmx)) { 1017 error = SACENC_INVALID_CONFIG; 1018 goto bail; 1019 } 1020 1021 /* 1022 * Get Frame Data Handle. 1023 */ 1024 1025 /* get bitstream handle (for storage of cld's, icc's and so on) 1026 * get spatialframe 2 frames in the future; NOTE: this is necessary to 1027 * synchronise spatial data and audio data */ 1028 if (NULL == (pFrameData = fdk_sacenc_getSpatialFrame( 1029 hMp4SpaceEnc->hBitstreamFormatter, WRITE_SPATIALFRAME))) { 1030 error = SACENC_INVALID_HANDLE; 1031 goto bail; 1032 } 1033 1034 /* Independent Frames Counters*/ 1035 if (hMp4SpaceEnc->nDiscardOutFrames > 1036 0) { /* Independent Frames if they should be discarded, Reset Counter*/ 1037 hMp4SpaceEnc->independencyCount = 1038 0; /* Reset the counter, first valid frame is an independent one*/ 1039 hMp4SpaceEnc->independencyFlag = 1; 1040 } else { /*hMp4SpaceEnc->nDiscardOutFrames == 0*/ 1041 hMp4SpaceEnc->independencyFlag = 1042 (hMp4SpaceEnc->independencyCount == 0) ? 1 : 0; 1043 if (hMp4SpaceEnc->independencyFactor > 0) { 1044 hMp4SpaceEnc->independencyCount++; 1045 hMp4SpaceEnc->independencyCount = 1046 hMp4SpaceEnc->independencyCount % 1047 ((int)hMp4SpaceEnc->independencyFactor); 1048 } else { /* independencyFactor == 0 */ 1049 hMp4SpaceEnc->independencyCount = -1; 1050 } 1051 } 1052 1053 /* 1054 * Time signal preprocessing: 1055 * - Feed input buffer 1056 * - Prescale time signal 1057 * - Apply DC filter on input signal 1058 */ 1059 1060 /* Feed, Deinterleave, Pre-Scale the input time signals */ 1061 if (SACENC_OK != 1062 (error = __FeedDeinterPreScale( 1063 hMp4SpaceEnc, pInputSamples, pOutputSamples, inargs->nInputSamples, 1064 inargs->isInputInterleaved, inargs->inputBufferSizePerChannel, 1065 &outargs->nSamplesConsumed))) { 1066 goto bail; 1067 } 1068 1069 if (hMp4SpaceEnc->nSamplesNext != hMp4SpaceEnc->nSamplesValid) { 1070 error = SACENC_INVALID_CONFIG; 1071 goto bail; 1072 } 1073 1074 if (hMp4SpaceEnc->encMode == SACENC_212 && 1075 hMp4SpaceEnc->bEncMode_212_only) { 1076 for (ch = 0; ch < nChIn; ch++) { 1077 for (slot = 0; slot < nFrameTimeSlots; slot++) { 1078 setCplxVec( 1079 hMp4SpaceEnc->pppHybridIn__FDK 1080 [ch][hMp4SpaceEnc->nUpdateHybridPositionTimeSlots + 1081 nFrameTimeSlots - nFrameTimeSlotsReduction + slot], 1082 (FIXP_DBL)0, hMp4SpaceEnc->nHybridBands); 1083 } 1084 } 1085 } 1086 1087 /* 1088 * Time / Frequency: 1089 * - T/F audio input channels 1090 * - T/F arbitrary downmix input channels 1091 */ 1092 for (ch = 0; ch < nChIn; ch++) { 1093 C_AALLOC_SCRATCH_START(pQmfInReal, FIXP_DBL, MAX_QMF_BANDS) 1094 C_AALLOC_SCRATCH_START(pQmfInImag, FIXP_DBL, MAX_QMF_BANDS) 1095 FIXP_GAIN *pPreGain = 1096 fdk_sacenc_getPreGainPtrFDK(hMp4SpaceEnc->hStaticGain); 1097 1098 for (ts = 0; ts < nFrameTimeSlots; ts++) { 1099 FIXP_DBL *pSpecReal; 1100 FIXP_DBL *pSpecImag; 1101 1102 INT_PCM *pTimeIn = 1103 &hMp4SpaceEnc->ppTimeSigIn__FDK[ch][(ts * hMp4SpaceEnc->nQmfBands)]; 1104 1105 { 1106 /* Apply DC filter on input channels */ 1107 if (SACENC_OK != (error = fdk_sacenc_applyDCFilter( 1108 hMp4SpaceEnc->phDCFilterSigIn[ch], pTimeIn, 1109 pTimeIn, hMp4SpaceEnc->nQmfBands))) { 1110 goto bail; 1111 } 1112 } 1113 1114 /* QMF filterbank */ 1115 C_ALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL, (MAX_QMF_BANDS << 1)); 1116 1117 qmfAnalysisFilteringSlot(hMp4SpaceEnc->phQmfFiltIn__FDK[ch], pQmfInReal, 1118 pQmfInImag, pTimeIn, 1, pWorkBuffer); 1119 1120 C_ALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, (MAX_QMF_BANDS << 1)); 1121 1122 pSpecReal = pQmfInReal; 1123 pSpecImag = pQmfInImag; 1124 1125 /* Apply pre-scale after filterbank */ 1126 if (MAXVAL_GAIN != pPreGain[ch]) { 1127 for (i = 0; i < hMp4SpaceEnc->nHybridBands; i++) { 1128 hMp4SpaceEnc 1129 ->pppHybridIn__FDK[ch] 1130 [hMp4SpaceEnc->nAnalysisLookaheadTimeSlots + 1131 ts][i] 1132 .v.re = fMult(pSpecReal[i], pPreGain[ch]); 1133 hMp4SpaceEnc 1134 ->pppHybridIn__FDK[ch] 1135 [hMp4SpaceEnc->nAnalysisLookaheadTimeSlots + 1136 ts][i] 1137 .v.im = fMult(pSpecImag[i], pPreGain[ch]); 1138 } 1139 } else { 1140 for (i = 0; i < hMp4SpaceEnc->nHybridBands; i++) { 1141 hMp4SpaceEnc 1142 ->pppHybridIn__FDK[ch] 1143 [hMp4SpaceEnc->nAnalysisLookaheadTimeSlots + 1144 ts][i] 1145 .v.re = pSpecReal[i]; 1146 hMp4SpaceEnc 1147 ->pppHybridIn__FDK[ch] 1148 [hMp4SpaceEnc->nAnalysisLookaheadTimeSlots + 1149 ts][i] 1150 .v.im = pSpecImag[i]; 1151 } 1152 } 1153 } /* ts */ 1154 C_AALLOC_SCRATCH_END(pQmfInImag, FIXP_DBL, MAX_QMF_BANDS) 1155 C_AALLOC_SCRATCH_END(pQmfInReal, FIXP_DBL, MAX_QMF_BANDS) 1156 1157 if (SACENC_OK != error) { 1158 goto bail; 1159 } 1160 } /* ch */ 1161 1162 if (hMp4SpaceEnc->encMode == SACENC_212 && 1163 hMp4SpaceEnc->bEncMode_212_only) { 1164 for (ch = 0; ch < nChIn; ch++) { 1165 for (slot = 0; 1166 slot < (int)(hMp4SpaceEnc->nUpdateHybridPositionTimeSlots + 1167 nFrameTimeSlots - nFrameTimeSlotsReduction); 1168 slot++) { 1169 copyCplxVec(hMp4SpaceEnc->pppHybridIn__FDK[ch][slot], 1170 hMp4SpaceEnc->pppHybridInStatic__FDK[ch][slot], 1171 hMp4SpaceEnc->nHybridBands); 1172 } 1173 } 1174 for (ch = 0; ch < nChIn; ch++) { 1175 for (slot = 0; 1176 slot < (int)(hMp4SpaceEnc->nUpdateHybridPositionTimeSlots + 1177 nFrameTimeSlots - nFrameTimeSlotsReduction); 1178 slot++) { 1179 copyCplxVec( 1180 hMp4SpaceEnc->pppHybridInStatic__FDK[ch][slot], 1181 hMp4SpaceEnc->pppHybridIn__FDK[ch][nFrameTimeSlots + slot], 1182 hMp4SpaceEnc->nHybridBands); 1183 } 1184 } 1185 } 1186 1187 /* 1188 * Onset Detection: 1189 * - detection of transients 1190 * - build framing 1191 */ 1192 for (ch = 0; ch < nChIn; ch++) { 1193 if (ch != 3) { /* !LFE */ 1194 if (SACENC_OK != 1195 (error = fdk_sacenc_onsetDetect_Apply( 1196 hMp4SpaceEnc->phOnset[ch], nFrameTimeSlots, 1197 hMp4SpaceEnc->nHybridBands, 1198 &hMp4SpaceEnc->pppHybridIn__FDK 1199 [ch][hMp4SpaceEnc->nAnalysisLookaheadTimeSlots], 1200 encoderInputChScale[ch], 1201 hMp4SpaceEnc->trPrevPos[1], /* contains previous Transient */ 1202 hMp4SpaceEnc->ppTrCurrPos[ch]))) { 1203 goto bail; 1204 } 1205 1206 if ((1) && (hMp4SpaceEnc->useFrameKeep == 0)) { 1207 hMp4SpaceEnc->ppTrCurrPos[ch][0] = -1; 1208 } 1209 1210 /* Find first Transient Position */ 1211 if ((hMp4SpaceEnc->ppTrCurrPos[ch][0] >= 0) && 1212 ((currTransPos < 0) || 1213 (hMp4SpaceEnc->ppTrCurrPos[ch][0] < currTransPos))) { 1214 currTransPos = hMp4SpaceEnc->ppTrCurrPos[ch][0]; 1215 } 1216 } /* !LFE */ 1217 } /* ch */ 1218 1219 if (hMp4SpaceEnc->useFrameKeep == 1) { 1220 if ((currTransPos != -1) || (hMp4SpaceEnc->independencyFlag == 1)) { 1221 hMp4SpaceEnc->avoid_keep = NUM_KEEP_WINDOWS; 1222 currTransPos = -1; 1223 } 1224 } 1225 1226 /* Save previous Transient Position */ 1227 hMp4SpaceEnc->trPrevPos[0] = 1228 FDKmax(-1, hMp4SpaceEnc->trPrevPos[1] - (INT)nFrameTimeSlots); 1229 hMp4SpaceEnc->trPrevPos[1] = currTransPos; 1230 1231 /* Update Onset Detection Energy Buffer */ 1232 for (ch = 0; ch < nChIn; ch++) { 1233 if (SACENC_OK != (error = fdk_sacenc_onsetDetect_Update( 1234 hMp4SpaceEnc->phOnset[ch], nFrameTimeSlots))) { 1235 goto bail; 1236 } 1237 } 1238 1239 /* Framing */ 1240 if (SACENC_OK != 1241 (error = fdk_sacenc_frameWindow_GetWindow( 1242 hMp4SpaceEnc->hFrameWindow, hMp4SpaceEnc->trPrevPos, 1243 nFrameTimeSlots, &pFrameData->framingInfo, 1244 hMp4SpaceEnc->pFrameWindowAna__FDK, &hMp4SpaceEnc->frameWinList, 1245 hMp4SpaceEnc->avoid_keep))) { 1246 goto bail; 1247 } 1248 1249 /* 1250 * MPS Processing: 1251 */ 1252 for (ps = 0, winCnt = 0; ps < hMp4SpaceEnc->frameWinList.n; ++ps) { 1253 /* Analysis Windowing */ 1254 if (hMp4SpaceEnc->frameWinList.dat[ps].hold == FW_HOLD) { 1255 /* ************************************** */ 1256 /* ONLY COPY AND HOLD PREVIOUS PARAMETERS */ 1257 if (SACENC_OK != (error = fdk_sacenc_duplicateParameterSet( 1258 &hMp4SpaceEnc->saveFrame, 0, pFrameData, ps))) { 1259 goto bail; 1260 } 1261 1262 } else { /* !FW_HOLD */ 1263 /* ************************************** */ 1264 /* NEW WINDOW */ 1265 1266 INT nAnalysisLengthTimeSlots, analysisStartTimeSlot; 1267 1268 nAnalysisLengthTimeSlots = getAnalysisLengthTimeSlots( 1269 hMp4SpaceEnc->pFrameWindowAna__FDK[winCnt], 1270 hMp4SpaceEnc->nAnalysisLengthTimeSlots); 1271 1272 analysisStartTimeSlot = 1273 getAnalysisStartTimeSlot(hMp4SpaceEnc->pFrameWindowAna__FDK[winCnt], 1274 hMp4SpaceEnc->nAnalysisLengthTimeSlots); 1275 1276 /* perform main signal analysis windowing in 1277 * fdk_sacenc_spaceTree_Apply() */ 1278 FIXP_WIN *pFrameWindowAna__FDK = 1279 hMp4SpaceEnc->pFrameWindowAna__FDK[winCnt]; 1280 FIXP_DPK ***pppHybridIn__FDK = hMp4SpaceEnc->pppHybridIn__FDK; 1281 FIXP_DPK ***pppProcDataIn__FDK = hMp4SpaceEnc->pppProcDataIn__FDK; 1282 1283 if (hMp4SpaceEnc->encMode == SACENC_212 && 1284 hMp4SpaceEnc->bEncMode_212_only) { 1285 pppProcDataIn__FDK = pppHybridIn__FDK; 1286 } 1287 1288 if (SACENC_OK != 1289 (error = fdk_sacenc_spaceTree_Apply( 1290 hMp4SpaceEnc->hSpaceTree, ps, nChIn, nAnalysisLengthTimeSlots, 1291 analysisStartTimeSlot, hMp4SpaceEnc->nHybridBands, 1292 pFrameWindowAna__FDK, pppHybridIn__FDK, 1293 pppProcDataIn__FDK, /* multi-channel input */ 1294 pFrameData, hMp4SpaceEnc->avoid_keep, encoderInputChScale))) { 1295 goto bail; 1296 } 1297 1298 /* Save spatial frame for potential hold parameter set */ 1299 if (SACENC_OK != (error = fdk_sacenc_duplicateParameterSet( 1300 pFrameData, ps, &hMp4SpaceEnc->saveFrame, 0))) { 1301 goto bail; 1302 } 1303 1304 ++winCnt; 1305 } 1306 if (hMp4SpaceEnc->avoid_keep > 0) { 1307 hMp4SpaceEnc->avoid_keep--; 1308 } 1309 } /* Loop over Parameter Sets */ 1310 /* ---- End of Processing Loop ---- */ 1311 1312 /* 1313 * Update hybridInReal/Imag buffer and do the same for arbDmx 1314 * this means to move the hybrid data of the current frame to the beginning 1315 * of the 2*nFrameLength-long buffer 1316 */ 1317 if (!(hMp4SpaceEnc->encMode == SACENC_212 && 1318 hMp4SpaceEnc->bEncMode_212_only)) { 1319 for (ch = 0; ch < nChIn; ch++) { /* for automatic downmix */ 1320 for (slot = 0; 1321 slot < (int)(hMp4SpaceEnc->nUpdateHybridPositionTimeSlots + 1322 nFrameTimeSlots - nFrameTimeSlotsReduction); 1323 slot++) { 1324 copyCplxVec( 1325 hMp4SpaceEnc->pppHybridIn__FDK[ch][slot], 1326 hMp4SpaceEnc->pppHybridIn__FDK[ch][nFrameTimeSlots + slot], 1327 hMp4SpaceEnc->nHybridBands); 1328 } 1329 for (slot = 0; slot < nFrameTimeSlots; slot++) { 1330 setCplxVec( 1331 hMp4SpaceEnc->pppHybridIn__FDK 1332 [ch][hMp4SpaceEnc->nUpdateHybridPositionTimeSlots + 1333 nFrameTimeSlots - nFrameTimeSlotsReduction + slot], 1334 (FIXP_DBL)0, hMp4SpaceEnc->nHybridBands); 1335 } 1336 } 1337 } 1338 /* 1339 * Spatial Tonality: 1340 */ 1341 { 1342 /* Smooth config off. */ 1343 FDKmemclear(&pFrameData->smgData, sizeof(pFrameData->smgData)); 1344 } 1345 1346 /* 1347 * Create bitstream 1348 * - control independecy flag 1349 * - write spatial frame 1350 * - return bitstream 1351 */ 1352 UCHAR *pBitstreamDelayBuffer; 1353 1354 if (hMp4SpaceEnc->encMode == SACENC_212) { 1355 /* no bitstream delay buffer for SACENC_212 mode, write bitstream directly 1356 * into the sacOutBuffer buffer which is provided by the core routine */ 1357 pBitstreamDelayBuffer = (UCHAR *)outBufDesc->ppBase[1]; 1358 } else { 1359 /* bitstream delay is handled in ppBitstreamDelayBuffer buffer */ 1360 pBitstreamDelayBuffer = 1361 hMp4SpaceEnc 1362 ->ppBitstreamDelayBuffer[hMp4SpaceEnc->nBitstreamBufferWrite]; 1363 } 1364 if (pBitstreamDelayBuffer == NULL) { 1365 error = SACENC_INVALID_HANDLE; 1366 goto bail; 1367 } 1368 1369 pFrameData->bsIndependencyFlag = hMp4SpaceEnc->independencyFlag; 1370 1371 if (SACENC_OK != 1372 (error = fdk_sacenc_writeSpatialFrame( 1373 pBitstreamDelayBuffer, MAX_MPEGS_BYTES, 1374 &hMp4SpaceEnc->pnOutputBits[hMp4SpaceEnc->nBitstreamBufferWrite], 1375 hMp4SpaceEnc->hBitstreamFormatter))) { 1376 goto bail; 1377 } 1378 1379 /* return bitstream info */ 1380 if ((hMp4SpaceEnc->nDiscardOutFrames == 0) && 1381 (getBufDescIdx(outBufDesc, 1382 (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_BS_DATA)) != -1)) { 1383 const INT idx = getBufDescIdx( 1384 outBufDesc, (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_BS_DATA)); 1385 const INT outBits = 1386 hMp4SpaceEnc->pnOutputBits[hMp4SpaceEnc->nBitstreamBufferRead]; 1387 1388 if (((outBits + 7) / 8) > 1389 (INT)(outBufDesc->pBufSize[idx] / outBufDesc->pEleSize[idx])) { 1390 outargs->nOutputBits = 0; 1391 error = SACENC_ENCODE_ERROR; 1392 goto bail; 1393 } 1394 1395 /* return bitstream buffer, copy delayed bitstream for all configurations 1396 * except for the SACENC_212 mode */ 1397 if (hMp4SpaceEnc->encMode != SACENC_212) { 1398 FDKmemcpy( 1399 outBufDesc->ppBase[idx], 1400 hMp4SpaceEnc 1401 ->ppBitstreamDelayBuffer[hMp4SpaceEnc->nBitstreamBufferRead], 1402 (outBits + 7) / 8); 1403 } 1404 1405 /* return number of valid bits */ 1406 outargs->nOutputBits = outBits; 1407 } else { /* No spatial data should be returned if the current frame is to be 1408 discarded. */ 1409 outargs->nOutputBits = 0; 1410 } 1411 1412 /* update pointers */ 1413 hMp4SpaceEnc->nBitstreamBufferRead = 1414 (hMp4SpaceEnc->nBitstreamBufferRead + 1) % 1415 hMp4SpaceEnc->nBitstreamDelayBuffer; 1416 hMp4SpaceEnc->nBitstreamBufferWrite = 1417 (hMp4SpaceEnc->nBitstreamBufferWrite + 1) % 1418 hMp4SpaceEnc->nBitstreamDelayBuffer; 1419 1420 /* Set Output Parameters */ 1421 nOutputSamples = 1422 (hMp4SpaceEnc->nDiscardOutFrames == 0) 1423 ? (nOutputSamplesMax) 1424 : 0; /* don't output samples in case frames to be discarded */ 1425 if (nOutputSamples > nOutputSamplesBufferSize) { 1426 error = SACENC_INVALID_CONFIG; 1427 goto bail; 1428 } 1429 outargs->nOutputSamples = nOutputSamples; 1430 1431 { /* !bQmfOutput */ 1432 1433 if (hMp4SpaceEnc->encMode != SACENC_212) { 1434 /* delay output samples and interleave them */ 1435 /* note: in case of arbitrary downmix this will always be processed, 1436 * because nOutputSamples != 0, even if bDMXAlign is switched on */ 1437 /* always run copy-func, so nOutputSamplesMax instead of nOutputSamples 1438 */ 1439 for (ch = 0; ch < nChOut; ch++) { 1440 FDKmemcpy_flex( 1441 &hMp4SpaceEnc->pOutputDelayBuffer__FDK 1442 [ch + (hMp4SpaceEnc->nOutputBufferDelay) * nChOut], 1443 nChOut, hMp4SpaceEnc->ppTimeSigOut__FDK[ch], 1, 1444 nOutputSamplesMax / nChOut); 1445 } 1446 1447 /* write delayed data in output pcm stream */ 1448 /* always calculate, limiter must have a lookahead!!! */ 1449 FDKmemcpy(pOutputSamples, hMp4SpaceEnc->pOutputDelayBuffer__FDK, 1450 nOutputSamplesMax * sizeof(INT_PCM)); 1451 1452 /* update delay buffer (move back end to the beginning of the buffer) */ 1453 FDKmemmove( 1454 hMp4SpaceEnc->pOutputDelayBuffer__FDK, 1455 &hMp4SpaceEnc->pOutputDelayBuffer__FDK[nOutputSamplesMax], 1456 nChOut * (hMp4SpaceEnc->nOutputBufferDelay) * sizeof(INT_PCM)); 1457 } 1458 1459 if (hMp4SpaceEnc->useTimeDomDownmix <= 0) { 1460 if (SACENC_OK != (error = fdk_sacenc_staticPostGain_ApplyFDK( 1461 hMp4SpaceEnc->hStaticGain, pOutputSamples, 1462 nOutputSamplesMax, 0))) { 1463 goto bail; 1464 } 1465 } 1466 1467 } /* !bQmfOutput */ 1468 1469 if (hMp4SpaceEnc->nDiscardOutFrames > 0) { 1470 hMp4SpaceEnc->nDiscardOutFrames--; 1471 } 1472 1473 /* Invalidate Input Buffer */ 1474 hMp4SpaceEnc->nSamplesValid = 0; 1475 1476 } /* valid handle */ 1477 bail: 1478 return error; 1479 } 1480 1481 FDK_SACENC_ERROR FDK_sacenc_close(HANDLE_MP4SPACE_ENCODER *phMp4SpaceEnc) { 1482 FDK_SACENC_ERROR error = SACENC_OK; 1483 1484 if (NULL != phMp4SpaceEnc) { 1485 if (NULL != *phMp4SpaceEnc) { 1486 int ch, i; 1487 HANDLE_MP4SPACE_ENCODER const hEnc = *phMp4SpaceEnc; 1488 1489 if (hEnc->pParameterBand2HybridBandOffset != NULL) { 1490 FDK_FREE_MEMORY_1D(hEnc->pParameterBand2HybridBandOffset); 1491 } 1492 /* Free Analysis Filterbank Structs */ 1493 if (hEnc->pEncoderInputChScale != NULL) { 1494 FDK_FREE_MEMORY_1D(hEnc->pEncoderInputChScale); 1495 } 1496 if (hEnc->staticTimeDomainDmxInScale != NULL) { 1497 FDK_FREE_MEMORY_1D(hEnc->staticTimeDomainDmxInScale); 1498 } 1499 if (hEnc->phQmfFiltIn__FDK != NULL) { 1500 for (ch = 0; ch < hEnc->setup.maxChIn; ch++) { 1501 if (hEnc->phQmfFiltIn__FDK[ch] != NULL) { 1502 if (hEnc->phQmfFiltIn__FDK[ch]->FilterStates != NULL) { 1503 FDK_FREE_MEMORY_1D(hEnc->phQmfFiltIn__FDK[ch]->FilterStates); 1504 } 1505 FDK_FREE_MEMORY_1D(hEnc->phQmfFiltIn__FDK[ch]); 1506 } 1507 } 1508 FDK_FREE_MEMORY_1D(hEnc->phQmfFiltIn__FDK); 1509 } 1510 for (ch = 0; ch < hEnc->setup.maxChIn; ch++) { 1511 if (NULL != hEnc->phDCFilterSigIn[ch]) { 1512 fdk_sacenc_destroyDCFilter(&hEnc->phDCFilterSigIn[ch]); 1513 } 1514 } 1515 /* Close Onset Detection */ 1516 for (ch = 0; ch < hEnc->setup.maxChIn; ch++) { 1517 if (NULL != hEnc->phOnset[ch]) { 1518 fdk_sacenc_onsetDetect_Close(&hEnc->phOnset[ch]); 1519 } 1520 } 1521 if (hEnc->ppTrCurrPos) { 1522 FDK_FREE_MEMORY_2D(hEnc->ppTrCurrPos); 1523 } 1524 if (hEnc->hFrameWindow) { 1525 fdk_sacenc_frameWindow_Destroy(&hEnc->hFrameWindow); 1526 } 1527 /* Close Space Tree */ 1528 if (NULL != hEnc->hSpaceTree) { 1529 fdk_sacenc_spaceTree_Close(&hEnc->hSpaceTree); 1530 } 1531 if (NULL != hEnc->hEnhancedTimeDmx) { 1532 fdk_sacenc_close_enhancedTimeDomainDmx(&hEnc->hEnhancedTimeDmx); 1533 } 1534 /* Close Static Gain */ 1535 if (NULL != hEnc->hStaticGain) { 1536 fdk_sacenc_staticGain_Close(&hEnc->hStaticGain); 1537 } 1538 if (NULL != hEnc->hStaticGainConfig) { 1539 fdk_sacenc_staticGain_CloseConfig(&hEnc->hStaticGainConfig); 1540 } 1541 /* Close Delay*/ 1542 if (NULL != hEnc->hDelay) { 1543 fdk_sacenc_delay_Close(&hEnc->hDelay); 1544 } 1545 /* Delete Bitstream Stuff */ 1546 if (NULL != hEnc->hBitstreamFormatter) { 1547 fdk_sacenc_destroySpatialBitstreamEncoder(&(hEnc->hBitstreamFormatter)); 1548 } 1549 if (hEnc->pppHybridIn__FDK != NULL) { 1550 if (hEnc->setup.bEncMode_212 == 1) { 1551 FDK_FREE_MEMORY_3D(hEnc->pppHybridIn__FDK); 1552 FDK_FREE_MEMORY_3D(hEnc->pppHybridInStatic__FDK); 1553 } else { 1554 FDK_FREE_MEMORY_3D(hEnc->pppHybridIn__FDK); 1555 } 1556 } 1557 if (hEnc->pppProcDataIn__FDK != NULL) { 1558 FDK_FREE_MEMORY_3D(hEnc->pppProcDataIn__FDK); 1559 } 1560 if (hEnc->pOutputDelayBuffer__FDK != NULL) { 1561 FDK_FREE_MEMORY_1D(hEnc->pOutputDelayBuffer__FDK); 1562 } 1563 if (hEnc->ppTimeSigIn__FDK != NULL) { 1564 { FDK_FREE_MEMORY_2D(hEnc->ppTimeSigIn__FDK); } 1565 } 1566 if (hEnc->ppTimeSigDelayIn__FDK != NULL) { 1567 FDK_FREE_MEMORY_2D(hEnc->ppTimeSigDelayIn__FDK); 1568 } 1569 if (hEnc->ppTimeSigOut__FDK != NULL) { 1570 FDK_FREE_MEMORY_2D(hEnc->ppTimeSigOut__FDK); 1571 } 1572 for (i = 0; i < MAX_NUM_PARAMS; i++) { 1573 if (hEnc->pFrameWindowAna__FDK[i] != NULL) { 1574 FDK_FREE_MEMORY_1D(hEnc->pFrameWindowAna__FDK[i]); 1575 } 1576 } 1577 if (hEnc->pnOutputBits != NULL) { 1578 FDK_FREE_MEMORY_1D(hEnc->pnOutputBits); 1579 } 1580 if (hEnc->ppBitstreamDelayBuffer != NULL) { 1581 FDK_FREE_MEMORY_2D(hEnc->ppBitstreamDelayBuffer); 1582 } 1583 if (hEnc->sscBuf.pSsc != NULL) { 1584 FDK_FREE_MEMORY_1D(hEnc->sscBuf.pSsc); 1585 } 1586 FDK_FREE_MEMORY_1D(*phMp4SpaceEnc); 1587 } 1588 } 1589 1590 return error; 1591 } 1592 1593 /*----------------------------------------------------------------------------- 1594 functionname: mp4SpaceEnc_InitDelayCompensation() 1595 description: initialzes delay compensation 1596 returns: noError on success, an apropriate error code else 1597 -----------------------------------------------------------------------------*/ 1598 static FDK_SACENC_ERROR mp4SpaceEnc_InitDelayCompensation( 1599 HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc, const INT coreCoderDelay) { 1600 FDK_SACENC_ERROR error = SACENC_OK; 1601 1602 /* Sanity Check */ 1603 if (hMp4SpaceEnc == NULL) { 1604 error = SACENC_INVALID_HANDLE; 1605 } else { 1606 hMp4SpaceEnc->coreCoderDelay = coreCoderDelay; 1607 1608 if (SACENC_OK != (error = fdk_sacenc_delay_Init( 1609 hMp4SpaceEnc->hDelay, hMp4SpaceEnc->nQmfBands, 1610 hMp4SpaceEnc->nFrameLength, coreCoderDelay, 1611 hMp4SpaceEnc->timeAlignment))) { 1612 goto bail; 1613 } 1614 1615 fdk_sacenc_delay_SetDmxAlign(hMp4SpaceEnc->hDelay, 0); 1616 fdk_sacenc_delay_SetTimeDomDmx( 1617 hMp4SpaceEnc->hDelay, (hMp4SpaceEnc->useTimeDomDownmix >= 1) ? 1 : 0); 1618 fdk_sacenc_delay_SetMinimizeDelay(hMp4SpaceEnc->hDelay, 1); 1619 1620 if (SACENC_OK != (error = fdk_sacenc_delay_SubCalulateBufferDelays( 1621 hMp4SpaceEnc->hDelay))) { 1622 goto bail; 1623 } 1624 1625 /* init output delay compensation */ 1626 hMp4SpaceEnc->nBitstreamDelayBuffer = 1627 fdk_sacenc_delay_GetBitstreamFrameBufferSize(hMp4SpaceEnc->hDelay); 1628 hMp4SpaceEnc->nOutputBufferDelay = 1629 fdk_sacenc_delay_GetOutputAudioBufferDelay(hMp4SpaceEnc->hDelay); 1630 hMp4SpaceEnc->nSurroundAnalysisBufferDelay = 1631 fdk_sacenc_delay_GetSurroundAnalysisBufferDelay(hMp4SpaceEnc->hDelay); 1632 hMp4SpaceEnc->nBitstreamBufferRead = 0; 1633 hMp4SpaceEnc->nBitstreamBufferWrite = 1634 hMp4SpaceEnc->nBitstreamDelayBuffer - 1; 1635 1636 if (hMp4SpaceEnc->encMode == SACENC_212) { 1637 /* mode 212 expects no bitstream delay */ 1638 if (hMp4SpaceEnc->nBitstreamBufferWrite != 1639 hMp4SpaceEnc->nBitstreamBufferRead) { 1640 error = SACENC_PARAM_ERROR; 1641 goto bail; 1642 } 1643 1644 /* mode 212 expects no output buffer delay */ 1645 if (hMp4SpaceEnc->nOutputBufferDelay != 0) { 1646 error = SACENC_PARAM_ERROR; 1647 goto bail; 1648 } 1649 } 1650 1651 /*** Input delay to obtain a net encoder delay that is a multiple 1652 of the used framelength to ensure synchronization of framing 1653 in artistic down-mix with the corresponding spatial data. ***/ 1654 hMp4SpaceEnc->nDiscardOutFrames = 1655 fdk_sacenc_delay_GetDiscardOutFrames(hMp4SpaceEnc->hDelay); 1656 hMp4SpaceEnc->nInputDelay = 1657 fdk_sacenc_delay_GetDmxAlignBufferDelay(hMp4SpaceEnc->hDelay); 1658 1659 /* reset independency Flag counter */ 1660 hMp4SpaceEnc->independencyCount = 0; 1661 hMp4SpaceEnc->independencyFlag = 1; 1662 1663 int i; 1664 1665 /* write some parameters to bitstream */ 1666 for (i = 0; i < hMp4SpaceEnc->nBitstreamDelayBuffer - 1; i++) { 1667 SPATIALFRAME *pFrameData = NULL; 1668 1669 if (NULL == (pFrameData = fdk_sacenc_getSpatialFrame( 1670 hMp4SpaceEnc->hBitstreamFormatter, READ_SPATIALFRAME))) { 1671 error = SACENC_INVALID_HANDLE; 1672 goto bail; 1673 } 1674 1675 pFrameData->bsIndependencyFlag = 1; 1676 pFrameData->framingInfo.numParamSets = 1; 1677 pFrameData->framingInfo.bsFramingType = 0; 1678 1679 fdk_sacenc_writeSpatialFrame( 1680 hMp4SpaceEnc->ppBitstreamDelayBuffer[i], MAX_MPEGS_BYTES, 1681 &hMp4SpaceEnc->pnOutputBits[i], hMp4SpaceEnc->hBitstreamFormatter); 1682 } 1683 1684 if ((hMp4SpaceEnc->nInputDelay > MAX_DELAY_INPUT) || 1685 (hMp4SpaceEnc->nOutputBufferDelay > MAX_DELAY_OUTPUT) || 1686 (hMp4SpaceEnc->nSurroundAnalysisBufferDelay > 1687 MAX_DELAY_SURROUND_ANALYSIS) || 1688 (hMp4SpaceEnc->nBitstreamDelayBuffer > MAX_BITSTREAM_DELAY)) { 1689 error = SACENC_INIT_ERROR; 1690 goto bail; 1691 } 1692 } 1693 1694 bail: 1695 1696 return error; 1697 } 1698 1699 static QUANTMODE __mapQuantMode(const MP4SPACEENC_QUANTMODE quantMode) { 1700 QUANTMODE bsQuantMode = QUANTMODE_INVALID; 1701 1702 switch (quantMode) { 1703 case SACENC_QUANTMODE_FINE: 1704 bsQuantMode = QUANTMODE_FINE; 1705 break; 1706 case SACENC_QUANTMODE_EBQ1: 1707 bsQuantMode = QUANTMODE_EBQ1; 1708 break; 1709 case SACENC_QUANTMODE_EBQ2: 1710 bsQuantMode = QUANTMODE_EBQ2; 1711 break; 1712 case SACENC_QUANTMODE_RSVD3: 1713 case SACENC_QUANTMODE_INVALID: 1714 default: 1715 bsQuantMode = QUANTMODE_INVALID; 1716 } /* switch hEnc->quantMode */ 1717 1718 return bsQuantMode; 1719 } 1720 1721 static FDK_SACENC_ERROR FillSpatialSpecificConfig( 1722 const HANDLE_MP4SPACE_ENCODER hEnc, SPATIALSPECIFICCONFIG *const hSsc) { 1723 FDK_SACENC_ERROR error = SACENC_OK; 1724 1725 if ((NULL == hEnc) || (NULL == hSsc)) { 1726 error = SACENC_INVALID_HANDLE; 1727 } else { 1728 SPACE_TREE_DESCRIPTION spaceTreeDescription; 1729 int i; 1730 1731 /* Get tree description */ 1732 if (SACENC_OK != (error = fdk_sacenc_spaceTree_GetDescription( 1733 hEnc->hSpaceTree, &spaceTreeDescription))) { 1734 goto bail; 1735 } 1736 1737 /* Fill SSC */ 1738 FDKmemclear(hSsc, sizeof(SPATIALSPECIFICCONFIG)); /* reset */ 1739 1740 hSsc->numBands = hEnc->spaceTreeSetup.nParamBands; /* for bsFreqRes */ 1741 1742 /* Fill tree configuration */ 1743 hSsc->treeDescription.numOttBoxes = spaceTreeDescription.nOttBoxes; 1744 hSsc->treeDescription.numInChan = spaceTreeDescription.nInChannels; 1745 hSsc->treeDescription.numOutChan = spaceTreeDescription.nOutChannels; 1746 1747 for (i = 0; i < SACENC_MAX_NUM_BOXES; i++) { 1748 hSsc->ottConfig[i].bsOttBands = hSsc->numBands; 1749 } 1750 1751 switch (hEnc->encMode) { 1752 case SACENC_212: 1753 hSsc->bsTreeConfig = TREE_212; 1754 break; 1755 case SACENC_INVALID_MODE: 1756 default: 1757 error = SACENC_INVALID_CONFIG; 1758 goto bail; 1759 } 1760 1761 hSsc->bsSamplingFrequency = 1762 hEnc->nSampleRate; /* for bsSamplingFrequencyIndex */ 1763 hSsc->bsFrameLength = hEnc->nFrameTimeSlots - 1; 1764 1765 /* map decorr type */ 1766 if (DECORR_INVALID == 1767 (hSsc->bsDecorrConfig = mp4SpaceEnc_GetDecorrConfig(hEnc->encMode))) { 1768 error = SACENC_INVALID_CONFIG; 1769 goto bail; 1770 } 1771 1772 /* map quantMode */ 1773 if (QUANTMODE_INVALID == 1774 (hSsc->bsQuantMode = __mapQuantMode(hEnc->quantMode))) { 1775 error = SACENC_INVALID_CONFIG; 1776 goto bail; 1777 } 1778 1779 /* Configure Gains*/ 1780 hSsc->bsFixedGainDMX = fdk_sacenc_staticGain_GetDmxGain(hEnc->hStaticGain); 1781 hSsc->bsEnvQuantMode = 0; 1782 1783 } /* valid handle */ 1784 1785 bail: 1786 return error; 1787 } 1788 1789 static FDK_SACENC_ERROR mp4SpaceEnc_FillSpaceTreeSetup( 1790 const HANDLE_MP4SPACE_ENCODER hEnc, 1791 SPACE_TREE_SETUP *const hSpaceTreeSetup) { 1792 FDK_SACENC_ERROR error = SACENC_OK; 1793 1794 /* Sanity Check */ 1795 if (NULL == hEnc || NULL == hSpaceTreeSetup) { 1796 error = SACENC_INVALID_HANDLE; 1797 } else { 1798 QUANTMODE tmpQuantmode = QUANTMODE_INVALID; 1799 1800 /* map quantMode */ 1801 if (QUANTMODE_INVALID == (tmpQuantmode = __mapQuantMode(hEnc->quantMode))) { 1802 error = SACENC_INVALID_CONFIG; 1803 goto bail; 1804 } 1805 1806 hSpaceTreeSetup->nParamBands = hEnc->nParamBands; 1807 hSpaceTreeSetup->bUseCoarseQuantTtoCld = hEnc->useCoarseQuantCld; 1808 hSpaceTreeSetup->bUseCoarseQuantTtoIcc = hEnc->useCoarseQuantIcc; 1809 hSpaceTreeSetup->quantMode = tmpQuantmode; 1810 hSpaceTreeSetup->nHybridBandsMax = hEnc->nHybridBands; 1811 1812 switch (hEnc->encMode) { 1813 case SACENC_212: 1814 hSpaceTreeSetup->mode = SPACETREE_212; 1815 hSpaceTreeSetup->nChannelsInMax = 2; 1816 break; 1817 case SACENC_INVALID_MODE: 1818 default: 1819 error = SACENC_INVALID_CONFIG; 1820 goto bail; 1821 } /* switch hEnc->encMode */ 1822 1823 } /* valid handle */ 1824 bail: 1825 return error; 1826 } 1827 1828 FDK_SACENC_ERROR FDK_sacenc_getInfo(const HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc, 1829 MP4SPACEENC_INFO *const pInfo) { 1830 FDK_SACENC_ERROR error = SACENC_OK; 1831 1832 if ((NULL == hMp4SpaceEnc) || (NULL == pInfo)) { 1833 error = SACENC_INVALID_HANDLE; 1834 } else { 1835 pInfo->nSampleRate = hMp4SpaceEnc->nSampleRate; 1836 pInfo->nSamplesFrame = hMp4SpaceEnc->nFrameLength; 1837 pInfo->nTotalInputChannels = hMp4SpaceEnc->nInputChannels; 1838 pInfo->nDmxDelay = fdk_sacenc_delay_GetInfoDmxDelay(hMp4SpaceEnc->hDelay); 1839 pInfo->nCodecDelay = 1840 fdk_sacenc_delay_GetInfoCodecDelay(hMp4SpaceEnc->hDelay); 1841 pInfo->nDecoderDelay = 1842 fdk_sacenc_delay_GetInfoDecoderDelay(hMp4SpaceEnc->hDelay); 1843 pInfo->nPayloadDelay = 1844 fdk_sacenc_delay_GetBitstreamFrameBufferSize(hMp4SpaceEnc->hDelay) - 1; 1845 pInfo->nDiscardOutFrames = hMp4SpaceEnc->nDiscardOutFrames; 1846 1847 pInfo->pSscBuf = &hMp4SpaceEnc->sscBuf; 1848 } 1849 return error; 1850 } 1851 1852 FDK_SACENC_ERROR FDK_sacenc_setParam(HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc, 1853 const SPACEENC_PARAM param, 1854 const UINT value) { 1855 FDK_SACENC_ERROR error = SACENC_OK; 1856 1857 /* check encoder handle */ 1858 if (hMp4SpaceEnc == NULL) { 1859 error = SACENC_INVALID_HANDLE; 1860 goto bail; 1861 } 1862 1863 /* apply param value */ 1864 switch (param) { 1865 case SACENC_LOWDELAY: 1866 if (!((value == 0) || (value == 1) || (value == 2))) { 1867 error = SACENC_INVALID_CONFIG; 1868 break; 1869 } 1870 hMp4SpaceEnc->user.bLdMode = value; 1871 break; 1872 1873 case SACENC_ENC_MODE: 1874 switch ((MP4SPACEENC_MODE)value) { 1875 case SACENC_212: 1876 hMp4SpaceEnc->user.encMode = (MP4SPACEENC_MODE)value; 1877 break; 1878 default: 1879 error = SACENC_INVALID_CONFIG; 1880 } 1881 break; 1882 1883 case SACENC_SAMPLERATE: 1884 if (((int)value < 0) || 1885 ((int)value > hMp4SpaceEnc->setup.maxSamplingrate)) { 1886 error = SACENC_INVALID_CONFIG; 1887 break; 1888 } 1889 hMp4SpaceEnc->user.sampleRate = value; 1890 break; 1891 1892 case SACENC_FRAME_TIME_SLOTS: 1893 if (((int)value < 0) || 1894 ((int)value > hMp4SpaceEnc->setup.maxFrameTimeSlots)) { 1895 error = SACENC_INVALID_CONFIG; 1896 break; 1897 } 1898 hMp4SpaceEnc->user.frameTimeSlots = value; 1899 break; 1900 1901 case SACENC_PARAM_BANDS: 1902 switch ((MP4SPACEENC_BANDS_CONFIG)value) { 1903 case SACENC_BANDS_4: 1904 case SACENC_BANDS_5: 1905 case SACENC_BANDS_7: 1906 case SACENC_BANDS_9: 1907 case SACENC_BANDS_12: 1908 case SACENC_BANDS_15: 1909 case SACENC_BANDS_23: 1910 hMp4SpaceEnc->user.nParamBands = (MP4SPACEENC_BANDS_CONFIG)value; 1911 break; 1912 default: 1913 error = SACENC_INVALID_CONFIG; 1914 } 1915 break; 1916 1917 case SACENC_TIME_DOM_DMX: 1918 if (!((value == 0) || (value == 2))) { 1919 error = SACENC_INVALID_CONFIG; 1920 break; 1921 } 1922 hMp4SpaceEnc->user.bTimeDomainDmx = value; 1923 break; 1924 1925 case SACENC_DMX_GAIN: 1926 if (!((value == 0) || (value == 1) || (value == 2) || (value == 3) || 1927 (value == 4) || (value == 5) || (value == 6) || (value == 7))) { 1928 error = SACENC_INVALID_CONFIG; 1929 break; 1930 } 1931 error = fdk_sacenc_staticGain_SetDmxGain(hMp4SpaceEnc->hStaticGainConfig, 1932 (MP4SPACEENC_DMX_GAIN)value); 1933 break; 1934 1935 case SACENC_COARSE_QUANT: 1936 if (!((value == 0) || (value == 1))) { 1937 error = SACENC_INVALID_CONFIG; 1938 break; 1939 } 1940 hMp4SpaceEnc->user.bUseCoarseQuant = value; 1941 break; 1942 1943 case SACENC_QUANT_MODE: 1944 switch ((MP4SPACEENC_QUANTMODE)value) { 1945 case SACENC_QUANTMODE_FINE: 1946 case SACENC_QUANTMODE_EBQ1: 1947 case SACENC_QUANTMODE_EBQ2: 1948 hMp4SpaceEnc->user.quantMode = (MP4SPACEENC_QUANTMODE)value; 1949 break; 1950 default: 1951 error = SACENC_INVALID_CONFIG; 1952 } 1953 break; 1954 1955 case SACENC_TIME_ALIGNMENT: 1956 if ((INT)value < -32768 || (INT)value > 32767) { 1957 error = SACENC_INVALID_CONFIG; 1958 break; 1959 } 1960 hMp4SpaceEnc->user.timeAlignment = value; 1961 break; 1962 1963 case SACENC_INDEPENDENCY_COUNT: 1964 hMp4SpaceEnc->independencyCount = value; 1965 break; 1966 1967 case SACENC_INDEPENDENCY_FACTOR: 1968 hMp4SpaceEnc->user.independencyFactor = value; 1969 break; 1970 1971 default: 1972 error = SACENC_UNSUPPORTED_PARAMETER; 1973 break; 1974 } /* switch(param) */ 1975 bail: 1976 return error; 1977 } 1978 1979 FDK_SACENC_ERROR FDK_sacenc_getLibInfo(LIB_INFO *info) { 1980 int i = 0; 1981 1982 if (info == NULL) { 1983 return SACENC_INVALID_HANDLE; 1984 } 1985 1986 FDK_toolsGetLibInfo(info); 1987 1988 /* search for next free tab */ 1989 for (i = 0; i < FDK_MODULE_LAST; i++) { 1990 if (info[i].module_id == FDK_NONE) break; 1991 } 1992 if (i == FDK_MODULE_LAST) { 1993 return SACENC_INIT_ERROR; 1994 } 1995 1996 info[i].module_id = FDK_MPSENC; 1997 info[i].build_date = SACENC_LIB_BUILD_DATE; 1998 info[i].build_time = SACENC_LIB_BUILD_TIME; 1999 info[i].title = SACENC_LIB_TITLE; 2000 info[i].version = LIB_VERSION(SACENC_LIB_VL0, SACENC_LIB_VL1, SACENC_LIB_VL2); 2001 LIB_VERSION_STRING(&info[i]); 2002 2003 /* Capability flags */ 2004 info[i].flags = 0; 2005 /* End of flags */ 2006 2007 return SACENC_OK; 2008 } 2009 2010 static DECORRCONFIG mp4SpaceEnc_GetDecorrConfig( 2011 const MP4SPACEENC_MODE encMode) { 2012 DECORRCONFIG decorrConfig = DECORR_INVALID; 2013 2014 /* set decorrConfig dependent on tree mode */ 2015 switch (encMode) { 2016 case SACENC_212: 2017 decorrConfig = DECORR_QMFSPLIT0; 2018 break; 2019 case SACENC_INVALID_MODE: 2020 default: 2021 decorrConfig = DECORR_INVALID; 2022 } 2023 return decorrConfig; 2024 } 2025 2026 static FDK_SACENC_ERROR mp4SpaceEnc_InitNumParamBands( 2027 HANDLE_MP4SPACE_ENCODER hEnc, const MP4SPACEENC_BANDS_CONFIG nParamBands) { 2028 FDK_SACENC_ERROR error = SACENC_OK; 2029 2030 /* Set/Check nParamBands */ 2031 int k = 0; 2032 const int n = sizeof(pValidBands_Ld) / sizeof(UCHAR); 2033 const UCHAR *pBands = pValidBands_Ld; 2034 2035 while (k < n && pBands[k] != (UCHAR)nParamBands) ++k; 2036 if (k == n) { 2037 hEnc->nParamBands = SACENC_BANDS_INVALID; 2038 } else { 2039 hEnc->nParamBands = nParamBands; 2040 } 2041 return error; 2042 } 2043