1 2 /* ----------------------------------------------------------------------------------------------------------- 3 Software License for The Fraunhofer FDK AAC Codec Library for Android 4 5 Copyright 1995 - 2012 Fraunhofer-Gesellschaft zur Frderung der angewandten Forschung e.V. 6 All rights reserved. 7 8 1. INTRODUCTION 9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements 10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. 11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices. 12 13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual 14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by 15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part 16 of the MPEG specifications. 17 18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) 19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners 20 individually for the purpose of encoding or decoding bit streams in products that are compliant with 21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license 22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec 23 software may already be covered under those patent licenses when it is used for those licensed purposes only. 24 25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, 26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional 27 applications information and documentation. 28 29 2. COPYRIGHT LICENSE 30 31 Redistribution and use in source and binary forms, with or without modification, are permitted without 32 payment of copyright license fees provided that you satisfy the following conditions: 33 34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or 35 your modifications thereto in source code form. 36 37 You must retain the complete text of this software license in the documentation and/or other materials 38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. 39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your 40 modifications thereto to recipients of copies in binary form. 41 42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without 43 prior written permission. 44 45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec 46 software or your modifications thereto. 47 48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software 49 and the date of any change. For modified versions of the FDK AAC Codec, the term 50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term 51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." 52 53 3. NO PATENT LICENSE 54 55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, 56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with 57 respect to this software. 58 59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized 60 by appropriate patent licenses. 61 62 4. DISCLAIMER 63 64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors 65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties 66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, 68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits, 69 or business interruption, however caused and on any theory of liability, whether in contract, strict 70 liability, or tort (including negligence), arising in any way out of the use of this software, even if 71 advised of the possibility of such damage. 72 73 5. CONTACT INFORMATION 74 75 Fraunhofer Institute for Integrated Circuits IIS 76 Attention: Audio and Multimedia Departments - FDK AAC LL 77 Am Wolfsmantel 33 78 91058 Erlangen, Germany 79 80 www.iis.fraunhofer.de/amm 81 amm-info (at) iis.fraunhofer.de 82 ----------------------------------------------------------------------------------------------------------- */ 83 84 #include "tran_det.h" 85 86 #include "fram_gen.h" 87 #include "sbr_ram.h" 88 #include "sbr_misc.h" 89 90 #include "genericStds.h" 91 92 #define NORM_QMF_ENERGY 5.684341886080801486968994140625e-14 /* 2^-44 */ 93 94 /* static FIXP_DBL ABS_THRES = fixMax( FL2FXCONST_DBL(1.28e5 * NORM_QMF_ENERGY), (FIXP_DBL)1) Minimum threshold for detecting changes */ 95 #define ABS_THRES ((FIXP_DBL)16) 96 97 /******************************************************************************* 98 Functionname: spectralChange 99 ******************************************************************************* 100 \brief Calculates a measure for the spectral change within the frame 101 102 The function says how good it would be to split the frame at the given border 103 position into 2 envelopes. 104 105 The return value delta_sum is scaled with the factor 1/64 106 107 \return calculated value 108 *******************************************************************************/ 109 static FIXP_DBL spectralChange(FIXP_DBL Energies[NUMBER_TIME_SLOTS_2304][MAX_FREQ_COEFFS], 110 INT *scaleEnergies, 111 FIXP_DBL EnergyTotal, 112 INT nSfb, 113 INT start, 114 INT border, 115 INT stop) 116 { 117 INT i,j; 118 INT len1,len2; 119 FIXP_DBL delta,tmp0,tmp1,tmp2; 120 FIXP_DBL accu1,accu2,delta_sum,result; 121 122 FDK_ASSERT(scaleEnergies[0] >= 0); 123 124 /* equal for aac (would be not equal for mp3) */ 125 len1 = border-start; 126 len2 = stop-border; 127 128 /* prefer borders near the middle of the frame */ 129 FIXP_DBL pos_weight; 130 pos_weight = FL2FXCONST_DBL(0.5f) - (len1*GetInvInt(len1+len2)); 131 pos_weight = /*FL2FXCONST_DBL(1.0)*/ (FIXP_DBL)MAXVAL_DBL - (fMult(pos_weight, pos_weight)<<2); 132 133 delta_sum = FL2FXCONST_DBL(0.0f); 134 135 /* Sum up energies of all QMF-timeslots for both halfs */ 136 for (j=0; j<nSfb; j++) { 137 #define NRG_SCALE 3 138 /* init with some energy to prevent division by zero 139 and to prevent splitting for very low levels */ 140 accu1 = ((FL2FXCONST_DBL((1.0e6*NORM_QMF_ENERGY*8.0/32))) << fixMin(scaleEnergies[0],25))>>NRG_SCALE; /* complex init for compare with original version */ 141 accu2 = ((FL2FXCONST_DBL((1.0e6*NORM_QMF_ENERGY*8.0/32))) << fixMin(scaleEnergies[0],25))>>NRG_SCALE; /* can be simplified in dsp implementation */ 142 143 /* Sum up energies in first half */ 144 for (i=start; i<border; i++) { 145 accu1 += (Energies[i][j]>>NRG_SCALE); 146 } 147 148 /* Sum up energies in second half */ 149 for (i=border; i<stop; i++) { 150 accu2 += (Energies[i][j]>>NRG_SCALE); 151 } 152 153 /* Energy change in current band */ 154 tmp0 = CalcLdData(accu2); 155 tmp1 = CalcLdData(accu1); 156 tmp2 = (tmp0 - tmp1 + CalcLdData(len1)-CalcLdData(len2)); 157 delta = fixp_abs(fMult(tmp2, FL2FXCONST_DBL(0.6931471806f))); 158 159 /* Weighting with amplitude ratio of this band */ 160 result = (EnergyTotal == FL2FXCONST_DBL(0.0f)) 161 ? FL2FXCONST_DBL(0.f) 162 : FDKsbrEnc_LSI_divide_scale_fract( (accu1+accu2), 163 (EnergyTotal>>NRG_SCALE)+(FIXP_DBL)1, 164 (FIXP_DBL)MAXVAL_DBL >> fixMin(scaleEnergies[0],(DFRACT_BITS-1)) ); 165 166 delta_sum += (FIXP_DBL)(fMult(sqrtFixp(result), delta)); 167 } 168 169 return fMult(delta_sum, pos_weight); 170 } 171 172 173 /******************************************************************************* 174 Functionname: addLowbandEnergies 175 ******************************************************************************* 176 \brief Calculates total lowband energy 177 178 The return value nrgTotal is scaled by the factor (1/32.0) 179 180 \return total energy in the lowband 181 *******************************************************************************/ 182 static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies, 183 int *scaleEnergies, 184 int YBufferWriteOffset, 185 int nrgSzShift, 186 int tran_off, 187 UCHAR *freqBandTable, 188 int slots) 189 { 190 FIXP_DBL nrgTotal; 191 FIXP_DBL accu1 = FL2FXCONST_DBL(0.0f); 192 FIXP_DBL accu2 = FL2FXCONST_DBL(0.0f); 193 int tran_offdiv2 = tran_off>>nrgSzShift; 194 int ts,k; 195 196 /* Sum up lowband energy from one frame at offset tran_off */ 197 for (ts=tran_offdiv2; ts<YBufferWriteOffset; ts++) { 198 for (k = 0; k < freqBandTable[0]; k++) { 199 accu1 += Energies[ts][k] >> 6; 200 } 201 } 202 for (; ts<tran_offdiv2+(slots>>nrgSzShift); ts++) { 203 for (k = 0; k < freqBandTable[0]; k++) { 204 accu2 += Energies[ts][k] >> 6; 205 } 206 } 207 208 nrgTotal = ( (accu1 >> fixMin(scaleEnergies[0],(DFRACT_BITS-1))) 209 + (accu2 >> fixMin(scaleEnergies[1],(DFRACT_BITS-1))) ) << (2); 210 211 return(nrgTotal); 212 } 213 214 215 /******************************************************************************* 216 Functionname: addHighbandEnergies 217 ******************************************************************************* 218 \brief Add highband energies 219 220 Highband energies are mapped to an array with smaller dimension: 221 Its time resolution is only 1 SBR-timeslot and its frequency resolution 222 is 1 SBR-band. Therefore the data to be fed into the spectralChange 223 function is reduced. 224 225 The values EnergiesM are scaled by the factor (1/32.0) and scaleEnergies[0] 226 The return value nrgTotal is scaled by the factor (1/32.0) 227 228 \return total energy in the highband 229 *******************************************************************************/ 230 231 static FIXP_DBL addHighbandEnergies(FIXP_DBL **RESTRICT Energies, /*!< input */ 232 INT *scaleEnergies, 233 FIXP_DBL EnergiesM[NUMBER_TIME_SLOTS_2304][MAX_FREQ_COEFFS], /*!< Combined output */ 234 UCHAR *RESTRICT freqBandTable, 235 INT nSfb, 236 INT sbrSlots, 237 INT timeStep) 238 { 239 INT i,j,k,slotIn,slotOut,scale; 240 INT li,ui; 241 FIXP_DBL nrgTotal; 242 FIXP_DBL accu = FL2FXCONST_DBL(0.0f); 243 244 /* Combine QMF-timeslots to SBR-timeslots, 245 combine QMF-bands to SBR-bands, 246 combine Left and Right channel */ 247 for (slotOut=0; slotOut<sbrSlots; slotOut++) { 248 slotIn = 2*slotOut; 249 250 for (j=0; j<nSfb; j++) { 251 accu = FL2FXCONST_DBL(0.0f); 252 253 li = freqBandTable[j]; 254 ui = freqBandTable[j + 1]; 255 256 for (k=li; k<ui; k++) { 257 for (i=0; i<timeStep; i++) { 258 accu += (Energies[(slotIn+i)>>1][k] >> 5); 259 } 260 } 261 EnergiesM[slotOut][j] = accu; 262 } 263 } 264 265 scale = fixMin(8,scaleEnergies[0]); /* scale energies down before add up */ 266 267 if ((scaleEnergies[0]-1) > (DFRACT_BITS-1) ) 268 nrgTotal = FL2FXCONST_DBL(0.0f); 269 else { 270 /* Now add all energies */ 271 accu = FL2FXCONST_DBL(0.0f); 272 for (slotOut=0; slotOut<sbrSlots; slotOut++) { 273 for (j=0; j<nSfb; j++) { 274 accu += (EnergiesM[slotOut][j] >> scale); 275 } 276 } 277 nrgTotal = accu >> (scaleEnergies[0]-scale); 278 } 279 280 return(nrgTotal); 281 } 282 283 284 /******************************************************************************* 285 Functionname: FDKsbrEnc_frameSplitter 286 ******************************************************************************* 287 \brief Decides if a FIXFIX-frame shall be splitted into 2 envelopes 288 289 If no transient has been detected before, the frame can still be splitted 290 into 2 envelopes. 291 *******************************************************************************/ 292 void 293 FDKsbrEnc_frameSplitter(FIXP_DBL **Energies, 294 INT *scaleEnergies, 295 HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector, 296 UCHAR *freqBandTable, 297 UCHAR *tran_vector, 298 int YBufferWriteOffset, 299 int YBufferSzShift, 300 int nSfb, 301 int timeStep, 302 int no_cols) 303 { 304 if (tran_vector[1]==0) /* no transient was detected */ 305 { 306 FIXP_DBL delta; 307 FIXP_DBL EnergiesM[NUMBER_TIME_SLOTS_2304][MAX_FREQ_COEFFS]; 308 FIXP_DBL EnergyTotal,newLowbandEnergy,newHighbandEnergy; 309 INT border; 310 INT sbrSlots = fMultI(GetInvInt(timeStep),no_cols); 311 312 FDK_ASSERT( sbrSlots * timeStep == no_cols ); 313 314 /* 315 Get Lowband-energy over a range of 2 frames (Look half a frame back and ahead). 316 */ 317 newLowbandEnergy = addLowbandEnergies(Energies, 318 scaleEnergies, 319 YBufferWriteOffset, 320 YBufferSzShift, 321 h_sbrTransientDetector->tran_off, 322 freqBandTable, 323 no_cols); 324 325 newHighbandEnergy = addHighbandEnergies(Energies, 326 scaleEnergies, 327 EnergiesM, 328 freqBandTable, 329 nSfb, 330 sbrSlots, 331 timeStep); 332 333 if ( h_sbrTransientDetector->frameShift != 0 ) { 334 if (tran_vector[1]==0) 335 tran_vector[0] = 0; 336 } else 337 { 338 /* prevLowBandEnergy: Corresponds to 1 frame, starting with half a frame look-behind 339 newLowbandEnergy: Corresponds to 1 frame, starting in the middle of the current frame */ 340 EnergyTotal = (newLowbandEnergy + h_sbrTransientDetector->prevLowBandEnergy) >> 1; 341 EnergyTotal += newHighbandEnergy; 342 /* The below border should specify the same position as the middle border 343 of a FIXFIX-frame with 2 envelopes. */ 344 border = (sbrSlots+1) >> 1; 345 346 delta = spectralChange(EnergiesM, 347 scaleEnergies, 348 EnergyTotal, 349 nSfb, 350 0, 351 border, 352 sbrSlots); 353 354 if (delta > (h_sbrTransientDetector->split_thr >> LD_DATA_SHIFT)) /* delta scaled by 1/64 */ 355 tran_vector[0] = 1; /* Set flag for splitting */ 356 else 357 tran_vector[0] = 0; 358 } 359 360 /* Update prevLowBandEnergy */ 361 h_sbrTransientDetector->prevLowBandEnergy = newLowbandEnergy; 362 h_sbrTransientDetector->prevHighBandEnergy = newHighbandEnergy; 363 } 364 } 365 366 /* 367 * Calculate transient energy threshold for each QMF band 368 */ 369 static void 370 calculateThresholds(FIXP_DBL **RESTRICT Energies, 371 INT *RESTRICT scaleEnergies, 372 FIXP_DBL *RESTRICT thresholds, 373 int YBufferWriteOffset, 374 int YBufferSzShift, 375 int noCols, 376 int noRows, 377 int tran_off) 378 { 379 FIXP_DBL mean_val,std_val,temp; 380 FIXP_DBL i_noCols; 381 FIXP_DBL i_noCols1; 382 FIXP_DBL accu,accu0,accu1; 383 int scaleFactor0,scaleFactor1,commonScale; 384 int i,j; 385 386 i_noCols = GetInvInt(noCols + tran_off ) << YBufferSzShift; 387 i_noCols1 = GetInvInt(noCols + tran_off - 1) << YBufferSzShift; 388 389 /* calc minimum scale of energies of previous and current frame */ 390 commonScale = fixMin(scaleEnergies[0],scaleEnergies[1]); 391 392 /* calc scalefactors to adapt energies to common scale */ 393 scaleFactor0 = fixMin((scaleEnergies[0]-commonScale), (DFRACT_BITS-1)); 394 scaleFactor1 = fixMin((scaleEnergies[1]-commonScale), (DFRACT_BITS-1)); 395 396 FDK_ASSERT((scaleFactor0 >= 0) && (scaleFactor1 >= 0)); 397 398 /* calculate standard deviation in every subband */ 399 for (i=0; i<noRows; i++) 400 { 401 int startEnergy = (tran_off>>YBufferSzShift); 402 int endEnergy = ((noCols>>YBufferSzShift)+tran_off); 403 int shift; 404 405 /* calculate mean value over decimated energy values (downsampled by 2). */ 406 accu0 = accu1 = FL2FXCONST_DBL(0.0f); 407 408 for (j=startEnergy; j<YBufferWriteOffset; j++) 409 accu0 += fMult(Energies[j][i], i_noCols); 410 for (; j<endEnergy; j++) 411 accu1 += fMult(Energies[j][i], i_noCols); 412 413 mean_val = (accu0 >> scaleFactor0) + (accu1 >> scaleFactor1); /* average */ 414 shift = fixMax(0,CountLeadingBits(mean_val)-6); /* -6 to keep room for accumulating upto N = 24 values */ 415 416 /* calculate standard deviation */ 417 accu = FL2FXCONST_DBL(0.0f); 418 419 /* summe { ((mean_val-nrg)^2) * i_noCols1 } */ 420 for (j=startEnergy; j<YBufferWriteOffset; j++) { 421 temp = ((FIXP_DBL)mean_val - ((FIXP_DBL)Energies[j][i] >> scaleFactor0))<<shift; 422 temp = fPow2(temp); 423 temp = fMult(temp, i_noCols1); 424 accu += temp; 425 } 426 for (; j<endEnergy; j++) { 427 temp = ((FIXP_DBL)mean_val - ((FIXP_DBL)Energies[j][i] >> scaleFactor1))<<shift; 428 temp = fPow2(temp); 429 temp = fMult(temp, i_noCols1); 430 accu += temp; 431 } 432 433 std_val = sqrtFixp(accu)>>shift; /* standard deviation */ 434 435 /* 436 Take new threshold as average of calculated standard deviation ratio 437 and old threshold if greater than absolute threshold 438 */ 439 temp = ( commonScale<=(DFRACT_BITS-1) ) 440 ? fMult(FL2FXCONST_DBL(0.66f), thresholds[i]) + (fMult(FL2FXCONST_DBL(0.34f), std_val) >> commonScale) 441 : (FIXP_DBL) 0; 442 443 thresholds[i] = fixMax(ABS_THRES,temp); 444 445 FDK_ASSERT(commonScale >= 0); 446 } 447 } 448 449 /* 450 * Calculate transient levels for each QMF time slot. 451 */ 452 static void 453 extractTransientCandidates(FIXP_DBL **RESTRICT Energies, 454 INT *RESTRICT scaleEnergies, 455 FIXP_DBL *RESTRICT thresholds, 456 FIXP_DBL *RESTRICT transients, 457 int YBufferWriteOffset, 458 int YBufferSzShift, 459 int noCols, 460 int start_band, 461 int stop_band, 462 int tran_off, 463 int addPrevSamples) 464 { 465 FIXP_DBL i_thres; 466 C_ALLOC_SCRATCH_START(EnergiesTemp, FIXP_DBL, 2*QMF_MAX_TIME_SLOTS); 467 FIXP_DBL *RESTRICT pEnergiesTemp = EnergiesTemp; 468 int tmpScaleEnergies0, tmpScaleEnergies1; 469 int endCond; 470 int startEnerg,endEnerg; 471 int i,j,jIndex,jpBM; 472 473 tmpScaleEnergies0 = scaleEnergies[0]; 474 tmpScaleEnergies1 = scaleEnergies[1]; 475 476 /* Scale value for first energies, upto YBufferWriteOffset */ 477 tmpScaleEnergies0 = fixMin(tmpScaleEnergies0, MAX_SHIFT_DBL); 478 /* Scale value for first energies, from YBufferWriteOffset upwards */ 479 tmpScaleEnergies1 = fixMin(tmpScaleEnergies1, MAX_SHIFT_DBL); 480 481 FDK_ASSERT((tmpScaleEnergies0 >= 0) && (tmpScaleEnergies1 >= 0)); 482 483 /* Keep addPrevSamples extra previous transient candidates. */ 484 FDKmemmove(transients, transients + noCols - addPrevSamples, (tran_off+addPrevSamples) * sizeof (FIXP_DBL)); 485 FDKmemclear(transients + tran_off + addPrevSamples, noCols * sizeof (FIXP_DBL)); 486 487 endCond = noCols; /* Amount of new transient values to be calculated. */ 488 startEnerg = (tran_off-3)>>YBufferSzShift; /* >>YBufferSzShift because of amount of energy values. -3 because of neighbors being watched. */ 489 endEnerg = ((noCols+ (YBufferWriteOffset<<YBufferSzShift))-1)>>YBufferSzShift; /* YBufferSzShift shifts because of half energy values. */ 490 491 /* Compute differential values with two different weightings in every subband */ 492 for (i=start_band; i<stop_band; i++) 493 { 494 FIXP_DBL thres = thresholds[i]; 495 496 if((LONG)thresholds[i]>=256) 497 i_thres = (LONG)( (LONG)MAXVAL_DBL / ((((LONG)thresholds[i]))+1) )<<(32-24); 498 else 499 i_thres = (LONG)MAXVAL_DBL; 500 501 /* Copy one timeslot and de-scale and de-squish */ 502 if (YBufferSzShift == 1) { 503 for(j=startEnerg; j<YBufferWriteOffset; j++) { 504 FIXP_DBL tmp = Energies[j][i]; 505 EnergiesTemp[(j<<1)+1] = EnergiesTemp[j<<1] = tmp>>tmpScaleEnergies0; 506 } 507 for(; j<=endEnerg; j++) { 508 FIXP_DBL tmp = Energies[j][i]; 509 EnergiesTemp[(j<<1)+1] = EnergiesTemp[j<<1] = tmp>>tmpScaleEnergies1; 510 } 511 } else { 512 for(j=startEnerg; j<YBufferWriteOffset; j++) { 513 FIXP_DBL tmp = Energies[j][i]; 514 EnergiesTemp[j] = tmp>>tmpScaleEnergies0; 515 } 516 for(; j<=endEnerg; j++) { 517 FIXP_DBL tmp = Energies[j][i]; 518 EnergiesTemp[j] = tmp>>tmpScaleEnergies1; 519 } 520 } 521 522 /* Detect peaks in energy values. */ 523 524 jIndex = tran_off; 525 jpBM = jIndex+addPrevSamples; 526 527 for (j=endCond; j--; jIndex++, jpBM++) 528 { 529 530 FIXP_DBL delta, tran; 531 int d; 532 533 delta = (FIXP_DBL)0; 534 tran = (FIXP_DBL)0; 535 536 for (d=1; d<4; d++) { 537 delta += pEnergiesTemp[jIndex+d]; /* R */ 538 delta -= pEnergiesTemp[jIndex-d]; /* L */ 539 delta -= thres; 540 541 if ( delta > (FIXP_DBL)0 ) { 542 tran += fMult(i_thres, delta); 543 } 544 } 545 transients[jpBM] += tran; 546 } 547 } 548 C_ALLOC_SCRATCH_END(EnergiesTemp, FIXP_DBL, 2*QMF_MAX_TIME_SLOTS); 549 } 550 551 void 552 FDKsbrEnc_transientDetect(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTran, 553 FIXP_DBL **Energies, 554 INT *scaleEnergies, 555 UCHAR *transient_info, 556 int YBufferWriteOffset, 557 int YBufferSzShift, 558 int timeStep, 559 int frameMiddleBorder) 560 { 561 int no_cols = h_sbrTran->no_cols; 562 int qmfStartSample; 563 int addPrevSamples; 564 int timeStepShift=0; 565 int i, cond; 566 567 /* Where to start looking for transients in the transient candidate buffer */ 568 qmfStartSample = timeStep * frameMiddleBorder; 569 /* We need to look one value backwards in the transients, so we might need one more previous value. */ 570 addPrevSamples = (qmfStartSample > 0) ? 0: 1; 571 572 switch (timeStep) { 573 case 1: timeStepShift = 0; break; 574 case 2: timeStepShift = 1; break; 575 case 4: timeStepShift = 2; break; 576 } 577 578 calculateThresholds(Energies, 579 scaleEnergies, 580 h_sbrTran->thresholds, 581 YBufferWriteOffset, 582 YBufferSzShift, 583 h_sbrTran->no_cols, 584 h_sbrTran->no_rows, 585 h_sbrTran->tran_off); 586 587 extractTransientCandidates(Energies, 588 scaleEnergies, 589 h_sbrTran->thresholds, 590 h_sbrTran->transients, 591 YBufferWriteOffset, 592 YBufferSzShift, 593 h_sbrTran->no_cols, 594 0, 595 h_sbrTran->no_rows, 596 h_sbrTran->tran_off, 597 addPrevSamples ); 598 599 transient_info[0] = 0; 600 transient_info[1] = 0; 601 transient_info[2] = 0; 602 603 /* Offset by the amount of additional previous transient candidates being kept. */ 604 qmfStartSample += addPrevSamples; 605 606 /* Check for transients in second granule (pick the last value of subsequent values) */ 607 for (i=qmfStartSample; i<qmfStartSample + no_cols; i++) { 608 cond = (h_sbrTran->transients[i] < fMult(FL2FXCONST_DBL(0.9f), h_sbrTran->transients[i - 1]) ) 609 && (h_sbrTran->transients[i - 1] > h_sbrTran->tran_thr); 610 611 if (cond) { 612 transient_info[0] = (i - qmfStartSample)>>timeStepShift; 613 transient_info[1] = 1; 614 break; 615 } 616 } 617 618 if ( h_sbrTran->frameShift != 0) { 619 /* transient prediction for LDSBR */ 620 /* Check for transients in first <frameShift> qmf-slots of second frame */ 621 for (i=qmfStartSample+no_cols; i<qmfStartSample + no_cols+h_sbrTran->frameShift; i++) { 622 623 cond = (h_sbrTran->transients[i] < fMult(FL2FXCONST_DBL(0.9f), h_sbrTran->transients[i - 1]) ) 624 && (h_sbrTran->transients[i - 1] > h_sbrTran->tran_thr); 625 626 if (cond) { 627 int pos = (int) ( (i - qmfStartSample-no_cols) >> timeStepShift ); 628 if ((pos < 3) && (transient_info[1]==0)) { 629 transient_info[2] = 1; 630 } 631 break; 632 } 633 } 634 } 635 } 636 637 int 638 FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector, 639 INT frameSize, 640 INT sampleFreq, 641 sbrConfigurationPtr params, 642 int tran_fc, 643 int no_cols, 644 int no_rows, 645 int YBufferWriteOffset, 646 int YBufferSzShift, 647 int frameShift, 648 int tran_off) 649 { 650 INT totalBitrate = params->codecSettings.standardBitrate * params->codecSettings.nChannels; 651 INT codecBitrate = params->codecSettings.bitRate; 652 FIXP_DBL bitrateFactor_fix, framedur_fix; 653 INT scale_0, scale_1; 654 655 FDKmemclear(h_sbrTransientDetector,sizeof(SBR_TRANSIENT_DETECTOR)); 656 657 h_sbrTransientDetector->frameShift = frameShift; 658 h_sbrTransientDetector->tran_off = tran_off; 659 660 if(codecBitrate) { 661 bitrateFactor_fix = fDivNorm((FIXP_DBL)totalBitrate, (FIXP_DBL)(codecBitrate<<2),&scale_0); 662 } 663 else { 664 bitrateFactor_fix = FL2FXCONST_DBL(1.0/4.0); 665 scale_0 = 0; 666 } 667 668 framedur_fix = fDivNorm(frameSize, sampleFreq); 669 670 /* The longer the frames, the more often should the FIXFIX- 671 case transmit 2 envelopes instead of 1. 672 Frame durations below 10 ms produce the highest threshold 673 so that practically always only 1 env is transmitted. */ 674 FIXP_DBL tmp = framedur_fix - FL2FXCONST_DBL(0.010); 675 676 tmp = fixMax(tmp, FL2FXCONST_DBL(0.0001)); 677 tmp = fDivNorm(FL2FXCONST_DBL(0.000075), fPow2(tmp), &scale_1); 678 679 scale_1 = -(scale_1 + scale_0 + 2); 680 681 FDK_ASSERT(no_cols <= QMF_MAX_TIME_SLOTS); 682 FDK_ASSERT(no_rows <= QMF_CHANNELS); 683 684 h_sbrTransientDetector->no_cols = no_cols; 685 h_sbrTransientDetector->tran_thr = (FIXP_DBL)((params->tran_thr << (32-24-1)) / no_rows); 686 h_sbrTransientDetector->tran_fc = tran_fc; 687 688 if (scale_1>=0) { 689 h_sbrTransientDetector->split_thr = fMult(tmp, bitrateFactor_fix) >> scale_1; 690 } 691 else { 692 h_sbrTransientDetector->split_thr = fMult(tmp, bitrateFactor_fix) << (-scale_1); 693 } 694 695 h_sbrTransientDetector->no_rows = no_rows; 696 h_sbrTransientDetector->mode = params->tran_det_mode; 697 h_sbrTransientDetector->prevLowBandEnergy = FL2FXCONST_DBL(0.0f); 698 699 return (0); 700 } 701 702