1/* ----------------------------------------------------------------------------- 2Software License for The Fraunhofer FDK AAC Codec Library for Android 3 4© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten 5Forschung e.V. All rights reserved. 6 7 1. INTRODUCTION 8The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software 9that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding 10scheme for digital audio. This FDK AAC Codec software is intended to be used on 11a wide variety of Android devices. 12 13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient 14general perceptual audio codecs. AAC-ELD is considered the best-performing 15full-bandwidth communications codec by independent studies and is widely 16deployed. AAC has been standardized by ISO and IEC as part of the MPEG 17specifications. 18 19Patent licenses for necessary patent claims for the FDK AAC Codec (including 20those of Fraunhofer) may be obtained through Via Licensing 21(www.vialicensing.com) or through the respective patent owners individually for 22the purpose of encoding or decoding bit streams in products that are compliant 23with the ISO/IEC MPEG audio standards. Please note that most manufacturers of 24Android devices already license these patent claims through Via Licensing or 25directly from the patent owners, and therefore FDK AAC Codec software may 26already be covered under those patent licenses when it is used for those 27licensed purposes only. 28 29Commercially-licensed AAC software libraries, including floating-point versions 30with enhanced sound quality, are also available from Fraunhofer. Users are 31encouraged to check the Fraunhofer website for additional applications 32information and documentation. 33 342. COPYRIGHT LICENSE 35 36Redistribution and use in source and binary forms, with or without modification, 37are permitted without payment of copyright license fees provided that you 38satisfy the following conditions: 39 40You must retain the complete text of this software license in redistributions of 41the FDK AAC Codec or your modifications thereto in source code form. 42 43You must retain the complete text of this software license in the documentation 44and/or other materials provided with redistributions of the FDK AAC Codec or 45your modifications thereto in binary form. You must make available free of 46charge copies of the complete source code of the FDK AAC Codec and your 47modifications thereto to recipients of copies in binary form. 48 49The name of Fraunhofer may not be used to endorse or promote products derived 50from this library without prior written permission. 51 52You may not charge copyright license fees for anyone to use, copy or distribute 53the FDK AAC Codec software or your modifications thereto. 54 55Your modified versions of the FDK AAC Codec must carry prominent notices stating 56that you changed the software and the date of any change. For modified versions 57of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" 58must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK 59AAC Codec Library for Android." 60 613. NO PATENT LICENSE 62 63NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without 64limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. 65Fraunhofer provides no warranty of patent non-infringement with respect to this 66software. 67 68You may use this FDK AAC Codec software or modifications thereto only for 69purposes that are authorized by appropriate patent licenses. 70 714. DISCLAIMER 72 73This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright 74holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, 75including but not limited to the implied warranties of merchantability and 76fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 77CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, 78or consequential damages, including but not limited to procurement of substitute 79goods or services; loss of use, data, or profits, or business interruption, 80however caused and on any theory of liability, whether in contract, strict 81liability, or tort (including negligence), arising in any way out of the use of 82this software, even if advised of the possibility of such damage. 83 845. CONTACT INFORMATION 85 86Fraunhofer Institute for Integrated Circuits IIS 87Attention: Audio and Multimedia Departments - FDK AAC LL 88Am Wolfsmantel 33 8991058 Erlangen, Germany 90 91www.iis.fraunhofer.de/amm 92amm-info@iis.fraunhofer.de 93----------------------------------------------------------------------------- */ 94 95/**************************** SBR encoder library ****************************** 96 97 Author(s): 98 99 Description: 100 101*******************************************************************************/ 102 103/*! 104 \file 105 \brief frequency scale $Revision: 95225 $ 106*/ 107 108#include "sbrenc_freq_sca.h" 109#include "sbr_misc.h" 110 111#include "genericStds.h" 112 113/* StartFreq */ 114static INT getStartFreq(INT fsCore, const INT start_freq); 115 116/* StopFreq */ 117static INT getStopFreq(INT fsCore, const INT stop_freq); 118 119static INT numberOfBands(INT b_p_o, INT start, INT stop, FIXP_DBL warp_factor); 120static void CalcBands(INT *diff, INT start, INT stop, INT num_bands); 121static INT modifyBands(INT max_band, INT *diff, INT length); 122static void cumSum(INT start_value, INT *diff, INT length, UCHAR *start_adress); 123 124/******************************************************************************* 125 Functionname: FDKsbrEnc_getSbrStartFreqRAW 126 ******************************************************************************* 127 Description: 128 129 Arguments: 130 131 Return: 132 *******************************************************************************/ 133 134INT FDKsbrEnc_getSbrStartFreqRAW(INT startFreq, INT fsCore) { 135 INT result; 136 137 if (startFreq < 0 || startFreq > 15) { 138 return -1; 139 } 140 /* Update startFreq struct */ 141 result = getStartFreq(fsCore, startFreq); 142 143 result = 144 (result * (fsCore >> 5) + 1) >> 1; /* (result*fsSBR/QMFbands+1)>>1; */ 145 146 return (result); 147 148} /* End FDKsbrEnc_getSbrStartFreqRAW */ 149 150/******************************************************************************* 151 Functionname: getSbrStopFreq 152 ******************************************************************************* 153 Description: 154 155 Arguments: 156 157 Return: 158 *******************************************************************************/ 159INT FDKsbrEnc_getSbrStopFreqRAW(INT stopFreq, INT fsCore) { 160 INT result; 161 162 if (stopFreq < 0 || stopFreq > 13) return -1; 163 164 /* Uppdate stopFreq struct */ 165 result = getStopFreq(fsCore, stopFreq); 166 result = 167 (result * (fsCore >> 5) + 1) >> 1; /* (result*fsSBR/QMFbands+1)>>1; */ 168 169 return (result); 170} /* End getSbrStopFreq */ 171 172/******************************************************************************* 173 Functionname: getStartFreq 174 ******************************************************************************* 175 Description: 176 177 Arguments: fsCore - core sampling rate 178 179 180 Return: 181 *******************************************************************************/ 182static INT getStartFreq(INT fsCore, const INT start_freq) { 183 INT k0_min; 184 185 switch (fsCore) { 186 case 8000: 187 k0_min = 24; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */ 188 break; 189 case 11025: 190 k0_min = 17; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */ 191 break; 192 case 12000: 193 k0_min = 16; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */ 194 break; 195 case 16000: 196 k0_min = 16; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */ 197 break; 198 case 22050: 199 k0_min = 12; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */ 200 break; 201 case 24000: 202 k0_min = 11; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */ 203 break; 204 case 32000: 205 k0_min = 10; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */ 206 break; 207 case 44100: 208 k0_min = 7; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */ 209 break; 210 case 48000: 211 k0_min = 7; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */ 212 break; 213 case 96000: 214 k0_min = 3; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */ 215 break; 216 default: 217 k0_min = 11; /* illegal fs */ 218 } 219 220 switch (fsCore) { 221 case 8000: { 222 INT v_offset[] = {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}; 223 return (k0_min + v_offset[start_freq]); 224 } 225 case 11025: { 226 INT v_offset[] = {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13}; 227 return (k0_min + v_offset[start_freq]); 228 } 229 case 12000: { 230 INT v_offset[] = {-5, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16}; 231 return (k0_min + v_offset[start_freq]); 232 } 233 case 16000: { 234 INT v_offset[] = {-6, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16}; 235 return (k0_min + v_offset[start_freq]); 236 } 237 case 22050: 238 case 24000: 239 case 32000: { 240 INT v_offset[] = {-4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20}; 241 return (k0_min + v_offset[start_freq]); 242 } 243 case 44100: 244 case 48000: 245 case 96000: { 246 INT v_offset[] = {-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24}; 247 return (k0_min + v_offset[start_freq]); 248 } 249 default: { 250 INT v_offset[] = {0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24, 28, 33}; 251 return (k0_min + v_offset[start_freq]); 252 } 253 } 254} /* End getStartFreq */ 255 256/******************************************************************************* 257 Functionname: getStopFreq 258 ******************************************************************************* 259 Description: 260 261 Arguments: 262 263 Return: 264 *******************************************************************************/ 265static INT getStopFreq(INT fsCore, const INT stop_freq) { 266 INT result, i; 267 INT k1_min; 268 INT v_dstop[13]; 269 270 INT *v_stop_freq = NULL; 271 INT v_stop_freq_16[14] = {48, 49, 50, 51, 52, 54, 55, 272 56, 57, 59, 60, 61, 63, 64}; 273 INT v_stop_freq_22[14] = {35, 37, 38, 40, 42, 44, 46, 274 48, 51, 53, 56, 58, 61, 64}; 275 INT v_stop_freq_24[14] = {32, 34, 36, 38, 40, 42, 44, 276 46, 49, 52, 55, 58, 61, 64}; 277 INT v_stop_freq_32[14] = {32, 34, 36, 38, 40, 42, 44, 278 46, 49, 52, 55, 58, 61, 64}; 279 INT v_stop_freq_44[14] = {23, 25, 27, 29, 32, 34, 37, 280 40, 43, 47, 51, 55, 59, 64}; 281 INT v_stop_freq_48[14] = {21, 23, 25, 27, 30, 32, 35, 282 38, 42, 45, 49, 54, 59, 64}; 283 INT v_stop_freq_64[14] = {20, 22, 24, 26, 29, 31, 34, 284 37, 41, 45, 49, 54, 59, 64}; 285 INT v_stop_freq_88[14] = {15, 17, 19, 21, 23, 26, 29, 286 33, 37, 41, 46, 51, 57, 64}; 287 INT v_stop_freq_96[14] = {13, 15, 17, 19, 21, 24, 27, 288 31, 35, 39, 44, 50, 57, 64}; 289 INT v_stop_freq_192[14] = {7, 8, 10, 12, 14, 16, 19, 290 23, 27, 32, 38, 46, 54, 64}; 291 292 switch (fsCore) { 293 case 8000: 294 k1_min = 48; 295 v_stop_freq = v_stop_freq_16; 296 break; 297 case 11025: 298 k1_min = 35; 299 v_stop_freq = v_stop_freq_22; 300 break; 301 case 12000: 302 k1_min = 32; 303 v_stop_freq = v_stop_freq_24; 304 break; 305 case 16000: 306 k1_min = 32; 307 v_stop_freq = v_stop_freq_32; 308 break; 309 case 22050: 310 k1_min = 23; 311 v_stop_freq = v_stop_freq_44; 312 break; 313 case 24000: 314 k1_min = 21; 315 v_stop_freq = v_stop_freq_48; 316 break; 317 case 32000: 318 k1_min = 20; 319 v_stop_freq = v_stop_freq_64; 320 break; 321 case 44100: 322 k1_min = 15; 323 v_stop_freq = v_stop_freq_88; 324 break; 325 case 48000: 326 k1_min = 13; 327 v_stop_freq = v_stop_freq_96; 328 break; 329 case 96000: 330 k1_min = 7; 331 v_stop_freq = v_stop_freq_192; 332 break; 333 default: 334 k1_min = 21; /* illegal fs */ 335 } 336 337 /* Ensure increasing bandwidth */ 338 for (i = 0; i <= 12; i++) { 339 v_dstop[i] = v_stop_freq[i + 1] - v_stop_freq[i]; 340 } 341 342 FDKsbrEnc_Shellsort_int(v_dstop, 13); /* Sort bandwidth changes */ 343 344 result = k1_min; 345 for (i = 0; i < stop_freq; i++) { 346 result = result + v_dstop[i]; 347 } 348 349 return (result); 350 351} /* End getStopFreq */ 352 353/******************************************************************************* 354 Functionname: FDKsbrEnc_FindStartAndStopBand 355 ******************************************************************************* 356 Description: 357 358 Arguments: srSbr SBR sampling freqency 359 srCore AAC core sampling freqency 360 noChannels Number of QMF channels 361 startFreq SBR start frequency in QMF bands 362 stopFreq SBR start frequency in QMF bands 363 364 *k0 Output parameter 365 *k2 Output parameter 366 367 Return: Error code (0 is OK) 368 *******************************************************************************/ 369INT FDKsbrEnc_FindStartAndStopBand(const INT srSbr, const INT srCore, 370 const INT noChannels, const INT startFreq, 371 const INT stopFreq, INT *k0, INT *k2) { 372 /* Update startFreq struct */ 373 *k0 = getStartFreq(srCore, startFreq); 374 375 /* Test if start freq is outside corecoder range */ 376 if (srSbr * noChannels < *k0 * srCore) { 377 return ( 378 1); /* raise the cross-over frequency and/or lower the number 379 of target bands per octave (or lower the sampling frequency) */ 380 } 381 382 /*Update stopFreq struct */ 383 if (stopFreq < 14) { 384 *k2 = getStopFreq(srCore, stopFreq); 385 } else if (stopFreq == 14) { 386 *k2 = 2 * *k0; 387 } else { 388 *k2 = 3 * *k0; 389 } 390 391 /* limit to Nyqvist */ 392 if (*k2 > noChannels) { 393 *k2 = noChannels; 394 } 395 396 /* Test for invalid k0 k2 combinations */ 397 if ((srCore == 22050) && ((*k2 - *k0) > MAX_FREQ_COEFFS_FS44100)) 398 return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for 399 fs=44.1kHz */ 400 401 if ((srCore >= 24000) && ((*k2 - *k0) > MAX_FREQ_COEFFS_FS48000)) 402 return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for 403 fs>=48kHz */ 404 405 if ((*k2 - *k0) > MAX_FREQ_COEFFS) 406 return (1); /*Number of bands exceeds valid range of MAX_FREQ_COEFFS */ 407 408 if ((*k2 - *k0) < 0) return (1); /* Number of bands is negative */ 409 410 return (0); 411} 412 413/******************************************************************************* 414 Functionname: FDKsbrEnc_UpdateFreqScale 415 ******************************************************************************* 416 Description: 417 418 Arguments: 419 420 Return: 421 *******************************************************************************/ 422INT FDKsbrEnc_UpdateFreqScale(UCHAR *v_k_master, INT *h_num_bands, const INT k0, 423 const INT k2, const INT freqScale, 424 const INT alterScale) 425 426{ 427 INT b_p_o = 0; /* bands_per_octave */ 428 FIXP_DBL warp = FL2FXCONST_DBL(0.0f); 429 INT dk = 0; 430 431 /* Internal variables */ 432 INT k1 = 0, i; 433 INT num_bands0; 434 INT num_bands1; 435 INT diff_tot[MAX_OCTAVE + MAX_SECOND_REGION]; 436 INT *diff0 = diff_tot; 437 INT *diff1 = diff_tot + MAX_OCTAVE; 438 INT k2_achived; 439 INT k2_diff; 440 INT incr = 0; 441 442 /* Init */ 443 if (freqScale == 1) b_p_o = 12; 444 if (freqScale == 2) b_p_o = 10; 445 if (freqScale == 3) b_p_o = 8; 446 447 if (freqScale > 0) /*Bark*/ 448 { 449 if (alterScale == 0) 450 warp = FL2FXCONST_DBL(0.5f); /* 1.0/(1.0*2.0) */ 451 else 452 warp = FL2FXCONST_DBL(1.0f / 2.6f); /* 1.0/(1.3*2.0); */ 453 454 if (4 * k2 >= 9 * k0) /*two or more regions (how many times the basis band 455 is copied)*/ 456 { 457 k1 = 2 * k0; 458 459 num_bands0 = numberOfBands(b_p_o, k0, k1, FL2FXCONST_DBL(0.5f)); 460 num_bands1 = numberOfBands(b_p_o, k1, k2, warp); 461 462 CalcBands(diff0, k0, k1, num_bands0); /*CalcBands1 => diff0 */ 463 FDKsbrEnc_Shellsort_int(diff0, num_bands0); /*SortBands sort diff0 */ 464 465 if (diff0[0] == 0) /* too wide FB bands for target tuning */ 466 { 467 return (1); /* raise the cross-over frequency and/or lower the number 468 of target bands per octave (or lower the sampling 469 frequency */ 470 } 471 472 cumSum(k0, diff0, num_bands0, v_k_master); /* cumsum */ 473 474 CalcBands(diff1, k1, k2, num_bands1); /* CalcBands2 => diff1 */ 475 FDKsbrEnc_Shellsort_int(diff1, num_bands1); /* SortBands sort diff1 */ 476 if (diff0[num_bands0 - 1] > diff1[0]) /* max(1) > min(2) */ 477 { 478 if (modifyBands(diff0[num_bands0 - 1], diff1, num_bands1)) return (1); 479 } 480 481 /* Add 2'nd region */ 482 cumSum(k1, diff1, num_bands1, &v_k_master[num_bands0]); 483 *h_num_bands = num_bands0 + num_bands1; /* Output nr of bands */ 484 485 } else /* one region */ 486 { 487 k1 = k2; 488 489 num_bands0 = numberOfBands(b_p_o, k0, k1, FL2FXCONST_DBL(0.5f)); 490 CalcBands(diff0, k0, k1, num_bands0); /* CalcBands1 => diff0 */ 491 FDKsbrEnc_Shellsort_int(diff0, num_bands0); /* SortBands sort diff0 */ 492 493 if (diff0[0] == 0) /* too wide FB bands for target tuning */ 494 { 495 return (1); /* raise the cross-over frequency and/or lower the number 496 of target bands per octave (or lower the sampling 497 frequency */ 498 } 499 500 cumSum(k0, diff0, num_bands0, v_k_master); /* cumsum */ 501 *h_num_bands = num_bands0; /* Output nr of bands */ 502 } 503 } else /* Linear mode */ 504 { 505 if (alterScale == 0) { 506 dk = 1; 507 num_bands0 = 2 * ((k2 - k0) / 2); /* FLOOR to get to few number of bands*/ 508 } else { 509 dk = 2; 510 num_bands0 = 511 2 * (((k2 - k0) / dk + 1) / 2); /* ROUND to get closest fit */ 512 } 513 514 k2_achived = k0 + num_bands0 * dk; 515 k2_diff = k2 - k2_achived; 516 517 for (i = 0; i < num_bands0; i++) diff_tot[i] = dk; 518 519 /* If linear scale wasn't achived */ 520 /* and we got wide SBR are */ 521 if (k2_diff < 0) { 522 incr = 1; 523 i = 0; 524 } 525 526 /* If linear scale wasn't achived */ 527 /* and we got small SBR are */ 528 if (k2_diff > 0) { 529 incr = -1; 530 i = num_bands0 - 1; 531 } 532 533 /* Adjust diff vector to get sepc. SBR range */ 534 while (k2_diff != 0) { 535 diff_tot[i] = diff_tot[i] - incr; 536 i = i + incr; 537 k2_diff = k2_diff + incr; 538 } 539 540 cumSum(k0, diff_tot, num_bands0, v_k_master); /* cumsum */ 541 *h_num_bands = num_bands0; /* Output nr of bands */ 542 } 543 544 if (*h_num_bands < 1) return (1); /*To small sbr area */ 545 546 return (0); 547} /* End FDKsbrEnc_UpdateFreqScale */ 548 549static INT numberOfBands(INT b_p_o, INT start, INT stop, FIXP_DBL warp_factor) { 550 INT result = 0; 551 /* result = 2* (INT) ( (double)b_p_o * 552 * (double)(FDKlog((double)stop/(double)start)/FDKlog((double)2)) * 553 * (double)FX_DBL2FL(warp_factor) + 0.5); */ 554 result = ((b_p_o * fMult((CalcLdInt(stop) - CalcLdInt(start)), warp_factor) + 555 (FL2FX_DBL(0.5f) >> LD_DATA_SHIFT)) >> 556 ((DFRACT_BITS - 1) - LD_DATA_SHIFT)) 557 << 1; /* do not optimize anymore (rounding!!) */ 558 559 return (result); 560} 561 562static void CalcBands(INT *diff, INT start, INT stop, INT num_bands) { 563 INT i, qb, qe, qtmp; 564 INT previous; 565 INT current; 566 FIXP_DBL base, exp, tmp; 567 568 previous = start; 569 for (i = 1; i <= num_bands; i++) { 570 base = fDivNorm((FIXP_DBL)stop, (FIXP_DBL)start, &qb); 571 exp = fDivNorm((FIXP_DBL)i, (FIXP_DBL)num_bands, &qe); 572 tmp = fPow(base, qb, exp, qe, &qtmp); 573 tmp = fMult(tmp, (FIXP_DBL)(start << 24)); 574 current = (INT)scaleValue(tmp, qtmp - 23); 575 current = (current + 1) >> 1; /* rounding*/ 576 diff[i - 1] = current - previous; 577 previous = current; 578 } 579 580} /* End CalcBands */ 581 582static void cumSum(INT start_value, INT *diff, INT length, 583 UCHAR *start_adress) { 584 INT i; 585 start_adress[0] = start_value; 586 for (i = 1; i <= length; i++) 587 start_adress[i] = start_adress[i - 1] + diff[i - 1]; 588} /* End cumSum */ 589 590static INT modifyBands(INT max_band_previous, INT *diff, INT length) { 591 INT change = max_band_previous - diff[0]; 592 593 /* Limit the change so that the last band cannot get narrower than the first 594 * one */ 595 if (change > (diff[length - 1] - diff[0]) / 2) 596 change = (diff[length - 1] - diff[0]) / 2; 597 598 diff[0] += change; 599 diff[length - 1] -= change; 600 FDKsbrEnc_Shellsort_int(diff, length); 601 602 return (0); 603} /* End modifyBands */ 604 605/******************************************************************************* 606 Functionname: FDKsbrEnc_UpdateHiRes 607 ******************************************************************************* 608 Description: 609 610 611 Arguments: 612 613 Return: 614 *******************************************************************************/ 615INT FDKsbrEnc_UpdateHiRes(UCHAR *h_hires, INT *num_hires, UCHAR *v_k_master, 616 INT num_master, INT *xover_band) { 617 INT i; 618 INT max1, max2; 619 620 if ((v_k_master[*xover_band] > 621 32) || /* v_k_master[*xover_band] > noQMFChannels(dualRate)/divider */ 622 (*xover_band > num_master)) { 623 /* xover_band error, too big for this startFreq. Will be clipped */ 624 625 /* Calculate maximum value for xover_band */ 626 max1 = 0; 627 max2 = num_master; 628 while ((v_k_master[max1 + 1] < 32) && /* noQMFChannels(dualRate)/divider */ 629 ((max1 + 1) < max2)) { 630 max1++; 631 } 632 633 *xover_band = max1; 634 } 635 636 *num_hires = num_master - *xover_band; 637 for (i = *xover_band; i <= num_master; i++) { 638 h_hires[i - *xover_band] = v_k_master[i]; 639 } 640 641 return (0); 642} /* End FDKsbrEnc_UpdateHiRes */ 643 644/******************************************************************************* 645 Functionname: FDKsbrEnc_UpdateLoRes 646 ******************************************************************************* 647 Description: 648 649 Arguments: 650 651 Return: 652 *******************************************************************************/ 653void FDKsbrEnc_UpdateLoRes(UCHAR *h_lores, INT *num_lores, UCHAR *h_hires, 654 INT num_hires) { 655 INT i; 656 657 if (num_hires % 2 == 0) /* if even number of hires bands */ 658 { 659 *num_lores = num_hires / 2; 660 /* Use every second lores=hires[0,2,4...] */ 661 for (i = 0; i <= *num_lores; i++) h_lores[i] = h_hires[i * 2]; 662 663 } else /* odd number of hires which means xover is odd */ 664 { 665 *num_lores = (num_hires + 1) / 2; 666 667 /* Use lores=hires[0,1,3,5 ...] */ 668 h_lores[0] = h_hires[0]; 669 for (i = 1; i <= *num_lores; i++) { 670 h_lores[i] = h_hires[i * 2 - 1]; 671 } 672 } 673 674} /* End FDKsbrEnc_UpdateLoRes */ 675