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 45SC 29 Software Copyright Licencing Disclaimer: 46 47This software module was originally developed by 48 Coding Technologies 49 50and edited by 51 - 52 53in the course of development of the ISO/IEC 13818-7 and ISO/IEC 14496-3 54standards for reference purposes and its performance may not have been 55optimized. This software module is an implementation of one or more tools as 56specified by the ISO/IEC 13818-7 and ISO/IEC 14496-3 standards. 57ISO/IEC gives users free license to this software module or modifications 58thereof for use in products claiming conformance to audiovisual and 59image-coding related ITU Recommendations and/or ISO/IEC International 60Standards. ISO/IEC gives users the same free license to this software module or 61modifications thereof for research purposes and further ISO/IEC standardisation. 62Those intending to use this software module in products are advised that its 63use may infringe existing patents. ISO/IEC have no liability for use of this 64software module or modifications thereof. Copyright is not released for 65products that do not conform to audiovisual and image-coding related ITU 66Recommendations and/or ISO/IEC International Standards. 67The original developer retains full right to modify and use the code for its 68own purpose, assign or donate the code to a third party and to inhibit third 69parties from using the code for products that do not conform to audiovisual and 70image-coding related ITU Recommendations and/or ISO/IEC International Standards. 71This copyright notice must be included in all copies or derivative works. 72Copyright (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 */ 121const 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 */ 132const 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 154void 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