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 Pathname: tns_decode_coef.c 21 22 ------------------------------------------------------------------------------ 23 REVISION HISTORY 24 25 Description: Modified from original shareware code 26 27 Description: Implemented in 16-bit Fixed Point 28 29 Description: Implemented in 24-bit Fixed Point 30 31 Description: Modified to return the calculated LPC coefficients "in place" 32 This saves memory, cycles, etc. because it saves a large temporary 33 array being declared on the stack in another function (tns_setup_filter) 34 35 Description: Modified to return the q-format of the lpc coefficients. 36 37 Description: Modified for more reliable overflow protection. tns_decode_coef 38 no longer relies on "reasonable" outputs. This code should handle all 39 possible inputs. 40 41 Description: Modified per review comments. 42 43 Description: Added check condition to avoid numbers with a Q bigger than 44 15 from being passed, otherwise in a 16-bit number the sign is lost. 45 46 Description: Modified to utilize scratch memory techniques, thereby 47 eliminating two arrays of size TNS_MAX_ORDER, which were previously declared 48 on the stack. 49 50 Description: Updated the SW template to include the full pathname to the 51 source file and a slightly modified copyright header. 52 53 Description: 54 (1) Changed the order of the unsigned * signed multiply so the 55 casting to Int32 is performed on the unsigned operand. 56 57 (2) Removed some unnecessary casting. 58 (3) Fixed a problem where a 16-bit value was casted to 32-bits AFTER 59 a shift. It should have been cast to 32-bits BEFORE the shifting. 60 61 62 Description: modified precision of coefficients 63 64 Who: Date: 65 Description: 66 ------------------------------------------------------------------------------ 67 INPUT AND OUTPUT DEFINITIONS 68 69 The inputs and their range are defined in ISO/IEC 14496-3:1999(E) 70 Part 3 MPEG-4 Audio 71 Subpart 4 72 73 Inputs: order = RANGE = 1-20 74 const Int 75 76 coef_res = RANGE = 0-1 77 const Int 78 79 lpc_coef = RANGE = -8 to 7 if coef_res = 1 compression OFF 80 -4 to 3 if coef_res = 1 compression ON 81 -4 to 3 if coef_res = 0 compression OFF 82 -2 to 1 if coef_res = 0 compression ON 83 84 [Int *, length TNS_MAX_ORDER] 85 86 Global Stores/Buffers/Pointers Needed: 87 None 88 89 Outputs: 90 q_lpc = q_format for the calculated LPC coefs. 91 Int 92 93 Pointers and Buffers Modified: 94 lpc_coef = used to return the calculated LPC coefs in-place. 95 Int * 96 97 Global Stores Modified: 98 None 99 100 ------------------------------------------------------------------------------ 101 FUNCTION DESCRIPTION 102 103 This function calculates the LPC coefs from the encoded coefs... 104 105 ------------------------------------------------------------------------------ 106 REQUIREMENTS 107 108 This function should match the functionality of the ISO source code within 109 a reasonable tolerance for fixed point errors. 110 111 ------------------------------------------------------------------------------ 112 REFERENCES 113 114 (1) ISO/IEC 14496-3:1999(E) 115 Part 3 116 Subpart 4.6.8 (Temporal Noise Shaping) 117 (2) Markel & Gray Page 95 118 As referenced in the ISO source code 119 120 (3) MPEG-2 NBC Audio Decoder 121 "This software module was originally developed by AT&T, Dolby 122 Laboratories, Fraunhofer Gesellschaft IIS in the course of development 123 of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and 124 3. This software module is an implementation of a part of one or more 125 MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4 126 Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio 127 standards free license to this software module or modifications thereof 128 for use in hardware or software products claiming conformance to the 129 MPEG-2 NBC/MPEG-4 Audio standards. Those intending to use this software 130 module in hardware or software products are advised that this use may 131 infringe existing patents. The original developer of this software 132 module and his/her company, the subsequent editors and their companies, 133 and ISO/IEC have no liability for use of this software module or 134 modifications thereof in an implementation. Copyright is not released 135 for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original 136 developer retains full right to use the code for his/her own purpose, 137 assign or donate the code to a third party and to inhibit third party 138 from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products. 139 This copyright notice must be included in all copies or derivative 140 works." 141 Copyright(c)1996. 142 143 ------------------------------------------------------------------------------ 144 */ 145 146 /*---------------------------------------------------------------------------- 147 PSEUDOCODE: (ISO Reference Code) 148 149 int i, m; 150 Real iqfac, iqfac_m; 151 Real lpc_fp[TNS_MAX_ORDER+1]; 152 Real sin_result_fp[TNS_MAX_ORDER+1], b[TNS_MAX_ORDER+1]; 153 154 Inverse quantization 155 iqfac = (Real)(((1 << (coef_res-1)) - 0.5) / (PI/2.0)); 156 iqfac_m = (Real)(((1 << (coef_res-1)) + 0.5) / (PI/2.0)); 157 158 for (i=0; i<order; i++) 159 { 160 sin_result[i+1] = 161 (Real)sin( coef[i] / ((coef[i] >= 0) ? iqfac : iqfac_m) ); 162 } 163 164 lpc[0] = 1; 165 for (m=1; m<=order; m++) 166 { 167 168 b[0] = lpc[0]; 169 for (i=1; i<m; i++) 170 { 171 b[i] = sin_result[m] * lpc[m-i]; 172 b[i] += lpc[i]; 173 } 174 175 b[m] = sin_result[m]; 176 177 178 for (i=0; i<=m; i++) 179 { 180 lpc[i] = b[i]; 181 } 182 183 } 184 185 return; 186 187 } 188 ----------------------------------------------------------------------------*/ 189 190 /*---------------------------------------------------------------------------- 191 ; INCLUDES 192 ----------------------------------------------------------------------------*/ 193 #include "pv_audio_type_defs.h" 194 #include "e_tns_const.h" 195 #include "tns_decode_coef.h" 196 #include "fxp_mul32.h" 197 198 /*---------------------------------------------------------------------------- 199 ; MACROS 200 ; Define module specific macros here 201 ----------------------------------------------------------------------------*/ 202 203 /*---------------------------------------------------------------------------- 204 ; DEFINES 205 ; Include all pre-processor statements here. Include conditional 206 ; compile variables also. 207 ----------------------------------------------------------------------------*/ 208 #define MASK_LOW16 0xffff 209 #define UPPER16 16 210 211 /*---------------------------------------------------------------------------- 212 ; LOCAL FUNCTION DEFINITIONS 213 ; Function Prototype declaration 214 ----------------------------------------------------------------------------*/ 215 216 /*---------------------------------------------------------------------------- 217 ; LOCAL VARIABLE DEFINITIONS 218 ; Variable declaration - defined here and used outside this module 219 ----------------------------------------------------------------------------*/ 220 /* 221 * Derivation of tns_tables and q_tns_tables 222 * 223 * As defined in the ISO source code 224 * (with the modification that our coef_res has a range[0,1] 225 * The ISO code has a range of [3,4]) 226 * 227 * pi / 2 pi / 2 228 * iqfac = -------------------- iqfac_m = -------------------- 229 * (coef_res + 2) - 1/ (coef_res + 2) + 1/ 230 * 2 /2 2 /2 231 * 232 * 233 * ... Move 1/2 into denominator 234 * 235 * pi pi 236 * iqfac = -------------------- iqfac_m = -------------------- 237 * (coef_res + 3) (coef_res + 3) 238 * 2 - 1 2 + 1 239 * 240 * 241 * if a coef is negative, it is multiplied by iqfac_m 242 * if positive, " " " iqfac 243 * 244 * The range of coefs is limited to -4:3 if coef_res = 0 245 * -8:7 if coef_res = 1 246 * 247 * 248 * 249 */ 250 251 252 const Int32 tns_table[2][16] = 253 { 254 { 255 -2114858546, -1859775393, -1380375881, -734482665, 256 0, 931758235, 1678970324, 2093641749 257 }, 258 { 259 -2138322861, -2065504841, -1922348530, -1713728946, 260 -1446750378, -1130504462, -775760571, -394599085, 261 0, 446486956, 873460290, 1262259218, 262 1595891361, 1859775393, 2042378317, 2135719508 263 } 264 }; 265 266 267 const Int neg_offset[2] = {4, 8}; 268 /*---------------------------------------------------------------------------- 269 ; EXTERNAL FUNCTION REFERENCES 270 ; Declare functions defined elsewhere and referenced in this module 271 ----------------------------------------------------------------------------*/ 272 273 /*---------------------------------------------------------------------------- 274 ; EXTERNAL VARIABLES REFERENCES 275 ; Declare variables used in this module but defined elsewhere 276 ----------------------------------------------------------------------------*/ 277 278 /*---------------------------------------------------------------------------- 279 FUNCTION NAME: tns_decode_coef 280 Decoder transmitted coefficients for one TNS filter 281 ----------------------------------------------------------------------------*/ 282 283 Int tns_decode_coef( 284 const Int order, 285 const Int coef_res, 286 Int32 lpc_coef[TNS_MAX_ORDER], 287 Int32 scratchTnsDecCoefMem[2*TNS_MAX_ORDER]) 288 { 289 290 /* Simple loop counters */ 291 Int i; 292 Int m; 293 294 /* Arrays for calculation of the LPC */ 295 Int32 *pB = &(scratchTnsDecCoefMem[TNS_MAX_ORDER]); 296 297 Int32 *pA = scratchTnsDecCoefMem; 298 299 Int32 *temp_ptr = NULL; 300 301 /* Pointer for reading/storing the lpc_coef in place */ 302 Int32 *pLPC; 303 Int q_lpc = Q_LPC; 304 305 /* TNS table related variables */ 306 const Int32 *pTnsTable; 307 Int coef_offset; 308 Int32 table_index; 309 Int shift_amount; 310 Int32 sin_result; 311 312 Int32 tempInt32; 313 314 Int32 max; 315 Int32 mask; 316 317 Int32 mult_high; 318 319 /* Conversion to LPC coefficients Ref. (2) */ 320 coef_offset = neg_offset[coef_res]; 321 pTnsTable = tns_table[coef_res]; 322 323 m = 0; 324 pLPC = lpc_coef; 325 326 327 /* 328 * Conversion to LPC coefficients 329 */ 330 331 do 332 { 333 table_index = coef_offset + *(pLPC++); 334 335 /* Equiv. to sin_result = tns_table[coef_res][table_index]; */ 336 sin_result = *(pTnsTable + table_index); 337 338 /* sin_result has a range of -0.999 to +0.999 in Q-31 */ 339 340 /* 341 * It is important that this for loop is not entered on the first 342 * iteration of the do-while( m < order ) loop. 343 */ 344 for (i = m; i > 0; i--) 345 { 346 347 /* 348 * temp_ptr used to optimize index into pA 349 * mult = (Int32)( pA[m-i] * sin_result); 350 */ 351 352 mult_high = fxp_mul32_Q31(*(temp_ptr--), sin_result); 353 354 /* 355 * pB[i] = pA[i] + sin_result * pA[m-i] 356 * 357 * (mult_high <<1) eliminates extra sign bit 358 */ 359 360 *(pB++) = *(pA++) + (mult_high << 1); 361 362 } /* END for (i=m; i > 0; i--) */ 363 364 365 /* Shift to place pB[m] in q_lpc format */ 366 367 *pB = sin_result >> 12; 368 369 /* 370 * Swapping the pointers here has the same effect 371 * as specifically copying the data from b to a 372 */ 373 374 temp_ptr = pA; 375 pA = pB; 376 pB = temp_ptr; 377 378 /* 379 * At this point, pA = pA[m] 380 * and pB = pB[m] 381 */ 382 temp_ptr = pA; 383 384 tempInt32 = *(pA); 385 386 mask = tempInt32 >> 31; 387 tempInt32 ^= mask; 388 389 max = tempInt32; 390 391 /* 392 * It is important that this for loop is not entered on the first 393 * iteration of the do-while( m < order ) loop. 394 */ 395 for (i = m; i > 0; i--) 396 { 397 tempInt32 = *(--pA); 398 399 mask = tempInt32 >> 31; 400 tempInt32 ^= mask; 401 402 max |= tempInt32; 403 } 404 405 pB -= m; 406 407 /* 408 * Here, pA = &(pA[0]) 409 * and pB = &(pB[0]) 410 */ 411 412 if (max >= 0x40000000L) 413 { 414 max >>= 1; 415 416 for (i = m; i > 0; i--) 417 { 418 *(pA++) >>= 1; 419 *(pB++) >>= 1; 420 } 421 422 /* Shift the most recent entry down also */ 423 *(pA) >>= 1; 424 425 q_lpc--; 426 427 pA -= m; 428 pB -= m; 429 } 430 431 m++; 432 433 } 434 while (m < order); 435 436 437 /* 438 * The following code compacts 439 * 32-bit LPC coefficients into 16-bit numbers, 440 * shifting by the minimum amount necessary. 441 */ 442 443 shift_amount = 0; 444 445 while (max > 32767) 446 { 447 max >>= 1; 448 shift_amount++; 449 } 450 451 /* 452 * This while loop is for protective purposes only. 453 * I have not found data that causes it to be entered. 454 * 455 */ 456 if (max != 0) 457 { 458 while (max < 16384) 459 { 460 max <<= 1; 461 shift_amount--; 462 } 463 } 464 465 466 pLPC = lpc_coef; 467 468 if (shift_amount >= 0) 469 { 470 471 for (m = order; m > 0; m--) 472 { 473 *(pLPC++) = *(pA++) << (16 - shift_amount); 474 } 475 } 476 477 478 q_lpc -= shift_amount; 479 480 /* 481 * make sure that the numbers have some meaning, q_lpc can not be 482 * bigger than 15 (15 bits + sign) 483 */ 484 485 if (q_lpc > 15) 486 { 487 shift_amount = q_lpc - 15; 488 pLPC = lpc_coef; 489 490 for (m = order; m > 0; m--) 491 { 492 *(pLPC++) >>= shift_amount; 493 } 494 495 q_lpc -= shift_amount; 496 } 497 498 return (q_lpc); 499 500 } /* tns_decode_coef */ 501