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 /**************************** AAC decoder library ****************************** 96 97 Author(s): Josef Hoepfl 98 99 Description: joint stereo processing 100 101 *******************************************************************************/ 102 103 #include "stereo.h" 104 105 #include "aac_rom.h" 106 #include "FDK_bitstream.h" 107 #include "channelinfo.h" 108 #include "FDK_audio.h" 109 110 enum { L = 0, R = 1 }; 111 112 #include "block.h" 113 114 int CJointStereo_Read(HANDLE_FDK_BITSTREAM bs, 115 CJointStereoData *pJointStereoData, 116 const int windowGroups, 117 const int scaleFactorBandsTransmitted, 118 const int max_sfb_ste_clear, 119 CJointStereoPersistentData *pJointStereoPersistentData, 120 CCplxPredictionData *cplxPredictionData, 121 int cplxPredictionActiv, int scaleFactorBandsTotal, 122 int windowSequence, const UINT flags) { 123 int group, band; 124 125 pJointStereoData->MsMaskPresent = (UCHAR)FDKreadBits(bs, 2); 126 127 FDKmemclear(pJointStereoData->MsUsed, 128 scaleFactorBandsTransmitted * sizeof(UCHAR)); 129 130 pJointStereoData->cplx_pred_flag = 0; 131 if (cplxPredictionActiv) { 132 cplxPredictionData->pred_dir = 0; 133 cplxPredictionData->complex_coef = 0; 134 cplxPredictionData->use_prev_frame = 0; 135 cplxPredictionData->igf_pred_dir = 0; 136 } 137 138 switch (pJointStereoData->MsMaskPresent) { 139 case 0: /* no M/S */ 140 /* all flags are already cleared */ 141 break; 142 143 case 1: /* read ms_used */ 144 for (group = 0; group < windowGroups; group++) { 145 for (band = 0; band < scaleFactorBandsTransmitted; band++) { 146 pJointStereoData->MsUsed[band] |= (FDKreadBits(bs, 1) << group); 147 } 148 } 149 break; 150 151 case 2: /* full spectrum M/S */ 152 for (band = 0; band < scaleFactorBandsTransmitted; band++) { 153 pJointStereoData->MsUsed[band] = 255; /* set all flags to 1 */ 154 } 155 break; 156 157 case 3: 158 /* M/S coding is disabled, complex stereo prediction is enabled */ 159 if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) { 160 if (cplxPredictionActiv) { /* 'if (stereoConfigIndex == 0)' */ 161 162 pJointStereoData->cplx_pred_flag = 1; 163 164 /* cplx_pred_data() cp. ISO/IEC FDIS 23003-3:2011(E) Table 26 */ 165 int cplx_pred_all = 0; /* local use only */ 166 cplx_pred_all = FDKreadBits(bs, 1); 167 168 if (cplx_pred_all) { 169 for (group = 0; group < windowGroups; group++) { 170 UCHAR groupmask = ((UCHAR)1 << group); 171 for (band = 0; band < scaleFactorBandsTransmitted; band++) { 172 pJointStereoData->MsUsed[band] |= groupmask; 173 } 174 } 175 } else { 176 for (group = 0; group < windowGroups; group++) { 177 for (band = 0; band < scaleFactorBandsTransmitted; 178 band += SFB_PER_PRED_BAND) { 179 pJointStereoData->MsUsed[band] |= (FDKreadBits(bs, 1) << group); 180 if ((band + 1) < scaleFactorBandsTotal) { 181 pJointStereoData->MsUsed[band + 1] |= 182 (pJointStereoData->MsUsed[band] & ((UCHAR)1 << group)); 183 } 184 } 185 } 186 } 187 } else { 188 return -1; 189 } 190 } 191 break; 192 } 193 194 if (cplxPredictionActiv) { 195 /* If all sfb are MS-ed then no complex prediction */ 196 if (pJointStereoData->MsMaskPresent == 3) { 197 if (pJointStereoData->cplx_pred_flag) { 198 int delta_code_time = 0; 199 200 /* set pointer to Huffman codebooks */ 201 const CodeBookDescription *hcb = &AACcodeBookDescriptionTable[BOOKSCL]; 202 /* set predictors to zero in case of a transition from long to short 203 * window sequences and vice versa */ 204 if (((windowSequence == BLOCK_SHORT) && 205 (pJointStereoPersistentData->winSeqPrev != BLOCK_SHORT)) || 206 ((pJointStereoPersistentData->winSeqPrev == BLOCK_SHORT) && 207 (windowSequence != BLOCK_SHORT))) { 208 FDKmemclear(pJointStereoPersistentData->alpha_q_re_prev, 209 JointStereoMaximumGroups * JointStereoMaximumBands * 210 sizeof(SHORT)); 211 FDKmemclear(pJointStereoPersistentData->alpha_q_im_prev, 212 JointStereoMaximumGroups * JointStereoMaximumBands * 213 sizeof(SHORT)); 214 } 215 { 216 FDKmemclear(cplxPredictionData->alpha_q_re, 217 JointStereoMaximumGroups * JointStereoMaximumBands * 218 sizeof(SHORT)); 219 FDKmemclear(cplxPredictionData->alpha_q_im, 220 JointStereoMaximumGroups * JointStereoMaximumBands * 221 sizeof(SHORT)); 222 } 223 224 /* 0 = mid->side prediction, 1 = side->mid prediction */ 225 cplxPredictionData->pred_dir = FDKreadBits(bs, 1); 226 cplxPredictionData->complex_coef = FDKreadBits(bs, 1); 227 228 if (cplxPredictionData->complex_coef) { 229 if (flags & AC_INDEP) { 230 cplxPredictionData->use_prev_frame = 0; 231 } else { 232 cplxPredictionData->use_prev_frame = FDKreadBits(bs, 1); 233 } 234 } 235 236 if (flags & AC_INDEP) { 237 delta_code_time = 0; 238 } else { 239 delta_code_time = FDKreadBits(bs, 1); 240 } 241 242 { 243 int last_alpha_q_re = 0, last_alpha_q_im = 0; 244 245 for (group = 0; group < windowGroups; group++) { 246 for (band = 0; band < scaleFactorBandsTransmitted; 247 band += SFB_PER_PRED_BAND) { 248 if (delta_code_time == 1) { 249 if (group > 0) { 250 last_alpha_q_re = 251 cplxPredictionData->alpha_q_re[group - 1][band]; 252 last_alpha_q_im = 253 cplxPredictionData->alpha_q_im[group - 1][band]; 254 } else if ((windowSequence == BLOCK_SHORT) && 255 (pJointStereoPersistentData->winSeqPrev == 256 BLOCK_SHORT)) { 257 /* Included for error-robustness */ 258 if (pJointStereoPersistentData->winGroupsPrev == 0) return -1; 259 260 last_alpha_q_re = 261 pJointStereoPersistentData->alpha_q_re_prev 262 [pJointStereoPersistentData->winGroupsPrev - 1][band]; 263 last_alpha_q_im = 264 pJointStereoPersistentData->alpha_q_im_prev 265 [pJointStereoPersistentData->winGroupsPrev - 1][band]; 266 } else { 267 last_alpha_q_re = 268 pJointStereoPersistentData->alpha_q_re_prev[group][band]; 269 last_alpha_q_im = 270 pJointStereoPersistentData->alpha_q_im_prev[group][band]; 271 } 272 273 } else { 274 if (band > 0) { 275 last_alpha_q_re = 276 cplxPredictionData->alpha_q_re[group][band - 1]; 277 last_alpha_q_im = 278 cplxPredictionData->alpha_q_im[group][band - 1]; 279 } else { 280 last_alpha_q_re = 0; 281 last_alpha_q_im = 0; 282 } 283 284 } /* if (delta_code_time == 1) */ 285 286 if (pJointStereoData->MsUsed[band] & ((UCHAR)1 << group)) { 287 int dpcm_alpha_re, dpcm_alpha_im; 288 289 dpcm_alpha_re = CBlock_DecodeHuffmanWord(bs, hcb); 290 dpcm_alpha_re -= 60; 291 dpcm_alpha_re *= -1; 292 293 cplxPredictionData->alpha_q_re[group][band] = 294 dpcm_alpha_re + last_alpha_q_re; 295 296 if (cplxPredictionData->complex_coef) { 297 dpcm_alpha_im = CBlock_DecodeHuffmanWord(bs, hcb); 298 dpcm_alpha_im -= 60; 299 dpcm_alpha_im *= -1; 300 301 cplxPredictionData->alpha_q_im[group][band] = 302 dpcm_alpha_im + last_alpha_q_im; 303 } else { 304 cplxPredictionData->alpha_q_im[group][band] = 0; 305 } 306 307 } else { 308 cplxPredictionData->alpha_q_re[group][band] = 0; 309 cplxPredictionData->alpha_q_im[group][band] = 0; 310 } /* if (pJointStereoData->MsUsed[band] & ((UCHAR)1 << group)) */ 311 312 if ((band + 1) < 313 scaleFactorBandsTransmitted) { /* <= this should be the 314 correct way (cp. 315 ISO_IEC_FDIS_23003-0(E) */ 316 /* 7.7.2.3.2 Decoding of prediction coefficients) */ 317 cplxPredictionData->alpha_q_re[group][band + 1] = 318 cplxPredictionData->alpha_q_re[group][band]; 319 cplxPredictionData->alpha_q_im[group][band + 1] = 320 cplxPredictionData->alpha_q_im[group][band]; 321 } /* if ((band+1)<scaleFactorBandsTotal) */ 322 323 pJointStereoPersistentData->alpha_q_re_prev[group][band] = 324 cplxPredictionData->alpha_q_re[group][band]; 325 pJointStereoPersistentData->alpha_q_im_prev[group][band] = 326 cplxPredictionData->alpha_q_im[group][band]; 327 } 328 329 for (band = scaleFactorBandsTransmitted; band < max_sfb_ste_clear; 330 band++) { 331 cplxPredictionData->alpha_q_re[group][band] = 0; 332 cplxPredictionData->alpha_q_im[group][band] = 0; 333 pJointStereoPersistentData->alpha_q_re_prev[group][band] = 0; 334 pJointStereoPersistentData->alpha_q_im_prev[group][band] = 0; 335 } 336 } 337 } 338 } 339 } else { 340 for (group = 0; group < windowGroups; group++) { 341 for (band = 0; band < max_sfb_ste_clear; band++) { 342 pJointStereoPersistentData->alpha_q_re_prev[group][band] = 0; 343 pJointStereoPersistentData->alpha_q_im_prev[group][band] = 0; 344 } 345 } 346 } 347 348 pJointStereoPersistentData->winGroupsPrev = windowGroups; 349 } 350 351 return 0; 352 } 353 354 static void CJointStereo_filterAndAdd( 355 FIXP_DBL *in, int len, int windowLen, const FIXP_FILT *coeff, FIXP_DBL *out, 356 UCHAR isCurrent /* output values with even index get a 357 positve addon (=1) or a negative addon 358 (=0) */ 359 ) { 360 int i, j; 361 362 int indices_1[] = {2, 1, 0, 1, 2, 3}; 363 int indices_2[] = {1, 0, 0, 2, 3, 4}; 364 int indices_3[] = {0, 0, 1, 3, 4, 5}; 365 366 int subtr_1[] = {6, 5, 4, 2, 1, 1}; 367 int subtr_2[] = {5, 4, 3, 1, 1, 2}; 368 int subtr_3[] = {4, 3, 2, 1, 2, 3}; 369 370 if (isCurrent == 1) { 371 /* exploit the symmetry of the table: coeff[6] = - coeff[0], 372 coeff[5] = - coeff[1], 373 coeff[4] = - coeff[2], 374 coeff[3] = 0 375 */ 376 377 for (i = 0; i < 3; i++) { 378 out[0] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_1[i]]) >> SR_FNA_OUT; 379 out[0] += 380 (FIXP_DBL)fMultDiv2(coeff[i], in[indices_1[5 - i]]) >> SR_FNA_OUT; 381 } 382 383 for (i = 0; i < 3; i++) { 384 out[1] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_2[i]]) >> SR_FNA_OUT; 385 out[1] += 386 (FIXP_DBL)fMultDiv2(coeff[i], in[indices_2[5 - i]]) >> SR_FNA_OUT; 387 } 388 389 for (i = 0; i < 3; i++) { 390 out[2] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_3[i]]) >> SR_FNA_OUT; 391 out[2] += 392 (FIXP_DBL)fMultDiv2(coeff[i], in[indices_3[5 - i]]) >> SR_FNA_OUT; 393 } 394 395 for (j = 3; j < (len - 3); j++) { 396 for (i = 0; i < 3; i++) { 397 out[j] -= (FIXP_DBL)fMultDiv2(coeff[i], in[j - 3 + i]) >> SR_FNA_OUT; 398 out[j] += (FIXP_DBL)fMultDiv2(coeff[i], in[j + 3 - i]) >> SR_FNA_OUT; 399 } 400 } 401 402 for (i = 0; i < 3; i++) { 403 out[len - 3] -= 404 (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_1[i]]) >> SR_FNA_OUT; 405 out[len - 3] += 406 (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_1[5 - i]]) >> SR_FNA_OUT; 407 } 408 409 for (i = 0; i < 3; i++) { 410 out[len - 2] -= 411 (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_2[i]]) >> SR_FNA_OUT; 412 out[len - 2] += 413 (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_2[5 - i]]) >> SR_FNA_OUT; 414 } 415 416 for (i = 0; i < 3; i++) { 417 out[len - 1] -= 418 (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_3[i]]) >> SR_FNA_OUT; 419 out[len - 1] += 420 (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_3[5 - i]]) >> SR_FNA_OUT; 421 } 422 423 } else { 424 /* exploit the symmetry of the table: coeff[6] = coeff[0], 425 coeff[5] = coeff[1], 426 coeff[4] = coeff[2] 427 */ 428 429 for (i = 0; i < 3; i++) { 430 out[0] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_1[i]] >> SR_FNA_OUT); 431 out[0] -= 432 (FIXP_DBL)fMultDiv2(coeff[i], in[indices_1[5 - i]] >> SR_FNA_OUT); 433 } 434 out[0] -= (FIXP_DBL)fMultDiv2(coeff[3], in[0] >> SR_FNA_OUT); 435 436 for (i = 0; i < 3; i++) { 437 out[1] += (FIXP_DBL)fMultDiv2(coeff[i], in[indices_2[i]] >> SR_FNA_OUT); 438 out[1] += 439 (FIXP_DBL)fMultDiv2(coeff[i], in[indices_2[5 - i]] >> SR_FNA_OUT); 440 } 441 out[1] += (FIXP_DBL)fMultDiv2(coeff[3], in[1] >> SR_FNA_OUT); 442 443 for (i = 0; i < 3; i++) { 444 out[2] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_3[i]] >> SR_FNA_OUT); 445 out[2] -= 446 (FIXP_DBL)fMultDiv2(coeff[i], in[indices_3[5 - i]] >> SR_FNA_OUT); 447 } 448 out[2] -= (FIXP_DBL)fMultDiv2(coeff[3], in[2] >> SR_FNA_OUT); 449 450 for (j = 3; j < (len - 4); j++) { 451 for (i = 0; i < 3; i++) { 452 out[j] += (FIXP_DBL)fMultDiv2(coeff[i], in[j - 3 + i] >> SR_FNA_OUT); 453 out[j] += (FIXP_DBL)fMultDiv2(coeff[i], in[j + 3 - i] >> SR_FNA_OUT); 454 } 455 out[j] += (FIXP_DBL)fMultDiv2(coeff[3], in[j] >> SR_FNA_OUT); 456 457 j++; 458 459 for (i = 0; i < 3; i++) { 460 out[j] -= (FIXP_DBL)fMultDiv2(coeff[i], in[j - 3 + i] >> SR_FNA_OUT); 461 out[j] -= (FIXP_DBL)fMultDiv2(coeff[i], in[j + 3 - i] >> SR_FNA_OUT); 462 } 463 out[j] -= (FIXP_DBL)fMultDiv2(coeff[3], in[j] >> SR_FNA_OUT); 464 } 465 466 for (i = 0; i < 3; i++) { 467 out[len - 3] += 468 (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_1[i]] >> SR_FNA_OUT); 469 out[len - 3] += 470 (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_1[5 - i]] >> SR_FNA_OUT); 471 } 472 out[len - 3] += (FIXP_DBL)fMultDiv2(coeff[3], in[len - 3] >> SR_FNA_OUT); 473 474 for (i = 0; i < 3; i++) { 475 out[len - 2] -= 476 (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_2[i]] >> SR_FNA_OUT); 477 out[len - 2] -= 478 (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_2[5 - i]] >> SR_FNA_OUT); 479 } 480 out[len - 2] -= (FIXP_DBL)fMultDiv2(coeff[3], in[len - 2] >> SR_FNA_OUT); 481 482 for (i = 0; i < 3; i++) { 483 out[len - 1] += 484 (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_3[i]] >> SR_FNA_OUT); 485 out[len - 1] += 486 (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_3[5 - i]] >> SR_FNA_OUT); 487 } 488 out[len - 1] += (FIXP_DBL)fMultDiv2(coeff[3], in[len - 1] >> SR_FNA_OUT); 489 } 490 } 491 492 static inline void CJointStereo_GenerateMSOutput(FIXP_DBL *pSpecLCurrBand, 493 FIXP_DBL *pSpecRCurrBand, 494 UINT leftScale, 495 UINT rightScale, 496 UINT nSfbBands) { 497 unsigned int i; 498 499 FIXP_DBL leftCoefficient0; 500 FIXP_DBL leftCoefficient1; 501 FIXP_DBL leftCoefficient2; 502 FIXP_DBL leftCoefficient3; 503 504 FIXP_DBL rightCoefficient0; 505 FIXP_DBL rightCoefficient1; 506 FIXP_DBL rightCoefficient2; 507 FIXP_DBL rightCoefficient3; 508 509 for (i = nSfbBands; i > 0; i -= 4) { 510 leftCoefficient0 = pSpecLCurrBand[i - 4]; 511 leftCoefficient1 = pSpecLCurrBand[i - 3]; 512 leftCoefficient2 = pSpecLCurrBand[i - 2]; 513 leftCoefficient3 = pSpecLCurrBand[i - 1]; 514 515 rightCoefficient0 = pSpecRCurrBand[i - 4]; 516 rightCoefficient1 = pSpecRCurrBand[i - 3]; 517 rightCoefficient2 = pSpecRCurrBand[i - 2]; 518 rightCoefficient3 = pSpecRCurrBand[i - 1]; 519 520 /* MS output generation */ 521 leftCoefficient0 >>= leftScale; 522 leftCoefficient1 >>= leftScale; 523 leftCoefficient2 >>= leftScale; 524 leftCoefficient3 >>= leftScale; 525 526 rightCoefficient0 >>= rightScale; 527 rightCoefficient1 >>= rightScale; 528 rightCoefficient2 >>= rightScale; 529 rightCoefficient3 >>= rightScale; 530 531 pSpecLCurrBand[i - 4] = leftCoefficient0 + rightCoefficient0; 532 pSpecLCurrBand[i - 3] = leftCoefficient1 + rightCoefficient1; 533 pSpecLCurrBand[i - 2] = leftCoefficient2 + rightCoefficient2; 534 pSpecLCurrBand[i - 1] = leftCoefficient3 + rightCoefficient3; 535 536 pSpecRCurrBand[i - 4] = leftCoefficient0 - rightCoefficient0; 537 pSpecRCurrBand[i - 3] = leftCoefficient1 - rightCoefficient1; 538 pSpecRCurrBand[i - 2] = leftCoefficient2 - rightCoefficient2; 539 pSpecRCurrBand[i - 1] = leftCoefficient3 - rightCoefficient3; 540 } 541 } 542 543 void CJointStereo_ApplyMS( 544 CAacDecoderChannelInfo *pAacDecoderChannelInfo[2], 545 CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[2], 546 FIXP_DBL *spectrumL, FIXP_DBL *spectrumR, SHORT *SFBleftScale, 547 SHORT *SFBrightScale, SHORT *specScaleL, SHORT *specScaleR, 548 const SHORT *pScaleFactorBandOffsets, const UCHAR *pWindowGroupLength, 549 const int windowGroups, const int max_sfb_ste_outside, 550 const int scaleFactorBandsTransmittedL, 551 const int scaleFactorBandsTransmittedR, FIXP_DBL *store_dmx_re_prev, 552 SHORT *store_dmx_re_prev_e, const int mainband_flag) { 553 int window, group, band; 554 UCHAR groupMask; 555 CJointStereoData *pJointStereoData = 556 &pAacDecoderChannelInfo[L]->pComData->jointStereoData; 557 CCplxPredictionData *cplxPredictionData = 558 pAacDecoderChannelInfo[L]->pComStaticData->cplxPredictionData; 559 560 int max_sfb_ste = 561 fMax(scaleFactorBandsTransmittedL, scaleFactorBandsTransmittedR); 562 int min_sfb_ste = 563 fMin(scaleFactorBandsTransmittedL, scaleFactorBandsTransmittedR); 564 int scaleFactorBandsTransmitted = min_sfb_ste; 565 566 if (pJointStereoData->cplx_pred_flag) { 567 int windowLen, groupwin, frameMaxScale; 568 CJointStereoPersistentData *pJointStereoPersistentData = 569 &pAacDecoderStaticChannelInfo[L] 570 ->pCpeStaticData->jointStereoPersistentData; 571 FIXP_DBL *const staticSpectralCoeffsL = 572 pAacDecoderStaticChannelInfo[L] 573 ->pCpeStaticData->jointStereoPersistentData.spectralCoeffs[L]; 574 FIXP_DBL *const staticSpectralCoeffsR = 575 pAacDecoderStaticChannelInfo[L] 576 ->pCpeStaticData->jointStereoPersistentData.spectralCoeffs[R]; 577 SHORT *const staticSpecScaleL = 578 pAacDecoderStaticChannelInfo[L] 579 ->pCpeStaticData->jointStereoPersistentData.specScale[L]; 580 SHORT *const staticSpecScaleR = 581 pAacDecoderStaticChannelInfo[L] 582 ->pCpeStaticData->jointStereoPersistentData.specScale[R]; 583 584 FIXP_DBL *dmx_re = 585 pAacDecoderStaticChannelInfo[L] 586 ->pCpeStaticData->jointStereoPersistentData.scratchBuffer; 587 FIXP_DBL *dmx_re_prev = 588 pAacDecoderStaticChannelInfo[L] 589 ->pCpeStaticData->jointStereoPersistentData.scratchBuffer + 590 1024; 591 592 /* When MS is applied over the main band this value gets computed. Otherwise 593 * (for the tiles) it uses the assigned value */ 594 SHORT dmx_re_prev_e = *store_dmx_re_prev_e; 595 596 const FIXP_FILT *pCoeff; 597 const FIXP_FILT *pCoeffPrev; 598 int coeffPointerOffset; 599 600 int previousShape = (int)pJointStereoPersistentData->winShapePrev; 601 int currentShape = (int)pAacDecoderChannelInfo[L]->icsInfo.WindowShape; 602 603 /* complex stereo prediction */ 604 605 /* 0. preparations */ 606 607 /* 0.0. get scratch buffer for downmix MDST */ 608 C_AALLOC_SCRATCH_START(dmx_im, FIXP_DBL, 1024); 609 610 /* 0.1. window lengths */ 611 612 /* get length of short window for current configuration */ 613 windowLen = 614 pAacDecoderChannelInfo[L]->granuleLength; /* framelength 768 => 96, 615 framelength 1024 => 128 */ 616 617 /* if this is no short-block set length for long-block */ 618 if (pAacDecoderChannelInfo[L]->icsInfo.WindowSequence != BLOCK_SHORT) { 619 windowLen *= 8; 620 } 621 622 /* 0.2. set pointer to filter-coefficients for MDST excitation including 623 * previous frame portions */ 624 /* cp. ISO/IEC FDIS 23003-3:2011(E) table 125 */ 625 626 /* set pointer to default-position */ 627 pCoeffPrev = mdst_filt_coef_prev[previousShape]; 628 629 if (cplxPredictionData->complex_coef == 1) { 630 switch (pAacDecoderChannelInfo[L] 631 ->icsInfo.WindowSequence) { /* current window sequence */ 632 case BLOCK_SHORT: 633 case BLOCK_LONG: 634 pCoeffPrev = mdst_filt_coef_prev[previousShape]; 635 break; 636 637 case BLOCK_START: 638 if ((pJointStereoPersistentData->winSeqPrev == BLOCK_SHORT) || 639 (pJointStereoPersistentData->winSeqPrev == BLOCK_START)) { 640 /* a stop-start-sequence can only follow on an eight-short-sequence 641 * or a start-sequence */ 642 pCoeffPrev = mdst_filt_coef_prev[2 + previousShape]; 643 } else { 644 pCoeffPrev = mdst_filt_coef_prev[previousShape]; 645 } 646 break; 647 648 case BLOCK_STOP: 649 pCoeffPrev = mdst_filt_coef_prev[2 + previousShape]; 650 break; 651 652 default: 653 pCoeffPrev = mdst_filt_coef_prev[previousShape]; 654 break; 655 } 656 } 657 658 /* 0.3. set pointer to filter-coefficients for MDST excitation */ 659 660 /* define offset of pointer to filter-coefficients for MDST exitation 661 * employing only the current frame */ 662 if ((previousShape == SHAPE_SINE) && (currentShape == SHAPE_SINE)) { 663 coeffPointerOffset = 0; 664 } else if ((previousShape == SHAPE_SINE) && (currentShape == SHAPE_KBD)) { 665 coeffPointerOffset = 2; 666 } else if ((previousShape == SHAPE_KBD) && (currentShape == SHAPE_KBD)) { 667 coeffPointerOffset = 1; 668 } else /* if ( (previousShape == SHAPE_KBD) && (currentShape == SHAPE_SINE) 669 ) */ 670 { 671 coeffPointerOffset = 3; 672 } 673 674 /* set pointer to filter-coefficient table cp. ISO/IEC FDIS 23003-3:2011(E) 675 * table 124 */ 676 switch (pAacDecoderChannelInfo[L] 677 ->icsInfo.WindowSequence) { /* current window sequence */ 678 case BLOCK_SHORT: 679 case BLOCK_LONG: 680 pCoeff = mdst_filt_coef_curr[coeffPointerOffset]; 681 break; 682 683 case BLOCK_START: 684 if ((pJointStereoPersistentData->winSeqPrev == BLOCK_SHORT) || 685 (pJointStereoPersistentData->winSeqPrev == BLOCK_START)) { 686 /* a stop-start-sequence can only follow on an eight-short-sequence or 687 * a start-sequence */ 688 pCoeff = mdst_filt_coef_curr[12 + coeffPointerOffset]; 689 } else { 690 pCoeff = mdst_filt_coef_curr[4 + coeffPointerOffset]; 691 } 692 break; 693 694 case BLOCK_STOP: 695 pCoeff = mdst_filt_coef_curr[8 + coeffPointerOffset]; 696 break; 697 698 default: 699 pCoeff = mdst_filt_coef_curr[coeffPointerOffset]; 700 } 701 702 /* 0.4. find maximum common (l/r) band-scaling-factor for whole sequence 703 * (all windows) */ 704 frameMaxScale = 0; 705 for (window = 0, group = 0; group < windowGroups; group++) { 706 for (groupwin = 0; groupwin < pWindowGroupLength[group]; 707 groupwin++, window++) { 708 SHORT *leftScale = &SFBleftScale[window * 16]; 709 SHORT *rightScale = &SFBrightScale[window * 16]; 710 int windowMaxScale = 0; 711 712 /* find maximum scaling factor of all bands in this window */ 713 for (band = 0; band < min_sfb_ste; band++) { 714 int lScale = leftScale[band]; 715 int rScale = rightScale[band]; 716 int commonScale = ((lScale > rScale) ? lScale : rScale); 717 windowMaxScale = 718 (windowMaxScale < commonScale) ? commonScale : windowMaxScale; 719 } 720 if (scaleFactorBandsTransmittedL > 721 min_sfb_ste) { /* i.e. scaleFactorBandsTransmittedL == max_sfb_ste 722 */ 723 for (; band < max_sfb_ste; band++) { 724 int lScale = leftScale[band]; 725 windowMaxScale = 726 (windowMaxScale < lScale) ? lScale : windowMaxScale; 727 } 728 } else { 729 if (scaleFactorBandsTransmittedR > 730 min_sfb_ste) { /* i.e. scaleFactorBandsTransmittedR == max_sfb_ste 731 */ 732 for (; band < max_sfb_ste; band++) { 733 int rScale = rightScale[band]; 734 windowMaxScale = 735 (windowMaxScale < rScale) ? rScale : windowMaxScale; 736 } 737 } 738 } 739 740 /* find maximum common SF of all windows */ 741 frameMaxScale = 742 (frameMaxScale < windowMaxScale) ? windowMaxScale : frameMaxScale; 743 } 744 } 745 746 /* add some headroom for overflow protection during filter and add operation 747 */ 748 frameMaxScale += 2; 749 750 /* process on window-basis (i.e. iterate over all groups and corresponding 751 * windows) */ 752 for (window = 0, group = 0; group < windowGroups; group++) { 753 groupMask = 1 << group; 754 755 for (groupwin = 0; groupwin < pWindowGroupLength[group]; 756 groupwin++, window++) { 757 /* initialize the MDST with zeros */ 758 FDKmemclear(&dmx_im[windowLen * window], windowLen * sizeof(FIXP_DBL)); 759 760 /* 1. calculate the previous downmix MDCT. We do this once just for the 761 * Main band. */ 762 if (cplxPredictionData->complex_coef == 1) { 763 if ((cplxPredictionData->use_prev_frame == 1) && (mainband_flag)) { 764 /* if this is a long-block or the first window of a short-block 765 calculate the downmix MDCT of the previous frame. 766 use_prev_frame is assumed not to change during a frame! 767 */ 768 769 /* first determine shiftfactors to scale left and right channel */ 770 if ((pAacDecoderChannelInfo[L]->icsInfo.WindowSequence != 771 BLOCK_SHORT) || 772 (window == 0)) { 773 int index_offset = 0; 774 int srLeftChan = 0; 775 int srRightChan = 0; 776 if (pAacDecoderChannelInfo[L]->icsInfo.WindowSequence == 777 BLOCK_SHORT) { 778 /* use the last window of the previous frame for MDCT 779 * calculation if this is a short-block. */ 780 index_offset = windowLen * 7; 781 if (staticSpecScaleL[7] > staticSpecScaleR[7]) { 782 srRightChan = staticSpecScaleL[7] - staticSpecScaleR[7]; 783 dmx_re_prev_e = staticSpecScaleL[7]; 784 } else { 785 srLeftChan = staticSpecScaleR[7] - staticSpecScaleL[7]; 786 dmx_re_prev_e = staticSpecScaleR[7]; 787 } 788 } else { 789 if (staticSpecScaleL[0] > staticSpecScaleR[0]) { 790 srRightChan = staticSpecScaleL[0] - staticSpecScaleR[0]; 791 dmx_re_prev_e = staticSpecScaleL[0]; 792 } else { 793 srLeftChan = staticSpecScaleR[0] - staticSpecScaleL[0]; 794 dmx_re_prev_e = staticSpecScaleR[0]; 795 } 796 } 797 798 /* now scale channels and determine downmix MDCT of previous frame 799 */ 800 if (pAacDecoderStaticChannelInfo[L] 801 ->pCpeStaticData->jointStereoPersistentData 802 .clearSpectralCoeffs == 1) { 803 FDKmemclear(dmx_re_prev, windowLen * sizeof(FIXP_DBL)); 804 dmx_re_prev_e = 0; 805 } else { 806 if (cplxPredictionData->pred_dir == 0) { 807 for (int i = 0; i < windowLen; i++) { 808 dmx_re_prev[i] = 809 ((staticSpectralCoeffsL[index_offset + i] >> 810 srLeftChan) + 811 (staticSpectralCoeffsR[index_offset + i] >> 812 srRightChan)) >> 813 1; 814 } 815 } else { 816 for (int i = 0; i < windowLen; i++) { 817 dmx_re_prev[i] = 818 ((staticSpectralCoeffsL[index_offset + i] >> 819 srLeftChan) - 820 (staticSpectralCoeffsR[index_offset + i] >> 821 srRightChan)) >> 822 1; 823 } 824 } 825 } 826 827 /* In case that we use INF we have to preserve the state of the 828 "dmx_re_prev" (original or computed). This is necessary because we 829 have to apply MS over the separate IGF tiles. */ 830 FDKmemcpy(store_dmx_re_prev, &dmx_re_prev[0], 831 windowLen * sizeof(FIXP_DBL)); 832 833 /* Particular exponent of the computed/original "dmx_re_prev" must 834 * be kept for the tile MS calculations if necessary.*/ 835 *store_dmx_re_prev_e = dmx_re_prev_e; 836 837 } /* if ( (pAacDecoderChannelInfo[L]->icsInfo.WindowSequence != 838 BLOCK_SHORT) || (window == 0) ) */ 839 840 } /* if ( pJointStereoData->use_prev_frame == 1 ) */ 841 842 } /* if ( pJointStereoData->complex_coef == 1 ) */ 843 844 /* 2. calculate downmix MDCT of current frame */ 845 846 /* set pointer to scale-factor-bands of current window */ 847 SHORT *leftScale = &SFBleftScale[window * 16]; 848 SHORT *rightScale = &SFBrightScale[window * 16]; 849 850 specScaleL[window] = specScaleR[window] = frameMaxScale; 851 852 /* adapt scaling-factors to previous frame */ 853 if (cplxPredictionData->use_prev_frame == 1) { 854 if (window == 0) { 855 if (dmx_re_prev_e < frameMaxScale) { 856 if (mainband_flag == 0) { 857 scaleValues(dmx_re_prev, store_dmx_re_prev, windowLen, 858 -(frameMaxScale - dmx_re_prev_e)); 859 } else { 860 for (int i = 0; i < windowLen; i++) { 861 dmx_re_prev[i] >>= (frameMaxScale - dmx_re_prev_e); 862 } 863 } 864 } else { 865 if (mainband_flag == 0) { 866 FDKmemcpy(dmx_re_prev, store_dmx_re_prev, 867 windowLen * sizeof(FIXP_DBL)); 868 } 869 specScaleL[0] = dmx_re_prev_e; 870 specScaleR[0] = dmx_re_prev_e; 871 } 872 } else { /* window != 0 */ 873 FDK_ASSERT(pAacDecoderChannelInfo[L]->icsInfo.WindowSequence == 874 BLOCK_SHORT); 875 if (specScaleL[window - 1] < frameMaxScale) { 876 for (int i = 0; i < windowLen; i++) { 877 dmx_re[windowLen * (window - 1) + i] >>= 878 (frameMaxScale - specScaleL[window - 1]); 879 } 880 } else { 881 specScaleL[window] = specScaleL[window - 1]; 882 specScaleR[window] = specScaleR[window - 1]; 883 } 884 } 885 } /* if ( pJointStereoData->use_prev_frame == 1 ) */ 886 887 /* scaling factors of both channels ought to be equal now */ 888 FDK_ASSERT(specScaleL[window] == specScaleR[window]); 889 890 /* rescale signal and calculate downmix MDCT */ 891 for (band = 0; band < max_sfb_ste; band++) { 892 /* first adapt scaling of current band to scaling of current window => 893 * shift signal right */ 894 int lScale = leftScale[band]; 895 int rScale = rightScale[band]; 896 897 lScale = fMin(DFRACT_BITS - 1, specScaleL[window] - lScale); 898 rScale = fMin(DFRACT_BITS - 1, 899 specScaleL[window] - rScale); /* L or R doesn't 900 matter, 901 specScales are 902 equal at this 903 point */ 904 905 /* Write back to sfb scale to cover the case when max_sfb_ste < 906 * max_sfb */ 907 leftScale[band] = rightScale[band] = specScaleL[window]; 908 909 for (int i = pScaleFactorBandOffsets[band]; 910 i < pScaleFactorBandOffsets[band + 1]; i++) { 911 spectrumL[windowLen * window + i] >>= lScale; 912 spectrumR[windowLen * window + i] >>= rScale; 913 } 914 915 /* now calculate downmix MDCT */ 916 if (pJointStereoData->MsUsed[band] & groupMask) { 917 for (int i = pScaleFactorBandOffsets[band]; 918 i < pScaleFactorBandOffsets[band + 1]; i++) { 919 dmx_re[windowLen * window + i] = 920 spectrumL[windowLen * window + i]; 921 } 922 } else { 923 if (cplxPredictionData->pred_dir == 0) { 924 for (int i = pScaleFactorBandOffsets[band]; 925 i < pScaleFactorBandOffsets[band + 1]; i++) { 926 dmx_re[windowLen * window + i] = 927 (spectrumL[windowLen * window + i] + 928 spectrumR[windowLen * window + i]) >> 929 1; 930 } 931 } else { 932 for (int i = pScaleFactorBandOffsets[band]; 933 i < pScaleFactorBandOffsets[band + 1]; i++) { 934 dmx_re[windowLen * window + i] = 935 (spectrumL[windowLen * window + i] - 936 spectrumR[windowLen * window + i]) >> 937 1; 938 } 939 } 940 } 941 942 } /* for ( band=0; band<max_sfb_ste; band++ ) */ 943 /* Clean until the end */ 944 for (int i = pScaleFactorBandOffsets[max_sfb_ste_outside]; 945 i < windowLen; i++) { 946 dmx_re[windowLen * window + i] = (FIXP_DBL)0; 947 } 948 949 /* 3. calculate MDST-portion corresponding to the current frame. */ 950 if (cplxPredictionData->complex_coef == 1) { 951 { 952 /* 3.1 move pointer in filter-coefficient table in case of short 953 * window sequence */ 954 /* (other coefficients are utilized for the last 7 short 955 * windows) */ 956 if ((pAacDecoderChannelInfo[L]->icsInfo.WindowSequence == 957 BLOCK_SHORT) && 958 (window != 0)) { 959 pCoeff = mdst_filt_coef_curr[currentShape]; 960 pCoeffPrev = mdst_filt_coef_prev[currentShape]; 961 } 962 963 /* The length of the filter processing must be extended because of 964 * filter boundary problems */ 965 int extended_band = fMin( 966 pScaleFactorBandOffsets[max_sfb_ste_outside] + 7, windowLen); 967 968 /* 3.2. estimate downmix MDST from current frame downmix MDCT */ 969 if ((pAacDecoderChannelInfo[L]->icsInfo.WindowSequence == 970 BLOCK_SHORT) && 971 (window != 0)) { 972 CJointStereo_filterAndAdd(&dmx_re[windowLen * window], 973 extended_band, windowLen, pCoeff, 974 &dmx_im[windowLen * window], 1); 975 976 CJointStereo_filterAndAdd(&dmx_re[windowLen * (window - 1)], 977 extended_band, windowLen, pCoeffPrev, 978 &dmx_im[windowLen * window], 0); 979 } else { 980 CJointStereo_filterAndAdd(dmx_re, extended_band, windowLen, 981 pCoeff, dmx_im, 1); 982 983 if (cplxPredictionData->use_prev_frame == 1) { 984 CJointStereo_filterAndAdd(dmx_re_prev, extended_band, windowLen, 985 pCoeffPrev, 986 &dmx_im[windowLen * window], 0); 987 } 988 } 989 990 } /* if(pAacDecoderChannelInfo[L]->transform_splitting_active) */ 991 } /* if ( pJointStereoData->complex_coef == 1 ) */ 992 993 /* 4. upmix process */ 994 INT pred_dir = cplxPredictionData->pred_dir ? -1 : 1; 995 /* 0.1 in Q-3.34 */ 996 const FIXP_DBL pointOne = 0x66666666; /* 0.8 */ 997 /* Shift value for the downmix */ 998 const INT shift_dmx = SF_FNA_COEFFS + 1; 999 1000 for (band = 0; band < max_sfb_ste_outside; band++) { 1001 if (pJointStereoData->MsUsed[band] & groupMask) { 1002 FIXP_SGL tempRe = 1003 (FIXP_SGL)cplxPredictionData->alpha_q_re[group][band]; 1004 FIXP_SGL tempIm = 1005 (FIXP_SGL)cplxPredictionData->alpha_q_im[group][band]; 1006 1007 /* Find the minimum common headroom for alpha_re and alpha_im */ 1008 int alpha_re_headroom = CountLeadingBits((INT)tempRe) - 16; 1009 if (tempRe == (FIXP_SGL)0) alpha_re_headroom = 15; 1010 int alpha_im_headroom = CountLeadingBits((INT)tempIm) - 16; 1011 if (tempIm == (FIXP_SGL)0) alpha_im_headroom = 15; 1012 int val = fMin(alpha_re_headroom, alpha_im_headroom); 1013 1014 /* Multiply alpha by 0.1 with maximum precision */ 1015 FDK_ASSERT(val >= 0); 1016 FIXP_DBL alpha_re_tmp = fMult((FIXP_SGL)(tempRe << val), pointOne); 1017 FIXP_DBL alpha_im_tmp = fMult((FIXP_SGL)(tempIm << val), pointOne); 1018 1019 /* Calculate alpha exponent */ 1020 /* (Q-3.34 * Q15.0) shifted left by "val" */ 1021 int alpha_re_exp = -3 + 15 - val; 1022 1023 int help3_shift = alpha_re_exp + 1; 1024 1025 FIXP_DBL *p2CoeffL = &( 1026 spectrumL[windowLen * window + pScaleFactorBandOffsets[band]]); 1027 FIXP_DBL *p2CoeffR = &( 1028 spectrumR[windowLen * window + pScaleFactorBandOffsets[band]]); 1029 FIXP_DBL *p2dmxIm = 1030 &(dmx_im[windowLen * window + pScaleFactorBandOffsets[band]]); 1031 FIXP_DBL *p2dmxRe = 1032 &(dmx_re[windowLen * window + pScaleFactorBandOffsets[band]]); 1033 1034 for (int i = pScaleFactorBandOffsets[band]; 1035 i < pScaleFactorBandOffsets[band + 1]; i++) { 1036 /* Calculating helper term: 1037 side = specR[i] - alpha_re[i] * dmx_re[i] - alpha_im[i] * 1038 dmx_im[i]; 1039 1040 Here "dmx_re" may be the same as "specL" or alternatively keep 1041 the downmix. "dmx_re" and "specL" are two different pointers 1042 pointing to separate arrays, which may or may not contain the 1043 same data (with different scaling). 1044 */ 1045 1046 /* help1: alpha_re[i] * dmx_re[i] */ 1047 FIXP_DBL help1 = fMultDiv2(alpha_re_tmp, *p2dmxRe++); 1048 1049 /* tmp: dmx_im[i] */ 1050 FIXP_DBL tmp = (*p2dmxIm++) << shift_dmx; 1051 1052 /* help2: alpha_im[i] * dmx_im[i] */ 1053 FIXP_DBL help2 = fMultDiv2(alpha_im_tmp, tmp); 1054 1055 /* help3: alpha_re[i] * dmx_re[i] + alpha_im[i] * dmx_im[i] */ 1056 FIXP_DBL help3 = help1 + help2; 1057 1058 /* side (= help4) = specR[i] - (dmx_re[i] * specL[i] + alpha_im[i] 1059 * * dmx_im[i]) */ 1060 FIXP_DBL help4 = *p2CoeffR - scaleValue(help3, help3_shift); 1061 1062 /* We calculate the left and right output by using the helper 1063 * function */ 1064 /* specR[i] = -/+ (specL[i] - side); */ 1065 *p2CoeffR = 1066 (FIXP_DBL)((LONG)(*p2CoeffL - help4) * (LONG)pred_dir); 1067 p2CoeffR++; 1068 1069 /* specL[i] = specL[i] + side; */ 1070 *p2CoeffL = *p2CoeffL + help4; 1071 p2CoeffL++; 1072 } 1073 } 1074 1075 } /* for ( band=0; band < max_sfb_ste; band++ ) */ 1076 } /* for ( groupwin=0; groupwin<pWindowGroupLength[group]; groupwin++, 1077 window++ ) */ 1078 1079 } /* for ( window = 0, group = 0; group < windowGroups; group++ ) */ 1080 1081 /* free scratch buffer */ 1082 C_AALLOC_SCRATCH_END(dmx_im, FIXP_DBL, 1024); 1083 1084 } else { 1085 /* MS stereo */ 1086 1087 for (window = 0, group = 0; group < windowGroups; group++) { 1088 groupMask = 1 << group; 1089 1090 for (int groupwin = 0; groupwin < pWindowGroupLength[group]; 1091 groupwin++, window++) { 1092 FIXP_DBL *leftSpectrum, *rightSpectrum; 1093 SHORT *leftScale = &SFBleftScale[window * 16]; 1094 SHORT *rightScale = &SFBrightScale[window * 16]; 1095 1096 leftSpectrum = 1097 SPEC(spectrumL, window, pAacDecoderChannelInfo[L]->granuleLength); 1098 rightSpectrum = 1099 SPEC(spectrumR, window, pAacDecoderChannelInfo[R]->granuleLength); 1100 1101 for (band = 0; band < max_sfb_ste_outside; band++) { 1102 if (pJointStereoData->MsUsed[band] & groupMask) { 1103 int lScale = leftScale[band]; 1104 int rScale = rightScale[band]; 1105 int commonScale = lScale > rScale ? lScale : rScale; 1106 unsigned int offsetCurrBand, offsetNextBand; 1107 1108 /* ISO/IEC 14496-3 Chapter 4.6.8.1.1 : 1109 M/S joint channel coding can only be used if common_window is 1. 1110 */ 1111 FDK_ASSERT(GetWindowSequence(&pAacDecoderChannelInfo[L]->icsInfo) == 1112 GetWindowSequence(&pAacDecoderChannelInfo[R]->icsInfo)); 1113 FDK_ASSERT(GetWindowShape(&pAacDecoderChannelInfo[L]->icsInfo) == 1114 GetWindowShape(&pAacDecoderChannelInfo[R]->icsInfo)); 1115 1116 commonScale++; 1117 leftScale[band] = commonScale; 1118 rightScale[band] = commonScale; 1119 1120 lScale = fMin(DFRACT_BITS - 1, commonScale - lScale); 1121 rScale = fMin(DFRACT_BITS - 1, commonScale - rScale); 1122 1123 FDK_ASSERT(lScale >= 0 && rScale >= 0); 1124 1125 offsetCurrBand = pScaleFactorBandOffsets[band]; 1126 offsetNextBand = pScaleFactorBandOffsets[band + 1]; 1127 1128 CJointStereo_GenerateMSOutput(&(leftSpectrum[offsetCurrBand]), 1129 &(rightSpectrum[offsetCurrBand]), 1130 lScale, rScale, 1131 offsetNextBand - offsetCurrBand); 1132 } 1133 } 1134 if (scaleFactorBandsTransmittedL > scaleFactorBandsTransmitted) { 1135 for (; band < scaleFactorBandsTransmittedL; band++) { 1136 if (pJointStereoData->MsUsed[band] & groupMask) { 1137 rightScale[band] = leftScale[band]; 1138 1139 for (int index = pScaleFactorBandOffsets[band]; 1140 index < pScaleFactorBandOffsets[band + 1]; index++) { 1141 FIXP_DBL leftCoefficient = leftSpectrum[index]; 1142 /* FIXP_DBL rightCoefficient = (FIXP_DBL)0; */ 1143 rightSpectrum[index] = leftCoefficient; 1144 } 1145 } 1146 } 1147 } else if (scaleFactorBandsTransmittedR > scaleFactorBandsTransmitted) { 1148 for (; band < scaleFactorBandsTransmittedR; band++) { 1149 if (pJointStereoData->MsUsed[band] & groupMask) { 1150 leftScale[band] = rightScale[band]; 1151 1152 for (int index = pScaleFactorBandOffsets[band]; 1153 index < pScaleFactorBandOffsets[band + 1]; index++) { 1154 /* FIXP_DBL leftCoefficient = (FIXP_DBL)0; */ 1155 FIXP_DBL rightCoefficient = rightSpectrum[index]; 1156 1157 leftSpectrum[index] = rightCoefficient; 1158 rightSpectrum[index] = -rightCoefficient; 1159 } 1160 } 1161 } 1162 } 1163 } 1164 } 1165 1166 /* Reset MsUsed flags if no explicit signalling was transmitted. Necessary 1167 for intensity coding. PNS correlation signalling was mapped before 1168 calling CJointStereo_ApplyMS(). */ 1169 if (pJointStereoData->MsMaskPresent == 2) { 1170 FDKmemclear(pJointStereoData->MsUsed, 1171 JointStereoMaximumBands * sizeof(UCHAR)); 1172 } 1173 } 1174 } 1175 1176 void CJointStereo_ApplyIS(CAacDecoderChannelInfo *pAacDecoderChannelInfo[2], 1177 const SHORT *pScaleFactorBandOffsets, 1178 const UCHAR *pWindowGroupLength, 1179 const int windowGroups, 1180 const int scaleFactorBandsTransmitted) { 1181 CJointStereoData *pJointStereoData = 1182 &pAacDecoderChannelInfo[L]->pComData->jointStereoData; 1183 1184 for (int window = 0, group = 0; group < windowGroups; group++) { 1185 UCHAR *CodeBook; 1186 SHORT *ScaleFactor; 1187 UCHAR groupMask = 1 << group; 1188 1189 CodeBook = &pAacDecoderChannelInfo[R]->pDynData->aCodeBook[group * 16]; 1190 ScaleFactor = 1191 &pAacDecoderChannelInfo[R]->pDynData->aScaleFactor[group * 16]; 1192 1193 for (int groupwin = 0; groupwin < pWindowGroupLength[group]; 1194 groupwin++, window++) { 1195 FIXP_DBL *leftSpectrum, *rightSpectrum; 1196 SHORT *leftScale = 1197 &pAacDecoderChannelInfo[L]->pDynData->aSfbScale[window * 16]; 1198 SHORT *rightScale = 1199 &pAacDecoderChannelInfo[R]->pDynData->aSfbScale[window * 16]; 1200 int band; 1201 1202 leftSpectrum = SPEC(pAacDecoderChannelInfo[L]->pSpectralCoefficient, 1203 window, pAacDecoderChannelInfo[L]->granuleLength); 1204 rightSpectrum = SPEC(pAacDecoderChannelInfo[R]->pSpectralCoefficient, 1205 window, pAacDecoderChannelInfo[R]->granuleLength); 1206 1207 for (band = 0; band < scaleFactorBandsTransmitted; band++) { 1208 if ((CodeBook[band] == INTENSITY_HCB) || 1209 (CodeBook[band] == INTENSITY_HCB2)) { 1210 int bandScale = -(ScaleFactor[band] + 100); 1211 1212 int msb = bandScale >> 2; 1213 int lsb = bandScale & 0x03; 1214 1215 /* exponent of MantissaTable[lsb][0] is 1, thus msb+1 below. */ 1216 FIXP_DBL scale = MantissaTable[lsb][0]; 1217 1218 /* ISO/IEC 14496-3 Chapter 4.6.8.2.3 : 1219 The use of intensity stereo coding is signaled by the use of the 1220 pseudo codebooks INTENSITY_HCB and INTENSITY_HCB2 (15 and 14) only 1221 in the right channel of a channel_pair_element() having a common 1222 ics_info() (common_window == 1). */ 1223 FDK_ASSERT(GetWindowSequence(&pAacDecoderChannelInfo[L]->icsInfo) == 1224 GetWindowSequence(&pAacDecoderChannelInfo[R]->icsInfo)); 1225 FDK_ASSERT(GetWindowShape(&pAacDecoderChannelInfo[L]->icsInfo) == 1226 GetWindowShape(&pAacDecoderChannelInfo[R]->icsInfo)); 1227 1228 rightScale[band] = leftScale[band] + msb + 1; 1229 1230 if (pJointStereoData->MsUsed[band] & groupMask) { 1231 if (CodeBook[band] == INTENSITY_HCB) /* _NOT_ in-phase */ 1232 { 1233 scale = -scale; 1234 } 1235 } else { 1236 if (CodeBook[band] == INTENSITY_HCB2) /* out-of-phase */ 1237 { 1238 scale = -scale; 1239 } 1240 } 1241 1242 for (int index = pScaleFactorBandOffsets[band]; 1243 index < pScaleFactorBandOffsets[band + 1]; index++) { 1244 rightSpectrum[index] = fMult(leftSpectrum[index], scale); 1245 } 1246 } 1247 } 1248 } 1249 } 1250 } 1251