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: long_term_prediction.c 21 22 ------------------------------------------------------------------------------ 23 REVISION HISTORY 24 25 Description: Made changes based on comments and experiment results. 26 27 Description: Passed in buffer sizes based on review comments and prototype 28 agreements. 29 30 Description: 1. Passed in "weight_index" instead of "weight". 31 2. Added weight table. 32 33 Description: 1. Removed some passed in buffer size variables since they are 34 not used for long window. 35 2. Modified comments format. 36 37 Description: 38 Modified casting to ensure proper operations for different platforms 39 40 Description: 41 Implemented circular buffer techniques, which save 4096 memmoves per 42 frame. 43 44 Description: 45 Implemented some optimizations found during the code review of this 46 module. The optimizations related to the rules on the range of 47 ltp_buffer_index and num_samples, which allows for a simpler 48 code construct to be used in the processing of the predicted samples. 49 50 Description: 51 Add max calculation on the filter implementation, this to eliminate 52 function buffer_adaptation() on the time to frequency transformation. 53 Function interface changed. It now return the amount of shifting needed 54 to garb only the top 16 MSB. 55 56 Description: 57 Replace clearing memory with for-loop with pvmemset function 58 59 Description: 60 61 ------------------------------------------------------------------------------ 62 INPUT AND OUTPUT DEFINITIONS 63 64 Inputs: 65 win_seq = type of window sequence (WINDOW_SEQUENCE). 66 67 weight_index = index (Int) of LTP coefficient table for all windows in 68 current frame. 69 70 delay = buffer (Int) containing delays for each window. 71 72 buffer = history buffer (Int16) containing the reconstructed time domain 73 signals of previous frames. 74 75 buffer_offset = value (Int) that indicates the location of the first 76 element in the LTP circular buffer. (Either 0 or 1024) 77 78 time_quant = filterbank buffer (Int32) This buffer is used by the 79 filterbank, but it's first 1024 elements are equivalent 80 to the last 1024 elements in the conventionally 81 implemented LTP buffer. Using this buffer directly avoids 82 costly duplication of memory. 83 84 predicted_samples = buffer (Int32) with length of 2048 to hold 85 predicted time domain signals. 86 87 buffer_index = index into buffer where the first sample of data from 88 the frame (t-2) (two frames ago) resides. (Int) 89 90 frame_length = length of one frame, type of Int. 91 92 Local Stores/Buffers/Pointers Needed: 93 None 94 95 Global Stores/Buffers/Pointers Needed: 96 None 97 98 Outputs: 99 Amount of shifting needed to grab the top 16 MSB from teh predicted buffer 100 101 Pointers and Buffers Modified: 102 predicted_samples contents are the newly calculated predicted time 103 domain signals 104 105 Local Stores Modified: 106 None 107 108 Global Stores Modified: 109 None 110 111 ------------------------------------------------------------------------------ 112 FUNCTION DESCRIPTION 113 114 Long term prediction (LTP) is used to reduce the redundancy of a signal 115 between successive coding frames. This function performs prediction by 116 applying 1-tap IIR filtering to calculate the predicted time domain 117 signals of current frame from previous reconstructed frames stored in 118 time domain history buffer. 119 120 The equation used for IIR filter is as following. 121 122 y(n) = weight * x(n - delay) 123 124 where y(n) ----- predicted time domain signals 125 x(n) ----- reconstructed time domain signals 126 weight ----- LTP coefficient 127 delay ----- optimal delay from 0 to 2047 128 129 ------------------------------------------------------------------------------ 130 REQUIREMENTS 131 132 None 133 134 ------------------------------------------------------------------------------ 135 REFERENCES 136 137 (1) ISO/IEC 14496-3:1999(E) 138 Part 3: Audio 139 Subpart 4.6.6 Long Term Prediction (LTP) 140 141 (2) MPEG-2 NBC Audio Decoder 142 "This software module was originally developed by Nokia in the course 143 of development of the MPEG-2 AAC/MPEG-4 Audio standard ISO/IEC13818-7, 144 14496-1, 2 and 3. This software module is an implementation of a part 145 of one or more MPEG-2 AAC/MPEG-4 Audio tools as specified by the MPEG-2 146 aac/MPEG-4 Audio standard. ISO/IEC gives users of the MPEG-2aac/MPEG-4 147 Audio standards free license to this software module or modifications 148 thereof for use in hardware or software products claiming conformance 149 to the MPEG-2 aac/MPEG-4 Audio standards. Those intending to use this 150 software module in hardware or software products are advised that this 151 use may infringe existing patents. The original developer of this 152 software module, the subsequent editors and their companies, and ISO/IEC 153 have no liability for use of this software module or modifications 154 thereof in an implementation. Copyright is not released for non MPEG-2 155 aac/MPEG-4 Audio conforming products. The original developer retains 156 full right to use the code for the developer's own purpose, assign or 157 donate the code to a third party and to inhibit third party from using 158 the code for non MPEG-2 aac/MPEG-4 Audio conforming products. This 159 copyright notice must be included in all copies or derivative works. 160 Copyright (c)1997. 161 162 ------------------------------------------------------------------------------ 163 PSEUDO-CODE 164 165 pPredicted_samples = &predicted_samples[0]; 166 167 weight = codebook[weight_index]; 168 169 IF (win_seq != EIGHT_SHORT_SEQUENCE) 170 THEN 171 172 block_length = frame_length << 1; 173 174 lag = delay[0]; 175 176 j = block_length - lag; 177 178 IF (lag < frame_length) 179 THEN 180 181 num_samples = frame_length + lag; 182 183 ELSE 184 185 num_samples = block_length; 186 187 ENDIF 188 189 pBuffer = &buffer[j]; 190 191 FOR (i = num_samples; i>0; i--) 192 193 *pPredicted_samples = weight * (*pBuffer); 194 pPredicted_samples = pPredicted_samples + 1; 195 pBuffer = pBuffer + 1; 196 197 ENDFOR 198 199 FOR (i = block_length - num_samples; i>0; i--) 200 201 *pPredicted_samples = 0; 202 pPredicted_samples = pPredicted_samples + 1; 203 204 ENDFOR 205 206 ELSE 207 208 FOR (wnd = 0; wnd < short_window_num; wnd++) 209 210 IF (win_prediction_used[wnd] != FALSE) 211 THEN 212 213 delay[wnd] = delay[0] + ltp_short_lag[wnd]; 214 215 lag = delay[wnd]; 216 217 j = wnd*short_block_length - lag; 218 219 IF (lag < short_frame_length) 220 THEN 221 222 num_samples = short_frame_length + lag; 223 224 ELSE 225 226 num_samples = short_block_length; 227 228 ENDIF 229 230 pBuffer = &buffer[j]; 231 232 FOR (i = num_samples; i>0; i--) 233 234 *pPredicted_samples = weight * (*pBuffer); 235 pPredicted_samples = pPredicted_samples + 1; 236 pBuffer = pBuffer + 1; 237 238 ENDFOR 239 240 FOR (i = short_block_length - num_samples; i>0; i--) 241 242 *pPredicted_samples = 0; 243 pPredicted_samples = pPredicted_samples + 1; 244 245 ENDFOR 246 247 ELSE 248 249 CALL pv_memset( 250 pPredicted_samples, 251 0, 252 sizeof(*pPredicted_samples)*short_block_length); 253 MODIFYING (predicted_samples[]); 254 255 pPredicted_samples = pPredicted_samples + short_block_length; 256 257 ENDIF [ IF (win_prediction_used[wnd] != FALSE) ] 258 259 ENDFOR [ FOR (wnd=0; wnd<short_window_num; wnd++) ] 260 261 ENDIF [ IF (win_seq != EIGHT_SHORT_SEQUENCE) ] 262 263 RETURN 264 265 ------------------------------------------------------------------------------ 266 RESOURCES USED 267 When the code is written for a specific target processor the 268 the resources used should be documented below. 269 270 STACK USAGE: [stack count for this module] + [variable to represent 271 stack usage for each subroutine called] 272 273 where: [stack usage variable] = stack usage for [subroutine 274 name] (see [filename].ext) 275 276 DATA MEMORY USED: x words 277 278 PROGRAM MEMORY USED: x words 279 280 CLOCK CYCLES: [cycle count equation for this module] + [variable 281 used to represent cycle count for each subroutine 282 called] 283 284 where: [cycle count variable] = cycle count for [subroutine 285 name] (see [filename].ext) 286 287 ------------------------------------------------------------------------------ 288 */ 289 290 291 /*---------------------------------------------------------------------------- 292 ; INCLUDES 293 ----------------------------------------------------------------------------*/ 294 #include "pv_audio_type_defs.h" 295 #include "e_window_sequence.h" 296 #include "ltp_common_internal.h" 297 #include "long_term_prediction.h" 298 #include "aac_mem_funcs.h" 299 #include "pv_normalize.h" 300 #include "window_block_fxp.h" 301 302 303 /*---------------------------------------------------------------------------- 304 ; MACROS 305 ; Define module specific macros here 306 ----------------------------------------------------------------------------*/ 307 308 /*---------------------------------------------------------------------------- 309 ; DEFINES 310 ; Include all pre-processor statements here. Include conditional 311 ; compile variables also. 312 ----------------------------------------------------------------------------*/ 313 314 /*---------------------------------------------------------------------------- 315 ; LOCAL FUNCTION DEFINITIONS 316 ; Function Prototype declaration 317 ----------------------------------------------------------------------------*/ 318 319 /*---------------------------------------------------------------------------- 320 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS 321 ; Variable declaration - defined here and used outside this module 322 ----------------------------------------------------------------------------*/ 323 /* Purpose: Codebook for LTP weight coefficients. Stored in Q15 format */ 324 const UInt codebook[CODESIZE] = 325 { 326 18705, /* 0 */ 327 22827, /* 1 */ 328 26641, /* 2 */ 329 29862, /* 3 */ 330 32273, /* 4 */ 331 34993, /* 5 */ 332 39145, /* 6 */ 333 44877 /* 7 */ 334 }; 335 336 /*---------------------------------------------------------------------------- 337 ; EXTERNAL FUNCTION REFERENCES 338 ; Declare functions defined elsewhere and referenced in this module 339 ----------------------------------------------------------------------------*/ 340 341 /*---------------------------------------------------------------------------- 342 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 343 ; Declare variables used in this module but defined elsewhere 344 ----------------------------------------------------------------------------*/ 345 346 /*---------------------------------------------------------------------------- 347 ; FUNCTION CODE 348 ----------------------------------------------------------------------------*/ 349 Int long_term_prediction( 350 WINDOW_SEQUENCE win_seq, 351 const Int weight_index, 352 const Int delay[], 353 const Int16 buffer[], 354 const Int buffer_offset, 355 const Int32 time_quant[], 356 Int32 predicted_samples[], /* Q15 */ 357 const Int frame_length) 358 { 359 /*---------------------------------------------------------------------------- 360 ; Define all local variables 361 ----------------------------------------------------------------------------*/ 362 /* 363 * Window index 364 * 365 * Int wnd; 366 * 367 * will be enabled when short window information is available. 368 */ 369 370 /* Pointer to time domain history buffer */ 371 372 const Int16 *pBuffer; 373 374 const Int32 *pTimeQuant = time_quant; 375 376 /* Pointer to array containing predicted samples */ 377 Int32 *pPredicted_samples; 378 379 Int32 test; 380 Int32 datum; 381 382 /* IIR coefficient with Q15 format */ 383 UInt weight; 384 385 /* Length of one block (two frames) */ 386 Int block_length; 387 388 Int shift; 389 Int k; 390 Int ltp_buffer_index; 391 Int jump_point; 392 Int lag; 393 Int num_samples; 394 395 Int32 max = 0; 396 397 /*---------------------------------------------------------------------------- 398 ; Function body here 399 ----------------------------------------------------------------------------*/ 400 /* Initialize pointers */ 401 pPredicted_samples = &predicted_samples[0]; 402 403 weight = codebook[weight_index]; 404 405 /****************************************/ 406 /* LTP decoding process for long window */ 407 /****************************************/ 408 409 if (win_seq != EIGHT_SHORT_SEQUENCE) 410 { 411 /****************************************************/ 412 /* Prediction based on previous time domain signals */ 413 /****************************************************/ 414 block_length = frame_length << 1; 415 416 /* Calculate time lag for 1-tap IIR filter */ 417 lag = delay[0]; 418 419 ltp_buffer_index = block_length - lag; 420 421 /* Calculate number of samples used in IIR filter */ 422 if (lag < frame_length) 423 { 424 num_samples = frame_length + lag; 425 } 426 else 427 { 428 num_samples = block_length; 429 } 430 431 432 /* 433 * Calculate the predicted time domain signals from the 434 * reconstructed time domain signals of previous frames. 435 */ 436 437 /* The data is stored in TWO buffers, either as... 438 * 439 * [ t == 0 ] 440 * 441 * [ t == -1 ][ t == -2 ] 442 * 443 * OR... 444 * [ t == 0 ] 445 * 446 * [ t == -2 ][ t == -1 ] 447 * 448 * 449 * 450 * In the first case, all of the buffers are non-contiguous, 451 * and each must be handled separately. Code for this first case 452 * will function correctly for both cases. 453 * 454 * In the second case, the buffers storing t == -2, and t == -1 455 * data are contiguous, and an optimization could take advantage 456 * of this, at the cost of an increase in code size for this function. 457 */ 458 459 /* Decrement block_length by num_samples. This is important 460 * for the loop at the end of the "ACCESS DATA IN THE LTP BUFFERS" 461 * section that sets all remaining samples in the block to zero. 462 */ 463 464 block_length -= num_samples; 465 466 467 468 469 470 471 /* 472 ************************************ ACCESS DATA IN THE LTP BUFFERS 473 */ 474 475 /* 476 * This section of the code handles the t == -2 477 * buffer, which corresponds to 0 <= ltp_buffer_index < 1024 478 * 479 * BUFFER t == -2 480 * 481 * [0][][][][][][][][][][][...][][][][][][][][][][][][1023] 482 * 483 */ 484 485 jump_point = (frame_length - ltp_buffer_index); 486 487 if (jump_point > 0) 488 { 489 pBuffer = &(buffer[ltp_buffer_index + buffer_offset]); 490 491 for (k = jump_point; k > 0; k--) 492 { 493 /* Q15 = Q15 * Q0 */ 494 test = (Int32) weight * (*(pBuffer++)); 495 *(pPredicted_samples++) = test; 496 max |= (test >> 31) ^ test; 497 } 498 499 num_samples -= jump_point; 500 501 ltp_buffer_index += jump_point; 502 } 503 504 /* 505 * This section of the code handles the t == -1 506 * buffer, which corresponds to 1024 <= ltp_buffer_index < 2048 507 * 508 * BUFFER t == -1 509 * 510 * [1024][][][][][][][][][][][...][][][][][][][][][][][][2047] 511 * 512 */ 513 514 jump_point = 2 * frame_length - ltp_buffer_index; 515 516 pBuffer = &(buffer[ltp_buffer_index - buffer_offset]); 517 518 if (num_samples < jump_point) 519 { 520 jump_point = num_samples; 521 } 522 523 for (k = jump_point; k > 0; k--) 524 { 525 /* Q15 = Q15 * Q0 */ 526 test = (Int32) weight * (*(pBuffer++)); 527 *(pPredicted_samples++) = test; 528 max |= (test >> 31) ^ test; 529 } 530 531 num_samples -= jump_point; 532 533 ltp_buffer_index += jump_point; 534 535 /* 536 * This section of the code handles the t == 0 537 * buffer, which corresponds to 2048 <= ltp_buffer_index < 3072 538 * 539 * BUFFER t == 0 540 * 541 * [2048][][][][][][][][][][][...][][][][][][][][][][][][3071] 542 * 543 */ 544 for (k = num_samples; k > 0; k--) 545 { 546 547 datum = *(pTimeQuant++) >> SCALING; 548 549 /* 550 * Limit the values in the 32-bit filterbank's buffer to 551 * 16-bit resolution. 552 * 553 * Value's greater than 32767 or less than -32768 are saturated 554 * to 32767 and -32768, respectively. 555 */ 556 557 test = (Int32)datum * weight; 558 *(pPredicted_samples++) = test; 559 max |= (test >> 31) ^ test; 560 561 } 562 563 /* Set any remaining samples in the block to 0. */ 564 565 pv_memset( 566 pPredicted_samples, 567 0, 568 block_length*sizeof(*pPredicted_samples)); 569 570 } /* if (win_seq != EIGHT_SHORT_SEQUENCE) */ 571 572 573 /*****************************************/ 574 /* LTP decoding process for short window */ 575 /*****************************************/ 576 577 /* 578 * For short window LTP, since there is no "ltp_short_lag" 579 * information being passed, the following code for short 580 * window LTP will be applied in the future when those 581 * information are available. 582 */ 583 584 /* 585 *---------------------------------------------------------------------------- 586 * else 587 * { 588 * for (wnd = 0; wnd < short_window_num; wnd++) 589 * { 590 * if (win_prediction_used[wnd] != FALSE) 591 * { 592 * delay[wnd] = delay[0] + ltp_short_lag[wnd]; 593 * 594 * lag = delay[wnd]; 595 * 596 * j = wnd*short_block_length - lag; 597 * 598 * if (lag < short_frame_length) 599 * { 600 * num_samples = short_frame_length + lag; 601 * } 602 * else 603 * { 604 * num_samples = short_block_length; 605 * } 606 * 607 * pBuffer = &buffer[j]; 608 * 609 * for(i = num_samples; i>0; i--) 610 * { 611 * *(pPredicted_samples++) = weight * (*(pBuffer++)); 612 * } 613 * 614 * for(i = short_block_length - num_samples; i>0; i--) 615 * { 616 * *(pPredicted_samples++) = 0; 617 * } 618 * } 619 * else 620 * { 621 * pv_memset( 622 * pPredicted_samples, 623 * 0, 624 * sizeof(*pPredicted_samples)*short_block_length); 625 * 626 * pPredicted_samples += short_block_length; 627 * } 628 * } 629 * } 630 *---------------------------------------------------------------------------- 631 */ 632 633 shift = 16 - pv_normalize(max); 634 635 if (shift < 0) 636 { 637 shift = 0; 638 } 639 640 /*---------------------------------------------------------------------------- 641 ; Return nothing or data or data pointer 642 ----------------------------------------------------------------------------*/ 643 return (shift); 644 } /* long_term_prediction */ 645 646 647 648 649