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-D DRC decoder library ************************** 96 97 Author(s): Bernhard Neugebauer 98 99 Description: MPEG-D DRC Decoder 100 101 *******************************************************************************/ 102 103 #include "drcDec_reader.h" 104 #include "drcDec_gainDecoder.h" 105 #include "FDK_drcDecLib.h" 106 107 #include "drcDec_selectionProcess.h" 108 #include "drcDec_tools.h" 109 110 /* Decoder library info */ 111 #define DRCDEC_LIB_VL0 2 112 #define DRCDEC_LIB_VL1 1 113 #define DRCDEC_LIB_VL2 0 114 #define DRCDEC_LIB_TITLE "MPEG-D DRC Decoder Lib" 115 #ifdef __ANDROID__ 116 #define DRCDEC_LIB_BUILD_DATE "" 117 #define DRCDEC_LIB_BUILD_TIME "" 118 #else 119 #define DRCDEC_LIB_BUILD_DATE __DATE__ 120 #define DRCDEC_LIB_BUILD_TIME __TIME__ 121 #endif 122 123 typedef enum { 124 DRC_DEC_NOT_INITIALIZED = 0, 125 DRC_DEC_INITIALIZED, 126 DRC_DEC_NEW_GAIN_PAYLOAD, 127 DRC_DEC_INTERPOLATION_PREPARED 128 } DRC_DEC_STATUS; 129 130 struct s_drc_decoder { 131 DRC_DEC_CODEC_MODE codecMode; 132 DRC_DEC_FUNCTIONAL_RANGE functionalRange; 133 DRC_DEC_STATUS status; 134 135 /* handles of submodules */ 136 HANDLE_DRC_GAIN_DECODER hGainDec; 137 HANDLE_DRC_SELECTION_PROCESS hSelectionProc; 138 int selProcInputDiff; 139 140 /* data structs */ 141 UNI_DRC_CONFIG uniDrcConfig; 142 LOUDNESS_INFO_SET loudnessInfoSet; 143 UNI_DRC_GAIN uniDrcGain; 144 145 SEL_PROC_OUTPUT selProcOutput; 146 } DRC_DECODER; 147 148 static int isResetNeeded(HANDLE_DRC_DECODER hDrcDec, 149 const SEL_PROC_OUTPUT oldSelProcOutput) { 150 int i, resetNeeded = 0; 151 152 if (hDrcDec->selProcOutput.numSelectedDrcSets != 153 oldSelProcOutput.numSelectedDrcSets) { 154 resetNeeded = 1; 155 } else { 156 for (i = 0; i < hDrcDec->selProcOutput.numSelectedDrcSets; i++) { 157 if (hDrcDec->selProcOutput.selectedDrcSetIds[i] != 158 oldSelProcOutput.selectedDrcSetIds[i]) 159 resetNeeded = 1; 160 if (hDrcDec->selProcOutput.selectedDownmixIds[i] != 161 oldSelProcOutput.selectedDownmixIds[i]) 162 resetNeeded = 1; 163 } 164 } 165 166 if (hDrcDec->selProcOutput.boost != oldSelProcOutput.boost) resetNeeded = 1; 167 if (hDrcDec->selProcOutput.compress != oldSelProcOutput.compress) 168 resetNeeded = 1; 169 170 /* Note: Changes in downmix matrix are not caught, as they don't affect the 171 * DRC gain decoder */ 172 173 return resetNeeded; 174 } 175 176 static DRC_DEC_ERROR startSelectionProcess(HANDLE_DRC_DECODER hDrcDec) { 177 DRC_ERROR dErr = DE_OK; 178 DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR; 179 int uniDrcConfigHasChanged = 0; 180 SEL_PROC_OUTPUT oldSelProcOutput = hDrcDec->selProcOutput; 181 182 if (!hDrcDec->status) return DRC_DEC_NOT_READY; 183 184 if (hDrcDec->functionalRange & DRC_DEC_SELECTION) { 185 uniDrcConfigHasChanged = hDrcDec->uniDrcConfig.diff; 186 if (hDrcDec->uniDrcConfig.diff || hDrcDec->loudnessInfoSet.diff || 187 hDrcDec->selProcInputDiff) { 188 /* in case of an error, signal that selection process was not successful 189 */ 190 hDrcDec->selProcOutput.numSelectedDrcSets = 0; 191 192 sErr = drcDec_SelectionProcess_Process( 193 hDrcDec->hSelectionProc, &(hDrcDec->uniDrcConfig), 194 &(hDrcDec->loudnessInfoSet), &(hDrcDec->selProcOutput)); 195 if (sErr) return DRC_DEC_OK; 196 197 hDrcDec->selProcInputDiff = 0; 198 hDrcDec->uniDrcConfig.diff = 0; 199 hDrcDec->loudnessInfoSet.diff = 0; 200 } 201 } 202 203 if (hDrcDec->functionalRange & DRC_DEC_GAIN) { 204 if (isResetNeeded(hDrcDec, oldSelProcOutput) || uniDrcConfigHasChanged) { 205 dErr = 206 drcDec_GainDecoder_Config(hDrcDec->hGainDec, &(hDrcDec->uniDrcConfig), 207 hDrcDec->selProcOutput.numSelectedDrcSets, 208 hDrcDec->selProcOutput.selectedDrcSetIds, 209 hDrcDec->selProcOutput.selectedDownmixIds); 210 if (dErr) return DRC_DEC_OK; 211 } 212 } 213 return DRC_DEC_OK; 214 } 215 216 DRC_DEC_ERROR 217 FDK_drcDec_Open(HANDLE_DRC_DECODER* phDrcDec, 218 const DRC_DEC_FUNCTIONAL_RANGE functionalRange) { 219 DRC_ERROR dErr = DE_OK; 220 DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR; 221 HANDLE_DRC_DECODER hDrcDec; 222 223 *phDrcDec = (HANDLE_DRC_DECODER)FDKcalloc(1, sizeof(DRC_DECODER)); 224 if (!*phDrcDec) return DRC_DEC_OUT_OF_MEMORY; 225 hDrcDec = *phDrcDec; 226 227 hDrcDec->functionalRange = functionalRange; 228 229 hDrcDec->status = DRC_DEC_NOT_INITIALIZED; 230 hDrcDec->codecMode = DRC_DEC_CODEC_MODE_UNDEFINED; 231 232 if (hDrcDec->functionalRange & DRC_DEC_SELECTION) { 233 sErr = drcDec_SelectionProcess_Create(&(hDrcDec->hSelectionProc)); 234 if (sErr) return DRC_DEC_OUT_OF_MEMORY; 235 sErr = drcDec_SelectionProcess_Init(hDrcDec->hSelectionProc); 236 if (sErr) return DRC_DEC_NOT_OK; 237 hDrcDec->selProcInputDiff = 1; 238 } 239 240 if (hDrcDec->functionalRange & DRC_DEC_GAIN) { 241 dErr = drcDec_GainDecoder_Open(&(hDrcDec->hGainDec)); 242 if (dErr) return DRC_DEC_OUT_OF_MEMORY; 243 } 244 245 return DRC_DEC_OK; 246 } 247 248 DRC_DEC_ERROR 249 FDK_drcDec_SetCodecMode(HANDLE_DRC_DECODER hDrcDec, 250 const DRC_DEC_CODEC_MODE codecMode) { 251 DRC_ERROR dErr = DE_OK; 252 DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR; 253 254 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED; 255 256 if (hDrcDec->codecMode == 257 DRC_DEC_CODEC_MODE_UNDEFINED) { /* Set codec mode, if it is set for the 258 first time */ 259 hDrcDec->codecMode = codecMode; 260 261 if (hDrcDec->functionalRange & DRC_DEC_SELECTION) { 262 sErr = drcDec_SelectionProcess_SetCodecMode( 263 hDrcDec->hSelectionProc, (SEL_PROC_CODEC_MODE)codecMode); 264 if (sErr) return DRC_DEC_NOT_OK; 265 hDrcDec->selProcInputDiff = 1; 266 } 267 268 if (hDrcDec->functionalRange & DRC_DEC_GAIN) { 269 DELAY_MODE delayMode; 270 int timeDomainSupported; 271 SUBBAND_DOMAIN_MODE subbandDomainSupported; 272 273 switch (hDrcDec->codecMode) { 274 case DRC_DEC_MPEG_4_AAC: 275 case DRC_DEC_MPEG_D_USAC: 276 case DRC_DEC_MPEG_H_3DA: 277 default: 278 delayMode = DM_REGULAR_DELAY; 279 } 280 281 switch (hDrcDec->codecMode) { 282 case DRC_DEC_MPEG_4_AAC: 283 case DRC_DEC_MPEG_D_USAC: 284 timeDomainSupported = 1; 285 subbandDomainSupported = SDM_OFF; 286 break; 287 case DRC_DEC_MPEG_H_3DA: 288 timeDomainSupported = 1; 289 subbandDomainSupported = SDM_STFT256; 290 break; 291 292 case DRC_DEC_TEST_TIME_DOMAIN: 293 timeDomainSupported = 1; 294 subbandDomainSupported = SDM_OFF; 295 break; 296 case DRC_DEC_TEST_QMF_DOMAIN: 297 timeDomainSupported = 0; 298 subbandDomainSupported = SDM_QMF64; 299 break; 300 case DRC_DEC_TEST_STFT_DOMAIN: 301 timeDomainSupported = 0; 302 subbandDomainSupported = SDM_STFT256; 303 break; 304 305 default: 306 timeDomainSupported = 0; 307 subbandDomainSupported = SDM_OFF; 308 } 309 310 dErr = drcDec_GainDecoder_SetCodecDependentParameters( 311 hDrcDec->hGainDec, delayMode, timeDomainSupported, 312 subbandDomainSupported); 313 if (dErr) return DRC_DEC_NOT_OK; 314 } 315 } 316 317 /* Don't allow changing codecMode if it has already been set. */ 318 if (hDrcDec->codecMode != codecMode) return DRC_DEC_NOT_OK; 319 320 return DRC_DEC_OK; 321 } 322 323 DRC_DEC_ERROR 324 FDK_drcDec_Init(HANDLE_DRC_DECODER hDrcDec, const int frameSize, 325 const int sampleRate, const int baseChannelCount) { 326 DRC_ERROR dErr = DE_OK; 327 DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR; 328 329 if (hDrcDec == NULL || frameSize == 0 || sampleRate == 0 || 330 baseChannelCount == 0) 331 return DRC_DEC_OK; /* return without doing anything */ 332 333 if (hDrcDec->functionalRange & DRC_DEC_SELECTION) { 334 sErr = drcDec_SelectionProcess_SetParam( 335 hDrcDec->hSelectionProc, SEL_PROC_BASE_CHANNEL_COUNT, 336 (FIXP_DBL)baseChannelCount, &(hDrcDec->selProcInputDiff)); 337 if (sErr) return DRC_DEC_NOT_OK; 338 sErr = drcDec_SelectionProcess_SetParam( 339 hDrcDec->hSelectionProc, SEL_PROC_SAMPLE_RATE, (FIXP_DBL)sampleRate, 340 &(hDrcDec->selProcInputDiff)); 341 if (sErr) return DRC_DEC_NOT_OK; 342 } 343 344 if (hDrcDec->functionalRange & DRC_DEC_GAIN) { 345 dErr = drcDec_GainDecoder_Init(hDrcDec->hGainDec, frameSize, sampleRate); 346 if (dErr) return DRC_DEC_NOT_OK; 347 } 348 349 hDrcDec->status = DRC_DEC_INITIALIZED; 350 351 startSelectionProcess(hDrcDec); 352 353 return DRC_DEC_OK; 354 } 355 356 DRC_DEC_ERROR 357 FDK_drcDec_Close(HANDLE_DRC_DECODER* phDrcDec) { 358 HANDLE_DRC_DECODER hDrcDec; 359 360 if (phDrcDec == NULL) { 361 return DRC_DEC_OK; 362 } 363 364 hDrcDec = *phDrcDec; 365 366 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED; 367 368 if (hDrcDec->functionalRange & DRC_DEC_GAIN) { 369 drcDec_GainDecoder_Close(&(hDrcDec->hGainDec)); 370 } 371 372 if (hDrcDec->functionalRange & DRC_DEC_SELECTION) { 373 drcDec_SelectionProcess_Delete(&(hDrcDec->hSelectionProc)); 374 } 375 376 FDKfree(*phDrcDec); 377 *phDrcDec = NULL; 378 379 return DRC_DEC_OK; 380 } 381 382 DRC_DEC_ERROR 383 FDK_drcDec_SetParam(HANDLE_DRC_DECODER hDrcDec, 384 const DRC_DEC_USERPARAM requestType, 385 const FIXP_DBL requestValue) { 386 DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR; 387 388 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED; 389 390 if (hDrcDec->functionalRange == DRC_DEC_GAIN) 391 return DRC_DEC_NOT_OK; /* not supported for DRC_DEC_GAIN. All parameters are 392 handed over to selection process lib. */ 393 394 switch (requestType) { 395 case DRC_DEC_BOOST: 396 sErr = drcDec_SelectionProcess_SetParam(hDrcDec->hSelectionProc, 397 SEL_PROC_BOOST, requestValue, 398 &(hDrcDec->selProcInputDiff)); 399 if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE; 400 break; 401 case DRC_DEC_COMPRESS: 402 sErr = drcDec_SelectionProcess_SetParam(hDrcDec->hSelectionProc, 403 SEL_PROC_COMPRESS, requestValue, 404 &(hDrcDec->selProcInputDiff)); 405 if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE; 406 break; 407 case DRC_DEC_LOUDNESS_NORMALIZATION_ON: 408 sErr = drcDec_SelectionProcess_SetParam( 409 hDrcDec->hSelectionProc, SEL_PROC_LOUDNESS_NORMALIZATION_ON, 410 requestValue, &(hDrcDec->selProcInputDiff)); 411 if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE; 412 break; 413 case DRC_DEC_TARGET_LOUDNESS: 414 sErr = drcDec_SelectionProcess_SetParam( 415 hDrcDec->hSelectionProc, SEL_PROC_TARGET_LOUDNESS, requestValue, 416 &(hDrcDec->selProcInputDiff)); 417 if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE; 418 break; 419 case DRC_DEC_EFFECT_TYPE: 420 sErr = drcDec_SelectionProcess_SetParam( 421 hDrcDec->hSelectionProc, SEL_PROC_EFFECT_TYPE, requestValue, 422 &(hDrcDec->selProcInputDiff)); 423 if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE; 424 break; 425 case DRC_DEC_DOWNMIX_ID: 426 sErr = drcDec_SelectionProcess_SetParam(hDrcDec->hSelectionProc, 427 SEL_PROC_DOWNMIX_ID, requestValue, 428 &(hDrcDec->selProcInputDiff)); 429 if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE; 430 break; 431 case DRC_DEC_TARGET_CHANNEL_COUNT_REQUESTED: 432 sErr = drcDec_SelectionProcess_SetParam( 433 hDrcDec->hSelectionProc, SEL_PROC_TARGET_CHANNEL_COUNT, requestValue, 434 &(hDrcDec->selProcInputDiff)); 435 if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE; 436 break; 437 case DRC_DEC_BASE_CHANNEL_COUNT: 438 sErr = drcDec_SelectionProcess_SetParam( 439 hDrcDec->hSelectionProc, SEL_PROC_BASE_CHANNEL_COUNT, requestValue, 440 &(hDrcDec->selProcInputDiff)); 441 if (sErr) return DRC_DEC_NOT_OK; 442 break; 443 case DRC_DEC_LOUDNESS_MEASUREMENT_METHOD: 444 sErr = drcDec_SelectionProcess_SetParam( 445 hDrcDec->hSelectionProc, SEL_PROC_LOUDNESS_MEASUREMENT_METHOD, 446 requestValue, &(hDrcDec->selProcInputDiff)); 447 if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE; 448 break; 449 default: 450 return DRC_DEC_INVALID_PARAM; 451 } 452 453 /* All parameters need a new start of the selection process */ 454 startSelectionProcess(hDrcDec); 455 456 return DRC_DEC_OK; 457 } 458 459 LONG FDK_drcDec_GetParam(HANDLE_DRC_DECODER hDrcDec, 460 const DRC_DEC_USERPARAM requestType) { 461 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED; 462 463 switch (requestType) { 464 case DRC_DEC_BOOST: 465 return (LONG)hDrcDec->selProcOutput.boost; 466 case DRC_DEC_COMPRESS: 467 return (LONG)hDrcDec->selProcOutput.compress; 468 case DRC_DEC_IS_MULTIBAND_DRC_1: 469 return (LONG)bitstreamContainsMultibandDrc(&hDrcDec->uniDrcConfig, 0); 470 case DRC_DEC_IS_MULTIBAND_DRC_2: 471 return (LONG)bitstreamContainsMultibandDrc(&hDrcDec->uniDrcConfig, 0x7F); 472 case DRC_DEC_IS_ACTIVE: { 473 /* MPEG-D DRC is considered active (and overrides MPEG-4 DRC), if 474 * uniDrc payload is present (loudnessInfoSet and/or uniDrcConfig) 475 * at least one of DRC and Loudness Control is switched on */ 476 int drcOn = drcDec_SelectionProcess_GetParam( 477 hDrcDec->hSelectionProc, SEL_PROC_DYNAMIC_RANGE_CONTROL_ON); 478 int lnOn = drcDec_SelectionProcess_GetParam( 479 hDrcDec->hSelectionProc, SEL_PROC_LOUDNESS_NORMALIZATION_ON); 480 int uniDrcPayloadPresent = 481 (hDrcDec->loudnessInfoSet.loudnessInfoCount > 0); 482 uniDrcPayloadPresent |= 483 (hDrcDec->loudnessInfoSet.loudnessInfoAlbumCount > 0); 484 uniDrcPayloadPresent |= 485 (hDrcDec->uniDrcConfig.drcInstructionsUniDrcCount > 0); 486 uniDrcPayloadPresent |= 487 (hDrcDec->uniDrcConfig.downmixInstructionsCount > 0); 488 return (LONG)(uniDrcPayloadPresent && (drcOn || lnOn)); 489 } 490 case DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED: 491 return (LONG)hDrcDec->selProcOutput.targetChannelCount; 492 default: 493 return 0; 494 } 495 } 496 497 DRC_DEC_ERROR 498 FDK_drcDec_SetInterfaceParameters(HANDLE_DRC_DECODER hDrcDec, 499 HANDLE_UNI_DRC_INTERFACE hUniDrcInterface) { 500 return DRC_DEC_UNSUPPORTED_FUNCTION; 501 } 502 503 DRC_DEC_ERROR 504 FDK_drcDec_SetSelectionProcessMpeghParameters_simple( 505 HANDLE_DRC_DECODER hDrcDec, const int groupPresetIdRequested, 506 const int numGroupIdsRequested, const int* groupIdsRequested) { 507 return DRC_DEC_UNSUPPORTED_FUNCTION; 508 } 509 510 DRC_DEC_ERROR 511 FDK_drcDec_SetDownmixInstructions(HANDLE_DRC_DECODER hDrcDec, 512 const int numDownmixId, const int* downmixId, 513 const int* targetLayout, 514 const int* targetChannelCount) { 515 return DRC_DEC_UNSUPPORTED_FUNCTION; 516 } 517 518 void FDK_drcDec_SetSelectionProcessOutput( 519 HANDLE_DRC_DECODER hDrcDec, HANDLE_SEL_PROC_OUTPUT hSelProcOutput) {} 520 521 HANDLE_SEL_PROC_OUTPUT 522 FDK_drcDec_GetSelectionProcessOutput(HANDLE_DRC_DECODER hDrcDec) { 523 if (hDrcDec == NULL) return NULL; 524 525 return &(hDrcDec->selProcOutput); 526 } 527 528 LONG /* FIXP_DBL, e = 7 */ 529 FDK_drcDec_GetGroupLoudness(HANDLE_SEL_PROC_OUTPUT hSelProcOutput, 530 const int groupID, int* groupLoudnessAvailable) { 531 return (LONG)0; 532 } 533 534 void FDK_drcDec_SetChannelGains(HANDLE_DRC_DECODER hDrcDec, 535 const int numChannels, const int frameSize, 536 FIXP_DBL* channelGainDb, FIXP_DBL* audioBuffer, 537 const int audioBufferChannelOffset) { 538 int err; 539 540 if (hDrcDec == NULL) return; 541 542 err = drcDec_GainDecoder_SetLoudnessNormalizationGainDb( 543 hDrcDec->hGainDec, hDrcDec->selProcOutput.loudnessNormalizationGainDb); 544 if (err) return; 545 546 drcDec_GainDecoder_SetChannelGains(hDrcDec->hGainDec, numChannels, frameSize, 547 channelGainDb, audioBufferChannelOffset, 548 audioBuffer); 549 } 550 551 DRC_DEC_ERROR 552 FDK_drcDec_ReadUniDrcConfig(HANDLE_DRC_DECODER hDrcDec, 553 HANDLE_FDK_BITSTREAM hBitstream) { 554 DRC_ERROR dErr = DE_OK; 555 556 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED; 557 558 if (hDrcDec->codecMode == DRC_DEC_MPEG_D_USAC) { 559 dErr = drcDec_readUniDrcConfig(hBitstream, &(hDrcDec->uniDrcConfig)); 560 } else 561 return DRC_DEC_NOT_OK; 562 563 if (dErr) { 564 /* clear config, if parsing error occured */ 565 FDKmemclear(&hDrcDec->uniDrcConfig, sizeof(hDrcDec->uniDrcConfig)); 566 hDrcDec->uniDrcConfig.diff = 1; 567 } 568 569 startSelectionProcess(hDrcDec); 570 571 return DRC_DEC_OK; 572 } 573 574 DRC_DEC_ERROR 575 FDK_drcDec_ReadDownmixInstructions_Box(HANDLE_DRC_DECODER hDrcDec, 576 HANDLE_FDK_BITSTREAM hBitstream) { 577 DRC_ERROR dErr = DE_OK; 578 579 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED; 580 581 return DRC_DEC_NOT_OK; 582 583 if (dErr) { 584 /* clear config, if parsing error occurred */ 585 FDKmemclear(&hDrcDec->uniDrcConfig.downmixInstructions, 586 sizeof(hDrcDec->uniDrcConfig.downmixInstructions)); 587 hDrcDec->uniDrcConfig.downmixInstructionsCount = 0; 588 hDrcDec->uniDrcConfig.downmixInstructionsCountV0 = 0; 589 hDrcDec->uniDrcConfig.downmixInstructionsCountV1 = 0; 590 hDrcDec->uniDrcConfig.diff = 1; 591 } 592 593 startSelectionProcess(hDrcDec); 594 595 return DRC_DEC_OK; 596 } 597 598 DRC_DEC_ERROR 599 FDK_drcDec_ReadUniDrcInstructions_Box(HANDLE_DRC_DECODER hDrcDec, 600 HANDLE_FDK_BITSTREAM hBitstream) { 601 DRC_ERROR dErr = DE_OK; 602 603 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED; 604 605 return DRC_DEC_NOT_OK; 606 607 if (dErr) { 608 /* clear config, if parsing error occurred */ 609 FDKmemclear(&hDrcDec->uniDrcConfig.drcInstructionsUniDrc, 610 sizeof(hDrcDec->uniDrcConfig.drcInstructionsUniDrc)); 611 hDrcDec->uniDrcConfig.drcInstructionsUniDrcCount = 0; 612 hDrcDec->uniDrcConfig.drcInstructionsUniDrcCountV0 = 0; 613 hDrcDec->uniDrcConfig.drcInstructionsUniDrcCountV1 = 0; 614 hDrcDec->uniDrcConfig.diff = 1; 615 } 616 617 startSelectionProcess(hDrcDec); 618 619 return DRC_DEC_OK; 620 } 621 622 DRC_DEC_ERROR 623 FDK_drcDec_ReadUniDrcCoefficients_Box(HANDLE_DRC_DECODER hDrcDec, 624 HANDLE_FDK_BITSTREAM hBitstream) { 625 DRC_ERROR dErr = DE_OK; 626 627 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED; 628 629 return DRC_DEC_NOT_OK; 630 631 if (dErr) { 632 /* clear config, if parsing error occurred */ 633 FDKmemclear(&hDrcDec->uniDrcConfig.drcCoefficientsUniDrc, 634 sizeof(hDrcDec->uniDrcConfig.drcCoefficientsUniDrc)); 635 hDrcDec->uniDrcConfig.drcCoefficientsUniDrcCount = 0; 636 hDrcDec->uniDrcConfig.drcCoefficientsUniDrcCountV0 = 0; 637 hDrcDec->uniDrcConfig.drcCoefficientsUniDrcCountV1 = 0; 638 hDrcDec->uniDrcConfig.diff = 1; 639 } 640 641 startSelectionProcess(hDrcDec); 642 643 return DRC_DEC_OK; 644 } 645 646 DRC_DEC_ERROR 647 FDK_drcDec_ReadLoudnessInfoSet(HANDLE_DRC_DECODER hDrcDec, 648 HANDLE_FDK_BITSTREAM hBitstream) { 649 DRC_ERROR dErr = DE_OK; 650 651 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED; 652 653 if (hDrcDec->codecMode == DRC_DEC_MPEG_D_USAC) { 654 dErr = drcDec_readLoudnessInfoSet(hBitstream, &(hDrcDec->loudnessInfoSet)); 655 } else 656 return DRC_DEC_NOT_OK; 657 658 if (dErr) { 659 /* clear config, if parsing error occurred */ 660 FDKmemclear(&hDrcDec->loudnessInfoSet, sizeof(hDrcDec->loudnessInfoSet)); 661 hDrcDec->loudnessInfoSet.diff = 1; 662 } 663 664 startSelectionProcess(hDrcDec); 665 666 return DRC_DEC_OK; 667 } 668 669 DRC_DEC_ERROR 670 FDK_drcDec_ReadLoudnessBox(HANDLE_DRC_DECODER hDrcDec, 671 HANDLE_FDK_BITSTREAM hBitstream) { 672 DRC_ERROR dErr = DE_OK; 673 674 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED; 675 676 return DRC_DEC_NOT_OK; 677 678 if (dErr) { 679 /* clear config, if parsing error occurred */ 680 FDKmemclear(&hDrcDec->loudnessInfoSet, sizeof(hDrcDec->loudnessInfoSet)); 681 hDrcDec->loudnessInfoSet.diff = 1; 682 } 683 684 startSelectionProcess(hDrcDec); 685 686 return DRC_DEC_OK; 687 } 688 689 DRC_DEC_ERROR 690 FDK_drcDec_ReadUniDrcGain(HANDLE_DRC_DECODER hDrcDec, 691 HANDLE_FDK_BITSTREAM hBitstream) { 692 DRC_ERROR dErr = DE_OK; 693 694 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED; 695 if (!hDrcDec->status) { 696 return DRC_DEC_OK; 697 } 698 699 dErr = drcDec_readUniDrcGain( 700 hBitstream, &(hDrcDec->uniDrcConfig), 701 drcDec_GainDecoder_GetFrameSize(hDrcDec->hGainDec), 702 drcDec_GainDecoder_GetDeltaTminDefault(hDrcDec->hGainDec), 703 &(hDrcDec->uniDrcGain)); 704 if (dErr) return DRC_DEC_NOT_OK; 705 706 hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD; 707 708 return DRC_DEC_OK; 709 } 710 711 DRC_DEC_ERROR 712 FDK_drcDec_ReadUniDrc(HANDLE_DRC_DECODER hDrcDec, 713 HANDLE_FDK_BITSTREAM hBitstream) { 714 DRC_ERROR dErr = DE_OK; 715 716 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED; 717 if (!hDrcDec->status) return DRC_DEC_NOT_READY; 718 719 dErr = drcDec_readUniDrc( 720 hBitstream, &(hDrcDec->uniDrcConfig), &(hDrcDec->loudnessInfoSet), 721 drcDec_GainDecoder_GetFrameSize(hDrcDec->hGainDec), 722 drcDec_GainDecoder_GetDeltaTminDefault(hDrcDec->hGainDec), 723 &(hDrcDec->uniDrcGain)); 724 if (dErr) return DRC_DEC_NOT_OK; 725 726 startSelectionProcess(hDrcDec); 727 728 hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD; 729 730 return DRC_DEC_OK; 731 } 732 733 DRC_DEC_ERROR 734 FDK_drcDec_Preprocess(HANDLE_DRC_DECODER hDrcDec) { 735 DRC_ERROR dErr = DE_OK; 736 737 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED; 738 if (!hDrcDec->status) return DRC_DEC_NOT_READY; 739 if (!(hDrcDec->functionalRange & DRC_DEC_GAIN)) return DRC_DEC_NOT_OK; 740 741 if (hDrcDec->status != DRC_DEC_NEW_GAIN_PAYLOAD) { 742 /* no new gain payload was read, e.g. during concalment or flushing. 743 Generate DRC gains based on the stored DRC gains of last frames */ 744 drcDec_GainDecoder_Conceal(hDrcDec->hGainDec, &(hDrcDec->uniDrcConfig), 745 &(hDrcDec->uniDrcGain)); 746 } 747 748 dErr = drcDec_GainDecoder_Preprocess( 749 hDrcDec->hGainDec, &(hDrcDec->uniDrcGain), 750 hDrcDec->selProcOutput.loudnessNormalizationGainDb, 751 hDrcDec->selProcOutput.boost, hDrcDec->selProcOutput.compress); 752 if (dErr) return DRC_DEC_NOT_OK; 753 hDrcDec->status = DRC_DEC_INTERPOLATION_PREPARED; 754 755 return DRC_DEC_OK; 756 } 757 758 DRC_DEC_ERROR 759 FDK_drcDec_ProcessTime(HANDLE_DRC_DECODER hDrcDec, const int delaySamples, 760 const DRC_DEC_LOCATION drcLocation, 761 const int channelOffset, const int drcChannelOffset, 762 const int numChannelsProcessed, FIXP_DBL* realBuffer, 763 const int timeDataChannelOffset) { 764 DRC_ERROR dErr = DE_OK; 765 766 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED; 767 if (!(hDrcDec->functionalRange & DRC_DEC_GAIN)) return DRC_DEC_NOT_OK; 768 if (hDrcDec->status != DRC_DEC_INTERPOLATION_PREPARED) 769 return DRC_DEC_NOT_READY; 770 771 dErr = drcDec_GainDecoder_ProcessTimeDomain( 772 hDrcDec->hGainDec, delaySamples, (GAIN_DEC_LOCATION)drcLocation, 773 channelOffset, drcChannelOffset, numChannelsProcessed, 774 timeDataChannelOffset, realBuffer); 775 if (dErr) return DRC_DEC_NOT_OK; 776 777 return DRC_DEC_OK; 778 } 779 780 DRC_DEC_ERROR 781 FDK_drcDec_ProcessFreq(HANDLE_DRC_DECODER hDrcDec, const int delaySamples, 782 const DRC_DEC_LOCATION drcLocation, 783 const int channelOffset, const int drcChannelOffset, 784 const int numChannelsProcessed, 785 const int processSingleTimeslot, FIXP_DBL** realBuffer, 786 FIXP_DBL** imagBuffer) { 787 DRC_ERROR dErr = DE_OK; 788 789 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED; 790 if (!(hDrcDec->functionalRange & DRC_DEC_GAIN)) return DRC_DEC_NOT_OK; 791 if (hDrcDec->status != DRC_DEC_INTERPOLATION_PREPARED) 792 return DRC_DEC_NOT_READY; 793 794 dErr = drcDec_GainDecoder_ProcessSubbandDomain( 795 hDrcDec->hGainDec, delaySamples, (GAIN_DEC_LOCATION)drcLocation, 796 channelOffset, drcChannelOffset, numChannelsProcessed, 797 processSingleTimeslot, realBuffer, imagBuffer); 798 if (dErr) return DRC_DEC_NOT_OK; 799 800 return DRC_DEC_OK; 801 } 802 803 DRC_DEC_ERROR 804 FDK_drcDec_ApplyDownmix(HANDLE_DRC_DECODER hDrcDec, int* reverseInChannelMap, 805 int* reverseOutChannelMap, FIXP_DBL* realBuffer, 806 int* pNChannels) { 807 SEL_PROC_OUTPUT* pSelProcOutput = &(hDrcDec->selProcOutput); 808 int baseChCnt = pSelProcOutput->baseChannelCount; 809 int targetChCnt = pSelProcOutput->targetChannelCount; 810 int frameSize, n, ic, oc; 811 FIXP_DBL tmp_out[8]; 812 FIXP_DBL* audioChannels[8]; 813 814 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED; 815 if (!(hDrcDec->functionalRange & DRC_DEC_GAIN)) return DRC_DEC_NOT_OK; 816 817 /* only downmix is performed here, no upmix. 818 Downmix is only performed if downmix coefficients are provided. 819 All other cases of downmix and upmix are treated by pcmDmx library. */ 820 if (pSelProcOutput->downmixMatrixPresent == 0) 821 return DRC_DEC_OK; /* no downmix */ 822 if (targetChCnt >= baseChCnt) return DRC_DEC_OK; /* downmix only */ 823 824 /* sanity checks */ 825 if (realBuffer == NULL) return DRC_DEC_NOT_OK; 826 if (reverseInChannelMap == NULL) return DRC_DEC_NOT_OK; 827 if (reverseOutChannelMap == NULL) return DRC_DEC_NOT_OK; 828 if (baseChCnt > 8) return DRC_DEC_NOT_OK; 829 if (baseChCnt != *pNChannels) return DRC_DEC_NOT_OK; 830 if (targetChCnt > 8) return DRC_DEC_NOT_OK; 831 832 frameSize = drcDec_GainDecoder_GetFrameSize(hDrcDec->hGainDec); 833 834 for (ic = 0; ic < baseChCnt; ic++) { 835 audioChannels[ic] = &(realBuffer[ic * frameSize]); 836 } 837 838 /* in-place downmix */ 839 for (n = 0; n < frameSize; n++) { 840 for (oc = 0; oc < targetChCnt; oc++) { 841 tmp_out[oc] = (FIXP_DBL)0; 842 for (ic = 0; ic < baseChCnt; ic++) { 843 tmp_out[oc] += 844 fMultDiv2(audioChannels[ic][n], 845 pSelProcOutput->downmixMatrix[reverseInChannelMap[ic]] 846 [reverseOutChannelMap[oc]]) 847 << 3; 848 } 849 } 850 for (oc = 0; oc < targetChCnt; oc++) { 851 if (oc >= baseChCnt) break; 852 audioChannels[oc][n] = tmp_out[oc]; 853 } 854 } 855 856 for (oc = targetChCnt; oc < baseChCnt; oc++) { 857 FDKmemset(audioChannels[oc], 0, frameSize * sizeof(FIXP_DBL)); 858 } 859 860 *pNChannels = targetChCnt; 861 862 return DRC_DEC_OK; 863 } 864 865 /* Get library info for this module. */ 866 DRC_DEC_ERROR 867 FDK_drcDec_GetLibInfo(LIB_INFO* info) { 868 int i; 869 870 if (info == NULL) { 871 return DRC_DEC_INVALID_PARAM; 872 } 873 874 /* Search for next free tab */ 875 for (i = 0; i < FDK_MODULE_LAST; i++) { 876 if (info[i].module_id == FDK_NONE) break; 877 } 878 if (i == FDK_MODULE_LAST) { 879 return DRC_DEC_NOT_OK; 880 } 881 882 /* Add the library info */ 883 info[i].module_id = FDK_UNIDRCDEC; 884 info[i].version = LIB_VERSION(DRCDEC_LIB_VL0, DRCDEC_LIB_VL1, DRCDEC_LIB_VL2); 885 LIB_VERSION_STRING(info + i); 886 info[i].build_date = DRCDEC_LIB_BUILD_DATE; 887 info[i].build_time = DRCDEC_LIB_BUILD_TIME; 888 info[i].title = DRCDEC_LIB_TITLE; 889 890 return DRC_DEC_OK; 891 } 892