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_envelope_unmapping.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 38 ------------------------------------------------------------------------------ 39 REQUIREMENTS 40 41 42 ------------------------------------------------------------------------------ 43 REFERENCES 44 45 SC 29 Software Copyright Licencing Disclaimer: 46 47 This software module was originally developed by 48 Coding Technologies 49 50 and edited by 51 - 52 53 in the course of development of the ISO/IEC 13818-7 and ISO/IEC 14496-3 54 standards for reference purposes and its performance may not have been 55 optimized. This software module is an implementation of one or more tools as 56 specified by the ISO/IEC 13818-7 and ISO/IEC 14496-3 standards. 57 ISO/IEC gives users free license to this software module or modifications 58 thereof for use in products claiming conformance to audiovisual and 59 image-coding related ITU Recommendations and/or ISO/IEC International 60 Standards. ISO/IEC gives users the same free license to this software module or 61 modifications thereof for research purposes and further ISO/IEC standardisation. 62 Those intending to use this software module in products are advised that its 63 use may infringe existing patents. ISO/IEC have no liability for use of this 64 software module or modifications thereof. Copyright is not released for 65 products that do not conform to audiovisual and image-coding related ITU 66 Recommendations and/or ISO/IEC International Standards. 67 The original developer retains full right to modify and use the code for its 68 own purpose, assign or donate the code to a third party and to inhibit third 69 parties from using the code for products that do not conform to audiovisual and 70 image-coding related ITU Recommendations and/or ISO/IEC International Standards. 71 This copyright notice must be included in all copies or derivative works. 72 Copyright (c) ISO/IEC 2002. 73 74 ------------------------------------------------------------------------------ 75 PSEUDO-CODE 76 77 ------------------------------------------------------------------------------ 78 */ 79 80 81 /*---------------------------------------------------------------------------- 82 ; INCLUDES 83 ----------------------------------------------------------------------------*/ 84 85 #ifdef AAC_PLUS 86 87 88 #include "sbr_envelope_unmapping.h" 89 #include "sbr_constants.h" 90 91 #include "fxp_mul32.h" 92 93 /*---------------------------------------------------------------------------- 94 ; MACROS 95 ; Define module specific macros here 96 ----------------------------------------------------------------------------*/ 97 98 99 /*---------------------------------------------------------------------------- 100 ; DEFINES 101 ; Include all pre-processor statements here. Include conditional 102 ; compile variables also. 103 ----------------------------------------------------------------------------*/ 104 105 /*---------------------------------------------------------------------------- 106 ; LOCAL FUNCTION DEFINITIONS 107 ; Function Prototype declaration 108 ----------------------------------------------------------------------------*/ 109 110 /*---------------------------------------------------------------------------- 111 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS 112 ; Variable declaration - defined here and used outside this module 113 ----------------------------------------------------------------------------*/ 114 115 #define R_SHIFT 30 116 #define Qfmt(x) (Int32)(x*((Int32)1<<R_SHIFT) + (x>=0?0.5F:-0.5F)) 117 118 /* 119 * 1./(1+2.^-[0:10]) 120 */ 121 const Int32 one_over_one_plus_two_to_n[11] = 122 { 123 Qfmt(0.50000000000000F), Qfmt(0.66666666666667F), Qfmt(0.80000000000000F), 124 Qfmt(0.88888888888889F), Qfmt(0.94117647058824F), Qfmt(0.96969696969697F), 125 Qfmt(0.98461538461538F), Qfmt(0.99224806201550F), Qfmt(0.99610894941634F), 126 Qfmt(0.99805068226121F), Qfmt(0.99902439024390F) 127 }; 128 129 /* 130 * 1./(1+2.^[0.5:-1:-10.5]) 131 */ 132 const Int32 one_over_one_plus_sq_2_by_two_to_n[12] = 133 { 134 Qfmt(0.41421356237310F), Qfmt(0.58578643762690F), Qfmt(0.73879612503626F), 135 Qfmt(0.84977889517767F), Qfmt(0.91878969685839F), Qfmt(0.95767628767521F), 136 Qfmt(0.97838063800882F), Qfmt(0.98907219289563F), Qfmt(0.99450607818892F), 137 Qfmt(0.99724547251514F), Qfmt(0.99862083678608F), Qfmt(0.99930994254211F) 138 }; 139 140 /*---------------------------------------------------------------------------- 141 ; EXTERNAL FUNCTION REFERENCES 142 ; Declare functions defined elsewhere and referenced in this module 143 ----------------------------------------------------------------------------*/ 144 145 /*---------------------------------------------------------------------------- 146 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 147 ; Declare variables used in this module but defined elsewhere 148 ----------------------------------------------------------------------------*/ 149 150 /*---------------------------------------------------------------------------- 151 ; FUNCTION CODE 152 ----------------------------------------------------------------------------*/ 153 154 void sbr_envelope_unmapping(SBR_FRAME_DATA * hFrameData1, 155 SBR_FRAME_DATA * hFrameData2) 156 157 { 158 Int32 i; 159 Int32 tempLeft; 160 Int32 tempRight; 161 162 Int32 tmp; 163 Int32 *iEnvelopeLeft_man = hFrameData1->iEnvelope_man; 164 Int32 *iEnvelopeLeft_exp = hFrameData1->iEnvelope_exp; 165 Int32 *noiseFloorLeft_man = hFrameData1->sbrNoiseFloorLevel_man; 166 Int32 *noiseFloorLeft_exp = hFrameData1->sbrNoiseFloorLevel_exp; 167 168 Int32 *iEnvelopeRight_man = hFrameData2->iEnvelope_man; 169 Int32 *iEnvelopeRight_exp = hFrameData2->iEnvelope_exp; 170 Int32 *noiseFloorRight_man = hFrameData2->sbrNoiseFloorLevel_man; 171 Int32 *noiseFloorRight_exp = hFrameData2->sbrNoiseFloorLevel_exp; 172 173 174 if (hFrameData2->ampRes) 175 { 176 for (i = 0; i < hFrameData1->nScaleFactors; i++) 177 { 178 tempRight = iEnvelopeRight_man[i]; 179 tempLeft = iEnvelopeLeft_man[i]; 180 /* iEnvelope[i] always positive 6 bits max */ 181 182 iEnvelopeLeft_exp[i] = tempLeft + 7; 183 184 iEnvelopeRight_exp[i] = tempRight - 12; 185 iEnvelopeRight_man[i] = Qfmt(1.000F); 186 187 /* 188 * iEnvelopeRight[i] = tempLeft / (1 + tempRight); 189 * iEnvelopeLeft[i] = tempRight * iEnvelopeRight[i]; 190 * 191 * 192 * iEnvelopeRight[i] = k*2^n/(1+2^m) = k*2^(n-m)/(1 + 2^-m); 193 * where k = 1 or sqrt(2) 194 */ 195 if (iEnvelopeRight_exp[i] >= 0) 196 { 197 if (iEnvelopeRight_exp[i] < 11) 198 { 199 iEnvelopeRight_man[i] = one_over_one_plus_two_to_n[ iEnvelopeRight_exp[i]]; 200 } 201 else /* 1/(1+2^-m) == 1 - 2^-m ; for m >= 10 */ 202 { 203 iEnvelopeRight_man[i] -= (Qfmt(1.000F) >> iEnvelopeRight_exp[i]); 204 } 205 iEnvelopeRight_exp[i] = iEnvelopeLeft_exp[i] - iEnvelopeRight_exp[i]; 206 } 207 else 208 { 209 if (iEnvelopeRight_exp[i] > -11) 210 { 211 iEnvelopeRight_man[i] -= one_over_one_plus_two_to_n[ -iEnvelopeRight_exp[i]]; 212 iEnvelopeRight_exp[i] = iEnvelopeLeft_exp[i] - iEnvelopeRight_exp[i]; 213 214 } 215 else /* 1/(1+2^m) == 2^-m ; for m >= 10 */ 216 { 217 iEnvelopeRight_exp[i] = iEnvelopeLeft_exp[i]; 218 iEnvelopeLeft_exp[i] = 0; 219 } 220 } 221 222 iEnvelopeLeft_man[i] = iEnvelopeRight_man[i]; 223 } 224 } 225 else 226 { 227 for (i = 0; i < hFrameData1->nScaleFactors; i++) 228 { 229 /* iEnvelope[i] always positive 7 bits max */ 230 tempRight = iEnvelopeRight_man[i]; 231 tempLeft = iEnvelopeLeft_man[i]; 232 233 iEnvelopeLeft_exp[i] = (tempLeft >> 1) + 7; 234 if (tempLeft & 0x1) /* odd */ 235 { 236 iEnvelopeLeft_man[i] = Qfmt(1.41421356237310F); 237 } 238 else 239 { 240 iEnvelopeLeft_man[i] = Qfmt(1.000F); 241 } 242 243 iEnvelopeRight_exp[i] = (tempRight >> 1) - 12; 244 if (tempRight & 0x1) /* odd */ 245 { 246 if (iEnvelopeRight_exp[i] > 0) 247 { 248 iEnvelopeRight_man[i] = Qfmt(1.41421356237310F); 249 } 250 else 251 { 252 iEnvelopeRight_man[i] = Qfmt(0.7071067811865F); 253 } 254 } 255 else 256 { 257 iEnvelopeRight_man[i] = Qfmt(1.000F); 258 } 259 260 if (iEnvelopeRight_man[i] == Qfmt(1.000F)) 261 { 262 263 /* 264 * iEnvelopeRight[i] = tempLeft / (1 + tempRight); 265 * iEnvelopeLeft[i] = tempRight * iEnvelopeRight[i]; 266 * 267 * 268 * iEnvelopeRight[i] = k*2^n/(1+2^m) = k*2^(n-m)/(1 + 2^-m); 269 * where k = 1 or sqrt(2) 270 */ 271 if (iEnvelopeRight_exp[i] >= 0) 272 { 273 if (iEnvelopeRight_exp[i] < 11) 274 { 275 iEnvelopeRight_man[i] = one_over_one_plus_two_to_n[ iEnvelopeRight_exp[i]]; 276 } 277 else /* 1/(1+2^-m) == 1 - 2^-m ; for m >= 10 */ 278 { 279 iEnvelopeRight_man[i] -= (Qfmt(1.000F) >> iEnvelopeRight_exp[i]); 280 } 281 iEnvelopeRight_exp[i] = iEnvelopeLeft_exp[i] - iEnvelopeRight_exp[i]; 282 283 } 284 else 285 { 286 if (iEnvelopeRight_exp[i] > -11) 287 { 288 iEnvelopeRight_man[i] -= one_over_one_plus_two_to_n[ -iEnvelopeRight_exp[i]]; 289 iEnvelopeRight_exp[i] = iEnvelopeLeft_exp[i] - iEnvelopeRight_exp[i]; 290 } 291 else /* 1/(1+2^m) == 2^-m ; for m >= 10 */ 292 { 293 iEnvelopeRight_exp[i] = iEnvelopeLeft_exp[i]; 294 iEnvelopeLeft_exp[i] = 0; 295 } 296 } 297 298 /* 299 * apply "k" factor 1 or sqrt(2) 300 * 301 * (2^m)*2*k*2^n/(1+2^m) = k*2^(n+1)/(1 + 2^-m); 302 * 303 */ 304 if (iEnvelopeLeft_man[i] != Qfmt(1.000F)) 305 { 306 iEnvelopeRight_man[i] = fxp_mul32_Q30(iEnvelopeLeft_man[i], iEnvelopeRight_man[i]); 307 } 308 309 iEnvelopeLeft_man[i] = iEnvelopeRight_man[i]; 310 311 } 312 else 313 { 314 315 /* 316 * iEnvelopeRight[i] = tempLeft / (1 + tempRight); 317 * iEnvelopeLeft[i] = tempRight * iEnvelopeRight[i]; 318 * 319 * 320 * iEnvelopeRight[i] = k*2^n/(1+q2^m) = k*2^(n-m)/(1 + q2^-m); 321 * where k = 1 or sqrt(2) 322 * and q = sqrt(2) 323 */ 324 if (iEnvelopeRight_exp[i] >= 0) 325 { 326 if (iEnvelopeRight_exp[i] < 12) 327 { 328 iEnvelopeRight_man[i] = one_over_one_plus_sq_2_by_two_to_n[ iEnvelopeRight_exp[i]]; 329 } 330 else /* 1/(1+2^-m) == 1 - 2^-m ; for m >= 11 */ 331 { 332 iEnvelopeRight_man[i] = Qfmt(1.000F) - (Qfmt(1.000F) >> iEnvelopeRight_exp[i]); 333 } 334 } 335 else 336 { 337 if (iEnvelopeRight_exp[i] > -12) 338 { 339 iEnvelopeRight_man[i] = Qfmt(1.000F) - one_over_one_plus_sq_2_by_two_to_n[ -iEnvelopeRight_exp[i]]; 340 } 341 else /* 1/(1+2^m) == 2^-m ; for m >= 11 */ 342 { 343 iEnvelopeRight_man[i] = Qfmt(1.000F); 344 iEnvelopeRight_exp[i] = 0; 345 } 346 } 347 348 iEnvelopeRight_exp[i] = iEnvelopeLeft_exp[i] - iEnvelopeRight_exp[i]; 349 350 /* 351 * apply "k" factor 1 or sqrt(2) 352 * 353 * Right == k*2^(n-m)/(1 + q2^-m) 354 * Left == (q2^m)*k*2^n/(1 + q2^m) = qk*2^n/(1 + q2^-m); 355 */ 356 if (iEnvelopeLeft_man[i] != Qfmt(1.000F)) 357 { 358 /* 359 * k/(1 + q2^-m); 360 */ 361 tmp = iEnvelopeRight_man[i]; 362 iEnvelopeRight_man[i] = fxp_mul32_Q30(iEnvelopeLeft_man[i], iEnvelopeRight_man[i]); 363 iEnvelopeLeft_man[i] = tmp; 364 iEnvelopeLeft_exp[i] += 1; /* extra one due to sqrt(2)^2 */ 365 } 366 else 367 { 368 iEnvelopeLeft_man[i] = fxp_mul32_Q30(iEnvelopeRight_man[i], Qfmt(1.41421356237310F)); 369 } 370 371 } /* end of if (iEnvelopeRight_man[i] == Qfmt( 1.000F) ) */ 372 } /* end of for loop */ 373 } /* end if (hFrameData2->ampRes) */ 374 375 376 for (i = 0; i < hFrameData1->nNoiseFactors; i++) 377 { 378 379 noiseFloorLeft_exp[i] = NOISE_FLOOR_OFFSET_PLUS_1 - noiseFloorLeft_man[i]; 380 noiseFloorRight_exp[i] = noiseFloorRight_man[i] - SBR_ENERGY_PAN_OFFSET_INT; 381 382 383 /* 384 * noiseFloorRight[i] = tempLeft / (1.0f + tempRight); 385 * noiseFloorLeft[i] = tempRight*noiseFloorRight[i]; 386 * 387 * 388 * noiseFloorRight[i] = 2^n/(1+2^m) = 2^(n-m)/(1 + 2^-m); 389 */ 390 if (noiseFloorRight_exp[i] >= 0) 391 { 392 if (noiseFloorRight_exp[i] < 11) 393 { 394 noiseFloorRight_man[i] = one_over_one_plus_two_to_n[ noiseFloorRight_exp[i]]; 395 } 396 else /* 1/(1+2^-m) == 1 - 2^-m ; for m >= 10 */ 397 { 398 noiseFloorRight_man[i] = Qfmt(1.000F) - (Qfmt(1.000F) >> noiseFloorRight_exp[i]); 399 } 400 } 401 else 402 { 403 if (noiseFloorRight_exp[i] > -11) 404 { 405 noiseFloorRight_man[i] = Qfmt(1.000F) - one_over_one_plus_two_to_n[ -noiseFloorRight_exp[i]]; 406 } 407 else /* 1/(1+2^m) == 2^-m ; for m >= 10 */ 408 { 409 noiseFloorRight_man[i] = Qfmt(1.000F); 410 noiseFloorRight_exp[i] = 0; 411 } 412 } 413 414 noiseFloorRight_exp[i] = noiseFloorLeft_exp[i] - noiseFloorRight_exp[i]; 415 416 /* 417 * (2^m)*2^n/(1+2^m) = 2^n/(1 + 2^-m); 418 */ 419 420 noiseFloorLeft_man[i] = noiseFloorRight_man[i]; 421 noiseFloorLeft_exp[i] = noiseFloorLeft_exp[i]; 422 423 } 424 } 425 426 #endif 427 428