1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 /* 19 20 Filename: sbr_generate_high_freq.c 21 22 ------------------------------------------------------------------------------ 23 REVISION HISTORY 24 25 26 Who: Date: MM/DD/YYYY 27 Description: 28 29 ------------------------------------------------------------------------------ 30 INPUT AND OUTPUT DEFINITIONS 31 32 33 34 ------------------------------------------------------------------------------ 35 FUNCTION DESCRIPTION 36 37 HF generator with built-in QMF bank inverse filtering function 38 39 ------------------------------------------------------------------------------ 40 REQUIREMENTS 41 42 43 ------------------------------------------------------------------------------ 44 REFERENCES 45 46 SC 29 Software Copyright Licencing Disclaimer: 47 48 This software module was originally developed by 49 Coding Technologies 50 51 and edited by 52 - 53 54 in the course of development of the ISO/IEC 13818-7 and ISO/IEC 14496-3 55 standards for reference purposes and its performance may not have been 56 optimized. This software module is an implementation of one or more tools as 57 specified by the ISO/IEC 13818-7 and ISO/IEC 14496-3 standards. 58 ISO/IEC gives users free license to this software module or modifications 59 thereof for use in products claiming conformance to audiovisual and 60 image-coding related ITU Recommendations and/or ISO/IEC International 61 Standards. ISO/IEC gives users the same free license to this software module or 62 modifications thereof for research purposes and further ISO/IEC standardisation. 63 Those intending to use this software module in products are advised that its 64 use may infringe existing patents. ISO/IEC have no liability for use of this 65 software module or modifications thereof. Copyright is not released for 66 products that do not conform to audiovisual and image-coding related ITU 67 Recommendations and/or ISO/IEC International Standards. 68 The original developer retains full right to modify and use the code for its 69 own purpose, assign or donate the code to a third party and to inhibit third 70 parties from using the code for products that do not conform to audiovisual and 71 image-coding related ITU Recommendations and/or ISO/IEC International Standards. 72 This copyright notice must be included in all copies or derivative works. 73 Copyright (c) ISO/IEC 2002. 74 75 ------------------------------------------------------------------------------ 76 PSEUDO-CODE 77 78 ------------------------------------------------------------------------------ 79 */ 80 81 82 /*---------------------------------------------------------------------------- 83 ; INCLUDES 84 ----------------------------------------------------------------------------*/ 85 #ifdef AAC_PLUS 86 87 88 89 #include "sbr_generate_high_freq.h" 90 #include "calc_auto_corr.h" 91 #include "sbr_inv_filt_levelemphasis.h" 92 #include "pv_div.h" 93 #include "fxp_mul32.h" 94 #include "aac_mem_funcs.h" 95 #include "sbr_constants.h" 96 97 /*---------------------------------------------------------------------------- 98 ; MACROS 99 ; Define module specific macros here 100 ----------------------------------------------------------------------------*/ 101 102 103 /*---------------------------------------------------------------------------- 104 ; DEFINES 105 ; Include all pre-processor statements here. Include conditional 106 ; compile variables also. 107 ----------------------------------------------------------------------------*/ 108 109 /*---------------------------------------------------------------------------- 110 ; LOCAL FUNCTION DEFINITIONS 111 ; Function Prototype declaration 112 ----------------------------------------------------------------------------*/ 113 114 #ifdef __cplusplus 115 extern "C" 116 { 117 #endif 118 119 void high_freq_coeff_LC(Int32 sourceBufferReal[][32], 120 Int32 *alphar[2], 121 Int32 *degreeAlias, 122 Int32 *v_k_master, 123 Int32 *scratch_mem); 124 125 126 void high_freq_generation_LC(Int32 sourceBufferReal[][32], 127 Int32 *targetBufferReal, 128 Int32 *alphar[2], 129 Int32 *degreeAlias, 130 Int32 *invFiltBandTable, 131 Int32 targetStopBand, 132 Int32 patchDistance, 133 Int32 numBandsInPatch, 134 Int32 startSample, 135 Int32 slopeLength, 136 Int32 stopSample, 137 Int32 *BwVector, 138 Int32 sbrStartFreqOffset); 139 140 141 #ifdef HQ_SBR 142 143 void high_freq_coeff(Int32 sourceBufferReal[][32], 144 Int32 sourceBufferImag[][32], 145 Int32 *alphar[2], 146 Int32 *alphai[2], 147 Int32 *v_k_master); 148 149 void high_freq_generation(Int32 sourceBufferReal[][32], 150 Int32 sourceBufferImag[][32], 151 Int32 *targetBufferReal, 152 Int32 *targetBufferImag, 153 Int32 *alphar[2], 154 Int32 *alphai[2], 155 Int32 *invFiltBandTable, 156 Int32 targetStopBand, 157 Int32 patchDistance, 158 Int32 numBandsInPatch, 159 Int32 startSample, 160 Int32 slopeLength, 161 Int32 stopSample, 162 Int32 *BwVector, 163 Int32 sbrStartFreqOffset); 164 165 166 #endif 167 168 #ifdef __cplusplus 169 } 170 #endif 171 172 /*---------------------------------------------------------------------------- 173 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS 174 ; Variable declaration - defined here and used outside this module 175 ----------------------------------------------------------------------------*/ 176 177 /*---------------------------------------------------------------------------- 178 ; EXTERNAL FUNCTION REFERENCES 179 ; Declare functions defined elsewhere and referenced in this module 180 ----------------------------------------------------------------------------*/ 181 182 /*---------------------------------------------------------------------------- 183 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 184 ; Declare variables used in this module but defined elsewhere 185 ----------------------------------------------------------------------------*/ 186 187 /*---------------------------------------------------------------------------- 188 ; FUNCTION CODE 189 ----------------------------------------------------------------------------*/ 190 191 void sbr_generate_high_freq(Int32 sourceBufferReal[][32], 192 Int32 sourceBufferImag[][32], 193 Int32 *targetBufferReal, 194 Int32 *targetBufferImag, 195 INVF_MODE *invFiltMode, 196 INVF_MODE *prevInvFiltMode, 197 Int32 *invFiltBandTable, 198 Int32 noInvFiltBands, 199 Int32 highBandStartSb, 200 Int32 *v_k_master, 201 Int32 numMaster, 202 Int32 fs, 203 Int32 *frameInfo, 204 Int32 *degreeAlias, 205 Int32 scratch_mem[][64], 206 Int32 BwVector[MAX_NUM_PATCHES], 207 Int32 BwVectorOld[MAX_NUM_PATCHES], 208 struct PATCH *Patch, 209 Int32 LC_flag, 210 Int32 *highBandStopSb) 211 { 212 Int32 i; 213 Int32 patch; 214 Int32 startSample; 215 Int32 stopSample; 216 Int32 goalSb; 217 Int32 targetStopBand; 218 Int32 sourceStartBand; 219 Int32 patchDistance; 220 Int32 numBandsInPatch; 221 Int32 sbrStartFreqOffset; 222 223 Int32 *alphar[2]; 224 Int32 *alphai[2]; 225 226 Int32 lsb = v_k_master[0]; /* Lowest subband related to the synthesis filterbank */ 227 Int32 usb = v_k_master[numMaster]; /* Stop subband related to the synthesis filterbank */ 228 Int32 xoverOffset = highBandStartSb - v_k_master[0]; /* Calculate distance in subbands between k0 and kx */ 229 230 231 232 Int slopeLength = 0; 233 234 Int32 firstSlotOffs = frameInfo[1]; 235 Int32 lastSlotOffs = frameInfo[frameInfo[0] + 1] - 16; 236 237 238 alphar[0] = scratch_mem[0]; 239 alphar[1] = scratch_mem[1]; 240 alphai[0] = scratch_mem[2]; 241 alphai[1] = scratch_mem[3]; 242 243 244 startSample = (firstSlotOffs << 1); 245 stopSample = (lastSlotOffs << 1) + 32; 246 247 248 sbr_inv_filt_levelemphasis(invFiltMode, 249 prevInvFiltMode, 250 noInvFiltBands, 251 BwVector, 252 BwVectorOld); 253 254 255 if (LC_flag == ON) 256 { 257 /* Set subbands to zero */ 258 259 pv_memset((void *)&targetBufferReal[startSample*SBR_NUM_BANDS], 260 0, 261 (stopSample - startSample)*SBR_NUM_BANDS*sizeof(targetBufferReal[0])); 262 263 high_freq_coeff_LC(sourceBufferReal, 264 alphar, 265 degreeAlias, 266 v_k_master, 267 scratch_mem[4]); 268 } 269 #ifdef HQ_SBR 270 else 271 { 272 /* Set subbands to zero */ 273 274 pv_memset((void *)&targetBufferReal[startSample*SBR_NUM_BANDS], 275 0, 276 (stopSample - startSample)*SBR_NUM_BANDS*sizeof(targetBufferReal[0])); 277 pv_memset((void *)&targetBufferImag[startSample*SBR_NUM_BANDS], 278 0, 279 (stopSample - startSample)*SBR_NUM_BANDS*sizeof(targetBufferImag[0])); 280 281 high_freq_coeff(sourceBufferReal, 282 sourceBufferImag, 283 alphar, 284 alphai, 285 v_k_master); 286 287 } 288 #endif /* #ifdef HQ_SBR */ 289 290 291 292 293 /* 294 * Initialize the patching parameter 295 */ 296 switch (fs) 297 298 { 299 /* 300 * goalSb = (int)( 2.048e6f / fs + 0.5f ); 301 */ 302 case 48000: 303 goalSb = 43; /* 16 kHz band */ 304 break; 305 case 32000: 306 goalSb = 64; /* 16 kHz band */ 307 break; 308 case 24000: 309 goalSb = 85; /* 16 kHz band */ 310 break; 311 case 22050: 312 goalSb = 93; /* 16 kHz band */ 313 break; 314 case 16000: 315 goalSb = 128; /* 16 kHz band */ 316 break; 317 case 44100: 318 default: 319 goalSb = 46; /* 16 kHz band */ 320 break; 321 } 322 323 i = 0; 324 325 if (goalSb > v_k_master[0]) 326 { 327 if (goalSb < v_k_master[numMaster]) 328 { 329 while (v_k_master[i] < goalSb) 330 { 331 i++; 332 } 333 } 334 else 335 { 336 i = numMaster; 337 } 338 } 339 340 goalSb = v_k_master[i]; 341 342 /* First patch */ 343 sourceStartBand = xoverOffset + 1; 344 targetStopBand = lsb + xoverOffset; 345 346 /* even (odd) numbered channel must be patched to even (odd) numbered channel */ 347 patch = 0; 348 349 350 sbrStartFreqOffset = targetStopBand; 351 352 while (targetStopBand < usb) 353 { 354 Patch->targetStartBand[patch] = targetStopBand; 355 356 numBandsInPatch = goalSb - targetStopBand; /* get the desired range of the patch */ 357 358 if (numBandsInPatch >= lsb - sourceStartBand) 359 { 360 /* desired number bands are not available -> patch whole source range */ 361 patchDistance = targetStopBand - sourceStartBand; /* get the targetOffset */ 362 patchDistance = patchDistance & ~1; /* rounding off odd numbers and make all even */ 363 numBandsInPatch = lsb - (targetStopBand - patchDistance); 364 365 if (targetStopBand + numBandsInPatch > v_k_master[0]) 366 { 367 i = numMaster; 368 if (targetStopBand + numBandsInPatch < v_k_master[numMaster]) 369 { 370 while (v_k_master[i] > targetStopBand + numBandsInPatch) 371 { 372 i--; 373 } 374 } 375 } 376 else 377 { 378 i = 0; 379 } 380 numBandsInPatch = v_k_master[i] - targetStopBand; 381 } 382 383 /* desired number bands are available -> get the minimal even patching distance */ 384 patchDistance = numBandsInPatch + targetStopBand - lsb; /* get minimal distance */ 385 patchDistance = (patchDistance + 1) & ~1; /* rounding up odd numbers and make all even */ 386 387 /* All patches but first */ 388 sourceStartBand = 1; 389 390 /* Check if we are close to goalSb */ 391 if (goalSb - (targetStopBand + numBandsInPatch) < 3) 392 { /* MPEG doc */ 393 goalSb = usb; 394 } 395 396 397 if ((numBandsInPatch < 3) && (patch > 0)) 398 { 399 if (LC_flag == ON) 400 { 401 402 pv_memset((void *) °reeAlias[targetStopBand], 0, numBandsInPatch*sizeof(*degreeAlias)); 403 } 404 break; 405 } 406 407 if (numBandsInPatch <= 0) 408 { 409 continue; 410 } 411 412 413 /* 414 * High Frequency generation 415 */ 416 417 if (LC_flag == ON) 418 { 419 420 high_freq_generation_LC(sourceBufferReal, 421 (Int32 *)targetBufferReal, 422 alphar, 423 degreeAlias, 424 invFiltBandTable, 425 targetStopBand, 426 patchDistance, 427 numBandsInPatch, 428 startSample, 429 slopeLength, 430 stopSample, 431 BwVector, 432 sbrStartFreqOffset); 433 434 } 435 #ifdef HQ_SBR 436 else 437 { 438 439 high_freq_generation(sourceBufferReal, 440 sourceBufferImag, 441 (Int32 *)targetBufferReal, 442 (Int32 *)targetBufferImag, 443 alphar, 444 alphai, 445 invFiltBandTable, 446 targetStopBand, 447 patchDistance, 448 numBandsInPatch, 449 startSample, 450 slopeLength, 451 stopSample, 452 BwVector, 453 sbrStartFreqOffset); 454 455 } 456 #endif 457 458 targetStopBand += numBandsInPatch; 459 460 patch++; 461 462 } /* targetStopBand */ 463 464 Patch->noOfPatches = patch; 465 466 pv_memmove(BwVectorOld, BwVector, noInvFiltBands*sizeof(BwVector[0])); 467 468 *highBandStopSb = goalSb; 469 470 471 } 472 473 474 /*---------------------------------------------------------------------------- 475 ; FUNCTION CODE 476 ----------------------------------------------------------------------------*/ 477 478 479 void high_freq_coeff_LC(Int32 sourceBufferReal[][32], 480 Int32 *alphar[2], 481 Int32 *degreeAlias, 482 Int32 *v_k_master, 483 Int32 *scratch_mem) 484 { 485 486 Int32 fac; 487 Int32 *k1; 488 struct ACORR_COEFS ac; 489 struct intg_div quotient; 490 491 Int32 temp1; 492 Int32 temp2; 493 Int32 temp3; 494 Int32 autoCorrLength; 495 Int32 loBand; 496 497 k1 = scratch_mem; 498 499 500 autoCorrLength = 38; 501 502 for (loBand = 1; loBand < v_k_master[0]; loBand++) 503 { 504 505 calc_auto_corr_LC(&ac, 506 sourceBufferReal, 507 loBand, 508 autoCorrLength); 509 510 if (ac.r11r && ac.det) 511 { 512 513 pv_div(ac.r01r, ac.r11r, "ient); 514 515 fac = -(quotient.quotient >> 2); /* Q28 */ 516 517 if (quotient.shift_factor > 0) 518 { 519 fac >>= quotient.shift_factor; /* Q28 */ 520 } 521 else if (quotient.shift_factor < 0) 522 { 523 if (quotient.shift_factor > -4) /* |fac| < 8 */ 524 { 525 fac <<= (-quotient.shift_factor); /* Q28 */ 526 } 527 else 528 { 529 fac = 0x80000000; /* overshoot possible fac = -8 */ 530 } 531 } 532 533 /* 534 * prevent for overflow of reflection coefficients 535 */ 536 if (quotient.shift_factor > 0) 537 { 538 k1[loBand] = - quotient.quotient >> quotient.shift_factor; 539 } 540 else if (quotient.shift_factor == 0) 541 { 542 if (quotient.quotient >= 0x40000000) 543 { 544 k1[loBand] = (Int32)0xC0000000; /* -1.0 in Q30 */ 545 } 546 else if (quotient.quotient <= (Int32)0xC0000000) 547 { 548 k1[loBand] = 0x40000000; /* 1.0 in Q30 */ 549 } 550 else 551 { 552 k1[loBand] = -quotient.quotient; 553 } 554 } 555 else 556 { 557 if (quotient.quotient > 0) 558 { 559 k1[loBand] = (Int32)0xC0000000; /* -1.0 in Q30 */ 560 } 561 else 562 { 563 k1[loBand] = 0x40000000; /* 1.0 in Q30 */ 564 } 565 } 566 /* 567 * alphar[1][loBand] = ( ac.r01r * ac.r12r - ac.r02r * ac.r11r ) / ac.det; 568 */ 569 570 temp1 = -fxp_mul32_Q30(ac.r02r, ac.r11r); 571 temp1 = fxp_mac32_Q30(ac.r01r, ac.r12r, temp1); 572 573 temp2 = ac.det; 574 temp3 = temp1 > 0 ? temp1 : -temp1; 575 temp2 = temp2 > 0 ? temp2 : -temp2; 576 577 /* prevent for shootovers */ 578 if ((temp3 >> 2) >= temp2 || fac == (Int32)0x80000000) 579 { 580 alphar[0][loBand] = 0; 581 alphar[1][loBand] = 0; 582 } 583 else 584 { 585 pv_div(temp1, ac.det, "ient); 586 /* 587 * alphar[1][loBand] is lesser than 4.0 588 */ 589 alphar[1][loBand] = quotient.quotient; 590 quotient.shift_factor += 2; /* Q28 */ 591 592 if (quotient.shift_factor > 0) 593 { 594 alphar[1][loBand] >>= quotient.shift_factor; /* Q28 */ 595 } 596 else if (quotient.shift_factor < 0) /* at this point can only be -1 */ 597 { 598 alphar[1][loBand] <<= (-quotient.shift_factor); /* Q28 */ 599 } 600 601 /* 602 * alphar[0][loBand] = - ( ac.r01r + alphar[1][loBand] * ac.r12r ) / ac.r11r; 603 */ 604 605 pv_div(ac.r12r, ac.r11r, "ient); 606 607 temp3 = (quotient.quotient >> 2); /* Q28 */ 608 609 if (quotient.shift_factor > 0) 610 { 611 temp3 >>= quotient.shift_factor; /* Q28 */ 612 } 613 else if (quotient.shift_factor < 0) 614 { 615 temp3 <<= (-quotient.shift_factor); /* Q28 */ 616 } 617 618 alphar[0][loBand] = fac - fxp_mul32_Q28(alphar[1][loBand], temp3) ; /* Q28 */ 619 620 if ((alphar[0][loBand] >= 0x40000000) || (alphar[0][loBand] <= (Int32)0xC0000000)) 621 { 622 alphar[0][loBand] = 0; 623 alphar[1][loBand] = 0; 624 } 625 626 } 627 628 } 629 else 630 { 631 alphar[0][loBand] = 0; 632 alphar[1][loBand] = 0; 633 634 k1[loBand] = 0; 635 } 636 637 } 638 639 k1[0] = 0; 640 degreeAlias[1] = 0; 641 for (loBand = 2; loBand < v_k_master[0]; loBand++) 642 { 643 degreeAlias[loBand] = 0; 644 if ((!(loBand & 1)) && (k1[loBand] < 0)) 645 { 646 if (k1[loBand-1] < 0) 647 { // 2-CH Aliasing Detection 648 degreeAlias[loBand] = 0x40000000; 649 if (k1[loBand-2] > 0) 650 { // 3-CH Aliasing Detection 651 degreeAlias[loBand-1] = 0x40000000 - fxp_mul32_Q30(k1[loBand-1], k1[loBand-1]); 652 653 } 654 } 655 else if (k1[loBand-2] > 0) 656 { // 3-CH Aliasing Detection 657 degreeAlias[loBand] = 0x40000000 - fxp_mul32_Q30(k1[loBand-1], k1[loBand-1]); 658 } 659 } 660 if ((loBand & 1) && (k1[loBand] > 0)) 661 { 662 if (k1[loBand-1] > 0) 663 { // 2-CH Aliasing Detection 664 degreeAlias[loBand] = 0x40000000; 665 if (k1[loBand-2] < 0) 666 { // 3-CH Aliasing Detection 667 degreeAlias[loBand-1] = 0x40000000 - fxp_mul32_Q30(k1[loBand-1], k1[loBand-1]); 668 } 669 } 670 else if (k1[loBand-2] < 0) 671 { // 3-CH Aliasing Detection 672 degreeAlias[loBand] = 0x40000000 - fxp_mul32_Q30(k1[loBand-1], k1[loBand-1]); 673 } 674 } 675 } 676 677 } 678 679 680 /*---------------------------------------------------------------------------- 681 ; FUNCTION CODE 682 ----------------------------------------------------------------------------*/ 683 684 void high_freq_generation_LC(Int32 sourceBufferReal[][32], 685 Int32 *targetBufferReal, 686 Int32 *alphar[2], 687 Int32 *degreeAlias, 688 Int32 *invFiltBandTable, 689 Int32 targetStopBand, 690 Int32 patchDistance, 691 Int32 numBandsInPatch, 692 Int32 startSample, 693 Int32 slopeLength, 694 Int32 stopSample, 695 Int32 *BwVector, 696 Int32 sbrStartFreqOffset) 697 { 698 699 Int32 temp1; 700 Int32 temp2; 701 Int32 temp3; 702 703 704 Int32 a0r; 705 Int32 a1r; 706 Int32 i; 707 Int32 bw; 708 Int32 hiBand; 709 Int32 bwIndex; 710 Int32 loBand; 711 Int32 j; 712 713 bwIndex = 0; 714 715 for (hiBand = targetStopBand; hiBand < targetStopBand + numBandsInPatch; hiBand++) 716 { 717 loBand = hiBand - patchDistance; 718 719 if (hiBand != targetStopBand) 720 { 721 degreeAlias[hiBand] = degreeAlias[loBand]; 722 } 723 else 724 { 725 degreeAlias[hiBand] = 0; 726 } 727 728 while (hiBand >= invFiltBandTable[bwIndex]) 729 { 730 bwIndex++; 731 } 732 733 bw = BwVector[bwIndex]; 734 735 /* 736 * Inverse Filtering 737 */ 738 739 740 j = hiBand - sbrStartFreqOffset; 741 742 if (bw > 0 && (alphar[0][loBand] | alphar[1][loBand])) 743 { 744 /* Apply current bandwidth expansion factor */ 745 a0r = fxp_mul32_Q29(bw, alphar[0][loBand]); 746 747 bw = fxp_mul32_Q31(bw, bw) << 2; 748 749 a1r = fxp_mul32_Q28(bw, alphar[1][loBand]); 750 751 i = startSample + slopeLength; 752 753 temp1 = sourceBufferReal[i ][loBand]; 754 temp2 = sourceBufferReal[i - 1][loBand]; 755 temp3 = sourceBufferReal[i - 2][loBand]; 756 757 for (; i < stopSample + slopeLength - 1; i++) 758 { 759 760 761 targetBufferReal[i*SBR_NUM_BANDS + j] = temp1 + fxp_mul32_Q28(a0r, temp2) + 762 fxp_mul32_Q28(a1r, temp3); 763 764 765 temp3 = temp2; 766 temp2 = temp1; 767 temp1 = sourceBufferReal[i + 1][loBand]; 768 } 769 targetBufferReal[i*SBR_NUM_BANDS + j] = temp1 + fxp_mul32_Q28(a0r, temp2) + 770 fxp_mul32_Q28(a1r, temp3); 771 772 } 773 else 774 { 775 776 for (i = startSample + slopeLength; i < stopSample + slopeLength; i++) 777 { 778 targetBufferReal[i*SBR_NUM_BANDS + j] = sourceBufferReal[i][loBand]; 779 } 780 } 781 782 783 } /* hiBand */ 784 785 } 786 787 788 #ifdef HQ_SBR 789 790 /*---------------------------------------------------------------------------- 791 ; FUNCTION CODE 792 ----------------------------------------------------------------------------*/ 793 794 void high_freq_coeff(Int32 sourceBufferReal[][32], 795 Int32 sourceBufferImag[][32], 796 Int32 *alphar[2], 797 Int32 *alphai[2], 798 Int32 *v_k_master) 799 { 800 801 Int32 overflow_flag; 802 803 Int32 temp1r; 804 Int32 temp1i; 805 Int32 temp0r; 806 Int32 temp0i; 807 Int32 loBand; 808 809 struct ACORR_COEFS ac; 810 struct intg_div quotient; 811 812 Int32 autoCorrLength; 813 814 autoCorrLength = 38; 815 816 for (loBand = 1; loBand < v_k_master[0]; loBand++) 817 { 818 819 calc_auto_corr(&ac, 820 sourceBufferReal, 821 sourceBufferImag, 822 loBand, 823 autoCorrLength); 824 825 826 overflow_flag = 0; 827 828 if (ac.det < 1) 829 { 830 /* --- */ 831 temp1r = 0; 832 temp1i = 0; 833 alphar[1][loBand] = 0; 834 alphai[1][loBand] = 0; 835 836 } 837 else 838 { 839 840 temp1r = fxp_mul32_Q29(ac.r01r, ac.r12r); 841 temp1r = fxp_msu32_Q29(ac.r01i, ac.r12i, temp1r); 842 temp1r = fxp_msu32_Q29(ac.r02r, ac.r11r, temp1r); 843 844 temp1i = fxp_mul32_Q29(ac.r01r, ac.r12i); 845 temp1i = fxp_msu32_Q29(ac.r02i, ac.r11r, temp1i); 846 temp1i = fxp_mac32_Q29(ac.r01i, ac.r12r, temp1i); 847 848 pv_div(temp1r, ac.det, "ient); 849 overflow_flag = (quotient.shift_factor < -2) ? 1 : 0; 850 temp1r = quotient.quotient >> (2 + quotient.shift_factor); /* Q28 */ 851 pv_div(temp1i, ac.det, "ient); 852 overflow_flag = (quotient.shift_factor < -2) ? 1 : 0; 853 temp1i = quotient.quotient >> (2 + quotient.shift_factor); /* Q28 */ 854 855 alphar[1][loBand] = temp1r; 856 alphai[1][loBand] = temp1i; 857 858 } 859 860 if (ac.r11r == 0) 861 { 862 temp0r = 0; 863 temp0i = 0; 864 alphar[0][loBand] = 0; 865 alphai[0][loBand] = 0; 866 867 } 868 else 869 { 870 temp0r = - (ac.r01r + fxp_mul32_Q28(temp1r, ac.r12r) + fxp_mul32_Q28(temp1i, ac.r12i)); 871 temp0i = - (ac.r01i + fxp_mul32_Q28(temp1i, ac.r12r) - fxp_mul32_Q28(temp1r, ac.r12i)); 872 873 pv_div(temp0r, ac.r11r, "ient); 874 overflow_flag = (quotient.shift_factor < -2) ? 1 : 0; 875 temp0r = quotient.quotient >> (2 + quotient.shift_factor); /* Q28 */ 876 pv_div(temp0i, ac.r11r, "ient); 877 overflow_flag = (quotient.shift_factor < -2) ? 1 : 0; 878 temp0i = quotient.quotient >> (2 + quotient.shift_factor); /* Q28 */ 879 880 alphar[0][loBand] = temp0r; 881 alphai[0][loBand] = temp0i; 882 883 } 884 885 /* prevent for shootovers */ 886 887 if (fxp_mul32_Q28((temp0r >> 2), (temp0r >> 2)) + fxp_mul32_Q28((temp0i >> 2), (temp0i >> 2)) >= 0x10000000 || 888 fxp_mul32_Q28((temp1r >> 2), (temp1r >> 2)) + fxp_mul32_Q28((temp1i >> 2), (temp1i >> 2)) >= 0x10000000 || 889 overflow_flag) /* 0x10000000 == 1 in Q28 */ 890 891 { 892 alphar[0][loBand] = 0; 893 alphar[1][loBand] = 0; 894 alphai[0][loBand] = 0; 895 alphai[1][loBand] = 0; 896 897 } 898 } 899 } 900 901 /*---------------------------------------------------------------------------- 902 ; FUNCTION CODE 903 ----------------------------------------------------------------------------*/ 904 905 906 907 void high_freq_generation(Int32 sourceBufferReal[][32], 908 Int32 sourceBufferImag[][32], 909 Int32 *targetBufferReal, 910 Int32 *targetBufferImag, 911 Int32 *alphar[2], 912 Int32 *alphai[2], 913 Int32 *invFiltBandTable, 914 Int32 targetStopBand, 915 Int32 patchDistance, 916 Int32 numBandsInPatch, 917 Int32 startSample, 918 Int32 slopeLength, 919 Int32 stopSample, 920 Int32 *BwVector, 921 Int32 sbrStartFreqOffset) 922 { 923 Int32 temp1_r; 924 Int32 temp2_r; 925 Int32 temp3_r; 926 Int32 temp1_i; 927 Int32 temp2_i; 928 Int32 temp3_i; 929 930 931 Int32 a0i; 932 Int32 a1i; 933 Int32 a0r; 934 Int32 a1r; 935 Int32 i; 936 Int32 bw; 937 Int32 hiBand; 938 Int32 bwIndex; 939 Int32 loBand; 940 Int32 j; 941 942 943 944 int64_t tmp; 945 946 bwIndex = 0; 947 948 for (hiBand = targetStopBand; hiBand < targetStopBand + numBandsInPatch; hiBand++) 949 { 950 951 loBand = hiBand - patchDistance; 952 953 while (hiBand >= invFiltBandTable[bwIndex]) 954 { 955 bwIndex++; 956 } 957 958 bw = BwVector[bwIndex]; 959 960 /* 961 * Inverse Filtering 962 */ 963 964 965 j = hiBand - sbrStartFreqOffset; 966 967 if (bw >= 0 && (alphar[0][loBand] | alphar[1][loBand] | 968 alphai[0][loBand] | alphai[1][loBand])) 969 { 970 /* Apply current bandwidth expansion factor */ 971 a0r = fxp_mul32_Q29(bw, alphar[0][loBand]); 972 a0i = fxp_mul32_Q29(bw, alphai[0][loBand]); 973 974 975 bw = fxp_mul32_Q30(bw, bw); 976 977 978 a1r = fxp_mul32_Q28(bw, alphar[1][loBand]); 979 a1i = fxp_mul32_Q28(bw, alphai[1][loBand]); 980 981 982 i = startSample + slopeLength; 983 j += i * SBR_NUM_BANDS; 984 985 temp1_r = sourceBufferReal[i ][loBand]; 986 temp2_r = sourceBufferReal[i - 1][loBand]; 987 temp3_r = sourceBufferReal[i - 2][loBand]; 988 989 temp1_i = sourceBufferImag[i ][loBand]; 990 temp2_i = sourceBufferImag[i - 1][loBand]; 991 temp3_i = sourceBufferImag[i - 2][loBand]; 992 993 while (i < stopSample + slopeLength) 994 { 995 tmp = fxp_mac64_Q31(((int64_t)temp1_r << 28), a0r, temp2_r); 996 tmp = fxp_mac64_Q31(tmp, -a0i, temp2_i); 997 tmp = fxp_mac64_Q31(tmp, a1r, temp3_r); 998 targetBufferReal[j] = (Int32)(fxp_mac64_Q31(tmp, -a1i, temp3_i) >> 28); 999 1000 tmp = fxp_mac64_Q31(((int64_t)temp1_i << 28), a0i, temp2_r); 1001 tmp = fxp_mac64_Q31(tmp, a0r, temp2_i); 1002 tmp = fxp_mac64_Q31(tmp, a1i, temp3_r); 1003 targetBufferImag[j] = (Int32)(fxp_mac64_Q31(tmp, a1r, temp3_i) >> 28); 1004 1005 i++; 1006 j += SBR_NUM_BANDS; 1007 1008 temp3_r = temp2_r; 1009 temp2_r = temp1_r; 1010 temp1_r = sourceBufferReal[i ][loBand]; 1011 1012 temp3_i = temp2_i; 1013 temp2_i = temp1_i; 1014 temp1_i = sourceBufferImag[i ][loBand]; 1015 1016 } 1017 1018 } 1019 1020 1021 1022 else 1023 { 1024 i = startSample + slopeLength; 1025 j += i * SBR_NUM_BANDS; 1026 1027 for (; i < stopSample + slopeLength; i++) 1028 { 1029 targetBufferReal[j] = sourceBufferReal[i][loBand]; 1030 targetBufferImag[j] = sourceBufferImag[i][loBand]; 1031 j += SBR_NUM_BANDS; 1032 } 1033 } 1034 } 1035 } 1036 1037 #endif 1038 1039 1040 #endif 1041