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: trans4m_time_2_freq_fxp.c 21 Function: trans4m_time_2_freq_fxp 22 23 ------------------------------------------------------------------------------ 24 REVISION HISTORY 25 26 Description: 27 Modified normalization, so it now happen per window basis, eliminated 28 shifts left or rigth to accomodate TNS inverse filtering. The output 29 is 32 bits but only the lowest 16 are being used. 30 Modified fuction interface 31 32 Description: Modified variable names with leading "p" for pointers 33 34 Description: 35 Modified call to mdct_fxp to reflect extended precision use. Added routine 36 buffer_adaptation to extract 16 MSB and keep highest precision. 37 Modify casting to ensure proper operations for different platforms 38 39 Description: 40 Added comments according to code review 41 42 Description: 43 Removed include file "buffer_normalization.h" 44 45 Description: 46 Eliminated buffer_adaptation() and embedded its functionality in other 47 functions. Commented out the short window section given that this is 48 not supported by the standards 49 50 Description: 51 Added shift down operation for case when the window was equal to one. 52 This was not needed previuosly because buffer_adaptation() was doing 53 it. 54 55 Description: Created local version of vectors Long_Window_fxp and 56 Short_Window_fxp. This solve linking problem when using the 57 /ropi option (Read-only position independent) for some 58 compilers. 59 60 61 Who: Date: 62 Description: 63 64 ------------------------------------------------------------------------------ 65 INPUT AND OUTPUT DEFINITIONS 66 67 Inputs: 68 Time2Freq_data = buffer with data in the time domain, it holds 2048 69 points of input time data 70 Output holds frequency (first 1024 points ) 71 type Int32 72 73 wnd_seq = window sequence 74 type WINDOW_SEQUENCE 75 76 wnd_shape_prev_bk = previous window shape type 77 type Int 78 79 wnd_shape_this_bk = current window shape type 80 type Int 81 82 pQ_format = Holds the Q format of the data in, and data out 83 type Int * 84 85 mem_4_in_place_FFT[] = scratch memory for computing FFT, 1024 point 86 type Int32 87 88 89 90 Local Stores/Buffers/Pointers Needed: 91 None 92 93 Global Stores/Buffers/Pointers Needed: 94 None 95 96 Outputs: 97 None 98 99 Pointers and Buffers Modified: 100 Frequency information (1024 pts.) is returned in Time2Freq_data 101 pQ_format content spectral coefficients Q format 102 103 Local Stores Modified: 104 None 105 106 Global Stores Modified: 107 None 108 109 ------------------------------------------------------------------------------ 110 FUNCTION DESCRIPTION 111 112 The time/frequency representation of the signal is mapped onto the frequency 113 domain by feeding it into the filterbank module. This module consists of 114 a modified discrete cosine transform (MDCT), (windowing and DCT). 115 In order to adapt the time/frequency resolution of the filterbank to the 116 characteristics of the input signal, a block switching tool is also 117 adopted. N represents the window length, where N is a function of the 118 window_sequence. For each channel, the N time values are transformed into the 119 N/2 frequency domain values via the MDCT. 120 121 The adaptation of the time-frequency resolution of the filterbank to the 122 characteristics of the input signal is done by shifting between transforms 123 whose input lengths are either 2048 or 256 samples. By enabling the block 124 switching tool, the following transitions are meaningful: 125 126 from ONLY_LONG_SEQUENCE to { LONG_START_SEQUENCE 127 ONLY_LONG_SEQUENCE 128 129 from LONG_START_SEQUENCE to { LONG_STOP_SEQUENCE 130 EIGHT_SHORT_SEQUENCE 131 132 from LONG_STOP_SEQUENCE to { LONG_START_SEQUENCE 133 ONLY_LONG_SEQUENCE 134 135 from EIGHT_SHORT_SEQUENCE to { LONG_STOP_SEQUENCE 136 EIGHT_SHORT_SEQUENCE 137 138 Window shape decisions are made by the encoder on a frame-by-frame-basis. 139 The window selected is applicable to the second half of the window function 140 only, since the first half is constrained to use the appropriate window 141 shape from the preceding frame. 142 The 2048 time-domain values x'(i)(n), (i window, n sample) to be windowed are 143 the last 1024 values of the previous window_sequence concatenated with 1024 144 values of the current block. The formula below shows this fact: 145 146 | x(i-1)(n+1024) for 0 < n < 1024 147 x'(i)(n) { 148 | x(i)(n) for 1024 < n < 2048 149 150 151 152 Once the window shape is selected, the window_shape syntax element is 153 initialized. Together with the chosen window_sequence all information needed 154 for windowing exist. 155 With the window halves described below all window_sequences can be assembled. 156 For window_shape == 1, the window coefficients are given by the Kaiser - 157 Bessel derived (KBD) window. 158 Otherwise, for window_shape == 0, a sine window is employed. 159 160 The window length N can be 2048 or 256 for the KBD and the sine window. 161 All four window_sequences explained below have a total length of 2048 162 samples. 163 For all kinds of window_sequences the window_shape of the left half of 164 the first transform window is determined by the window shape of the previous 165 block. 166 ------------------------------------------------------------------------------ 167 REQUIREMENTS 168 169 This module shall implement a scheme to switch between window types and 170 in turn perform time to frequency transformations 171 172 173 ------------------------------------------------------------------------------ 174 REFERENCES 175 176 [1] ISO 14496-3:1999, pag 111 177 178 ------------------------------------------------------------------------------ 179 PSEUDO-CODE 180 181 IF ( wnd_seq == EIGHT_SHORT_SEQUENCE) 182 THEN 183 184 185 FOR ( wnd=0; wnd<NUM_SHORT_WINDOWS; wnd++) 186 187 time_info = &Time2Freq_data[ W_L_STOP_1 + wnd*SHORT_WINDOW] 188 189 FOR( i=0; i<SHORT_BLOCK1; i++) 190 aux_temp[i] = time_info[i] 191 ENDFOR 192 193 194 IF (wnd == 0) 195 THEN 196 pShort_Window_1 = &Short_Window[wnd_shape_prev_bk][0] 197 ELSE 198 pShort_Window_1 = &Short_Window[wnd_shape_this_bk][0] 199 ENDIF 200 201 202 pShort_Window_2 = 203 &Short_Window[wnd_shape->this_bk][SHORT_WINDOW_m_1] 204 205 FOR( i=0, j=SHORT_WINDOW; i<SHORT_WINDOW; i++, j--) 206 aux_temp[ i] *= pShort_Window_1[i] 207 aux_temp[SHORT_WINDOW+i] *= pShort_Window_2[j] 208 ENDFOR 209 210 211 CALL MDCT( aux_temp, SHORT_BLOCK1) 212 MODIFYING( aux_temp) 213 214 FOR( i=0; i<SHORT_WINDOW; i++) 215 Time2Freq_data[wnd*SHORT_WINDOW + i] = aux_temp[i]; 216 ENDFOR 217 218 ENDFOR 219 220 ELSE 221 222 SWITCH ( wnd_seq) 223 224 CASE ( ONLY_LONG_SEQUENCE) 225 226 pLong_Window_1 = &Long_Window[wnd_shape_prev_bk][0] 227 pLong_Window_2 = 228 &Long_Window[wnd_shape_this_bk][LONG_WINDOW_m_1] 229 230 FOR (i=0; i<LONG_WINDOW; i++) 231 Time2Freq_data[ i] *= *pLong_Window_1++ 232 Time2Freq_data[LONG_WINDOW+i] *= *pLong_Window_2-- 233 ENDFOR 234 235 BREAK 236 237 238 CASE ( LONG_START_SEQUENCE) 239 240 pLong_Window_1 = &Long_Window[wnd_shape_prev_bk][0]; 241 242 FOR ( i=0; i<LONG_WINDOW; i++) 243 Time2Freq_data[ i] *= *pLong_Window_1++; 244 ENDFOR 245 246 247 pShort_Window_1 = 248 &Short_Window[wnd_shape->this_bk][SHORT_WINDOW_m_1]; 249 250 FOR ( i=0; i<SHORT_WINDOW; i++) 251 Time2Freq_data[W_L_START_1 + i] *= *pShort_Window_1--; 252 ENDFOR 253 254 255 FOR ( i=W_L_START_2; i<LONG_BLOCK1; i++) 256 Time2Freq_data[W_L_START_2 + i] = 0; 257 ENDFOR 258 259 BREAK 260 261 262 CASE ( LONG_STOP_SEQUENCE ) 263 264 FOR ( i=0; i<W_L_STOP_1; i++) 265 Time2Freq_data[ i] = 0; 266 ENDFOR 267 268 269 pShort_Window_1 = &Short_Window[wnd_shape->prev_bk][0]; 270 271 FOR ( i=0; i<SHORT_WINDOW; i++) 272 Time2Freq_data[W_L_STOP_1+ i] *= *pShort_Window_1++; 273 ENDFOR 274 275 276 pLong_Window_1 = 277 &Long_Window[wnd_shape->this_bk][LONG_WINDOW_m_1]; 278 279 FOR ( i=0; i<LONG_WINDOW; i++) 280 Time2Freq_data[LONG_WINDOW + i] *= *pLong_Window_1--; 281 ENDFOR 282 283 BREAK 284 285 286 } 287 288 MDCT( Time2Freq_data, LONG_BLOCK1); 289 MODIFYING( Time2Freq_data) 290 291 ENDIF 292 293 ------------------------------------------------------------------------------ 294 RESOURCES USED 295 When the code is written for a specific target processor the 296 the resources used should be documented below. 297 298 STACK USAGE: [stack count for this module] + [variable to represent 299 stack usage for each subroutine called] 300 301 where: [stack usage variable] = stack usage for [subroutine 302 name] (see [filename].ext) 303 304 DATA MEMORY USED: x words 305 306 PROGRAM MEMORY USED: x words 307 308 CLOCK CYCLES: [cycle count equation for this module] + [variable 309 used to represent cycle count for each subroutine 310 called] 311 312 where: [cycle count variable] = cycle count for [subroutine 313 name] (see [filename].ext) 314 315 ------------------------------------------------------------------------------ 316 */ 317 318 319 /*---------------------------------------------------------------------------- 320 ; INCLUDES 321 ----------------------------------------------------------------------------*/ 322 323 #include "pv_audio_type_defs.h" 324 #include "aac_mem_funcs.h" 325 #include "window_block_fxp.h" 326 #include "mdct_fxp.h" 327 #include "long_term_prediction.h" 328 #include "fxp_mul32.h" 329 330 331 /*---------------------------------------------------------------------------- 332 ; MACROS 333 ; Define module specific macros here 334 ----------------------------------------------------------------------------*/ 335 336 /*---------------------------------------------------------------------------- 337 ; DEFINES 338 ; Include all pre-processor statements here. Include conditional 339 ; compile variables also. 340 ----------------------------------------------------------------------------*/ 341 /*---------------------------------------------------------------------------- 342 ; LOCAL FUNCTION DEFINITIONS 343 ; Function Prototype declaration 344 ----------------------------------------------------------------------------*/ 345 346 /*---------------------------------------------------------------------------- 347 ; LOCAL VARIABLE DEFINITIONS 348 ; Variable declaration - defined here and used outside this module 349 ----------------------------------------------------------------------------*/ 350 351 /*---------------------------------------------------------------------------- 352 ; EXTERNAL FUNCTION REFERENCES 353 ; Declare functions defined elsewhere and referenced in this module 354 ----------------------------------------------------------------------------*/ 355 356 /*---------------------------------------------------------------------------- 357 ; EXTERNAL VARIABLES REFERENCES 358 ; Declare variables used in this module but defined elsewhere 359 ----------------------------------------------------------------------------*/ 360 361 /*---------------------------------------------------------------------------- 362 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 363 ; Declare variables used in this module but defined elsewhere 364 ----------------------------------------------------------------------------*/ 365 366 /*---------------------------------------------------------------------------- 367 ; FUNCTION CODE 368 ----------------------------------------------------------------------------*/ 369 void trans4m_time_2_freq_fxp( 370 Int32 Time2Freq_data[], /* time data size 2048 */ 371 WINDOW_SEQUENCE wnd_seq, /* window sequence */ 372 Int wnd_shape_prev_bk, /* window shape, current and previous */ 373 Int wnd_shape_this_bk, 374 Int *pQ_format, 375 Int32 mem_4_in_place_FFT[]) /* scratch memory for computing FFT */ 376 { 377 378 Int i; 379 380 Int32 *pAux_temp_1; 381 Int32 *pAux_temp_2; 382 Int32 *pAux_temp; 383 // Int32 temp; 384 const Int16 *pLong_Window_1; 385 const Int16 *pLong_Window_2; 386 const Int16 *pShort_Window_1; 387 const Int16 *pShort_Window_2; 388 Int shift = *pQ_format - 1; 389 390 const Int16 * Long_Window_fxp[NUM_WINDOW_SHAPES]; 391 const Int16 * Short_Window_fxp[NUM_WINDOW_SHAPES]; 392 393 Long_Window_fxp[0] = Long_Window_sine_fxp; 394 Long_Window_fxp[1] = Long_Window_KBD_fxp; 395 Short_Window_fxp[0] = Short_Window_sine_fxp; 396 Short_Window_fxp[1] = Short_Window_KBD_fxp; 397 398 if (wnd_seq != EIGHT_SHORT_SEQUENCE) 399 { 400 401 pAux_temp = Time2Freq_data; 402 403 *pQ_format = LTP_Q_FORMAT - *pQ_format; 404 405 pAux_temp_1 = pAux_temp; 406 407 switch (wnd_seq) 408 { 409 410 case LONG_START_SEQUENCE: 411 412 pAux_temp_2 = &pAux_temp_1[HALF_LONG_WINDOW]; 413 414 pLong_Window_1 = &Long_Window_fxp[wnd_shape_prev_bk][0]; 415 pLong_Window_2 = &pLong_Window_1[ HALF_LONG_WINDOW]; 416 417 418 419 420 for (i = HALF_LONG_WINDOW; i > 0; i--) 421 { 422 423 *pAux_temp_1 = fxp_mul32_by_16((*pAux_temp_1), *pLong_Window_1++) >> shift; 424 pAux_temp_1++; 425 *pAux_temp_2 = fxp_mul32_by_16((*pAux_temp_2), *pLong_Window_2++) >> shift; 426 pAux_temp_2++; 427 428 } 429 430 431 /* data unchanged from LONG_WINDOW to W_L_START_1 */ 432 pAux_temp_1 = &pAux_temp[LONG_WINDOW]; 433 if (shift) 434 { 435 for (i = (W_L_START_1 - LONG_WINDOW) >> 1; i != 0; i--) 436 { 437 *(pAux_temp_1++) >>= shift; 438 *(pAux_temp_1++) >>= shift; 439 } 440 } 441 442 443 pAux_temp_1 = &pAux_temp[W_L_START_1]; 444 pAux_temp_2 = &pAux_temp_1[HALF_SHORT_WINDOW]; 445 446 pShort_Window_1 = 447 &Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1]; 448 449 pShort_Window_2 = pShort_Window_1 - HALF_SHORT_WINDOW; 450 451 for (i = HALF_SHORT_WINDOW; i > 0; i--) 452 { 453 454 *pAux_temp_1 = fxp_mul32_by_16((*pAux_temp_1), *pShort_Window_1--) >> shift; 455 pAux_temp_1++; 456 *pAux_temp_2 = fxp_mul32_by_16((*pAux_temp_2), *pShort_Window_2--) >> shift; 457 pAux_temp_2++; 458 459 } 460 461 pAux_temp_1 = &pAux_temp[W_L_START_2]; 462 463 pv_memset( 464 pAux_temp_1, 465 0, 466 (LONG_BLOCK1 - W_L_START_2)*sizeof(*pAux_temp_1)); 467 468 break; 469 470 471 case LONG_STOP_SEQUENCE: 472 473 pv_memset( 474 pAux_temp_1, 475 0, 476 (W_L_STOP_1)*sizeof(*pAux_temp_1)); 477 478 pShort_Window_1 = &Short_Window_fxp[wnd_shape_prev_bk][0]; 479 pShort_Window_2 = &pShort_Window_1[HALF_SHORT_WINDOW]; 480 481 pAux_temp_1 = &pAux_temp_1[W_L_STOP_1]; 482 pAux_temp_2 = pAux_temp_1 + HALF_SHORT_WINDOW; 483 484 for (i = HALF_SHORT_WINDOW; i > 0; i--) 485 { 486 487 *pAux_temp_1 = fxp_mul32_by_16((*pAux_temp_1), *pShort_Window_1++) >> shift; 488 pAux_temp_1++; 489 *pAux_temp_2 = fxp_mul32_by_16((*pAux_temp_2), *pShort_Window_2++) >> shift; 490 pAux_temp_2++; 491 492 493 } 494 495 /* data unchanged from W_L_STOP_2 to LONG_WINDOW */ 496 pAux_temp_1 = &pAux_temp[W_L_STOP_2]; 497 498 if (shift) 499 { 500 for (i = ((LONG_WINDOW - W_L_STOP_2) >> 1); i != 0; i--) 501 { 502 *(pAux_temp_1++) >>= shift; 503 *(pAux_temp_1++) >>= shift; 504 } 505 } 506 507 508 509 pAux_temp_1 = &pAux_temp[LONG_WINDOW]; 510 pAux_temp_2 = pAux_temp_1 + HALF_LONG_WINDOW; 511 512 pLong_Window_1 = 513 &Long_Window_fxp[wnd_shape_this_bk][LONG_WINDOW_m_1]; 514 515 516 pLong_Window_2 = &pLong_Window_1[-HALF_LONG_WINDOW]; 517 518 for (i = HALF_LONG_WINDOW; i > 0; i--) 519 { 520 *pAux_temp_1 = fxp_mul32_by_16((*pAux_temp_1), *pLong_Window_1--) >> shift; 521 pAux_temp_1++; 522 *pAux_temp_2 = fxp_mul32_by_16((*pAux_temp_2), *pLong_Window_2--) >> shift; 523 pAux_temp_2++; 524 525 } 526 527 break; 528 529 case ONLY_LONG_SEQUENCE: 530 default: 531 532 pAux_temp_2 = &pAux_temp[LONG_WINDOW]; 533 534 pLong_Window_1 = &Long_Window_fxp[wnd_shape_prev_bk][0]; 535 536 537 pLong_Window_2 = 538 &Long_Window_fxp[wnd_shape_this_bk][LONG_WINDOW_m_1]; 539 540 541 for (i = LONG_WINDOW; i > 0; i--) 542 { 543 544 *pAux_temp_1 = fxp_mul32_by_16((*pAux_temp_1), *pLong_Window_1++) >> shift; 545 pAux_temp_1++; 546 *pAux_temp_2 = fxp_mul32_by_16((*pAux_temp_2), *pLong_Window_2--) >> shift; 547 pAux_temp_2++; 548 } 549 550 break; 551 552 } /* end switch ( wnd_seq) */ 553 554 555 556 *pQ_format += mdct_fxp( 557 pAux_temp, 558 mem_4_in_place_FFT, 559 LONG_BLOCK1); 560 561 562 } /* end if( wnd_seq != EIGHT_SHORT_SEQUENCE) */ 563 564 565 566 /*****************************************/ 567 /* decoding process for short window */ 568 /*****************************************/ 569 570 /* 571 * For short window the following code will be applied 572 * in the future when short window is supported in the 573 * standards 574 */ 575 /*------------------------------------------------------------------------- 576 577 * pAux_temp = &mem_4_in_place_FFT[(2*SHORT_BLOCK1)]; 578 * 579 * for ( wnd=0; wnd<NUM_SHORT_WINDOWS; wnd++) 580 * { 581 * 582 * pShort_Window_1 = &Short_Window_fxp[wnd_shape_this_bk][0]; 583 * 584 * if (wnd == 0) 585 * { 586 * pShort_Window_1 = &Short_Window_fxp[wnd_shape_prev_bk][0]; 587 * } 588 * 589 * pShort_Window_2 = 590 * &Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1]; 591 * 592 * pAux_temp_1 = pAux_temp; 593 * pAux_temp_2 = pAux_temp_1 + SHORT_WINDOW; 594 * 595 * Q_aux = 0; 596 * 597 * buffer_adaptation ( 598 * &Q_aux, 599 * &Time2Freq_data[ W_L_STOP_1 + wnd*SHORT_WINDOW], 600 * (void *) pAux_temp, 601 * SHORT_BLOCK1, 602 * USING_INT, 603 * 16); 604 * 605 * 606 * for ( i=SHORT_WINDOW; i>0; i--) 607 * { 608 * temp = (*pAux_temp_1) * *pShort_Window_1++; 609 * *pAux_temp_1++ = (temp + 0x08000L) >> 16; 610 * 611 * temp = (*pAux_temp_2) * *pShort_Window_2--; 612 * *pAux_temp_2++ = (temp + 0x08000L) >> 16; 613 * 614 * } 615 * 616 * 617 * exp = mdct_fxp( 618 * pAux_temp, 619 * mem_4_in_place_FFT, 620 * SHORT_BLOCK1); 621 * 622 * 623 * exp += Q_aux; 624 * 625 * pAux_temp_1 = pAux_temp; 626 * pAux_temp_2 = pAux_temp_1 + HALF_SHORT_WINDOW; 627 * pTime_data_1 = &Time2Freq_data[wnd*SHORT_WINDOW]; 628 * pTime_data_2 = pTime_data_1 + HALF_SHORT_WINDOW; 629 * 630 * 631 * if (exp > 0) 632 * { 633 * for ( i=HALF_SHORT_WINDOW; i>0; i--) 634 * { 635 * *pTime_data_1++ = (*pAux_temp_1++>>exp); 636 * *pTime_data_2++ = (*pAux_temp_2++>>exp); 637 * } 638 * } 639 * else if (exp < 0) 640 * { 641 * exp = -exp; 642 * for ( i=HALF_SHORT_WINDOW; i>0; i--) 643 * { 644 * *pTime_data_1++ = (*pAux_temp_1++<<exp); 645 * *pTime_data_2++ = (*pAux_temp_2++<<exp); 646 * } 647 * } 648 * else 649 * { 650 * for ( i=HALF_SHORT_WINDOW; i>0; i--) 651 * { 652 * *pTime_data_1++ = (*pAux_temp_1++); 653 * *pTime_data_2++ = (*pAux_temp_2++); 654 * } 655 * } 656 * 657 * } 658 * 659 * } 660 * 661 *--------------------------------------------------------------------------*/ 662 663 } /* trans4m_time_2_freq_fxp */ 664