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 Portions of this file are derived from the following 3GPP standard: 20 21 3GPP TS 26.073 22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec 23 Available from http://www.3gpp.org 24 25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) 26 Permission to distribute, modify and use this file under the standard license 27 terms listed above has been obtained from the copyright holder. 28 ****************************************************************************************/ 29 /* 30 ------------------------------------------------------------------------------ 31 32 33 34 Pathname: ./audio/gsm-amr/c/src/dtx_enc.c 35 Funtions: dtx_enc_init 36 dtx_enc_reset 37 dtx_enc_exit 38 dtx_enc 39 dtx_buffer 40 tx_dtx_handler 41 42 Date: 06/08/2000 43 44 ------------------------------------------------------------------------------ 45 REVISION HISTORY 46 47 Description: Updated template used to PV coding template. First attempt at 48 optimizing C code. 49 50 Description: Updated file per comments gathered from Phase 2/3 review. 51 Synched up with new template (Inputs/Outputs section). Deleted 52 lines leftover from original code prior to the code section of 53 dtx_enc_exit function. Deleted confusing comment in the log_en 54 calculation in dtx_enc function. Restructured IF statement in 55 the calculation of the sum of squares of speech signals in 56 dtx_buffer. 57 58 Description: Added setting of Overflow flag in inlined code. 59 60 Description: Synchronized file with UTMS version 3.2.0. Updated coding 61 template. Removed unnecessary include files. 62 63 Description: Made the following changes per comments from Phase 2/3 review: 64 1. Modified FOR loops to count down. 65 2. Fixed typecasting issue with TI C compiler. 66 3. Fixed comment in dtx_enc pseudo-code. 67 4. Added dtx_enc code comment pertaining to possible assembly 68 implementation. 69 70 Description: Added calls to add() in tx_dtx_handler. Updated copyright year. 71 72 Description: Pass in pointer to overflow flag to all functions requiring this 73 flag. This is to make the library EPOC compatible. 74 75 Description: For dtx_enc_reset() only 76 1. Replaced copy() with memcpy. 77 2. Eliminated include file copy.h 78 3. Eliminated printf statement 79 For dtx_buffer() 80 1. Replaced copy() with memcpy. 81 2. Eliminated math operations that unnecessary checked for 82 saturation, in some cases this by shifting before adding and 83 in other cases by evaluating the operands 84 3. Unrolled loop to speed up execution 85 86 Description: For dtx_buffer() 87 1. Modified scaling and added check for saturation. Previous 88 scaling was correct but altered precision, this cause bit 89 exactness test failure. 90 91 Description: For dtx_buffer() 92 1. Modified scaling and saturation checks. Previous 93 scaling was correct but altered precision, this cause bit 94 exactness test failure for dtx vad2. 95 96 Description: Replaced OSCL mem type functions and eliminated include 97 files that now are chosen by OSCL definitions 98 99 Description: Replaced "int" and/or "char" with OSCL defined types. 100 101 Description: 102 103 ------------------------------------------------------------------------------ 104 MODULE DESCRIPTION 105 106 This file contains the various functions that perform the computation of the 107 Silence Indicator (SID) parameters when in Discontinuous Transmission (DTX) 108 mode. 109 110 ------------------------------------------------------------------------------ 111 */ 112 113 114 /*---------------------------------------------------------------------------- 115 ; INCLUDES 116 ----------------------------------------------------------------------------*/ 117 #include <stdlib.h> 118 #include <string.h> 119 120 #include "dtx_enc.h" 121 #include "q_plsf.h" 122 #include "typedef.h" 123 #include "mode.h" 124 #include "basic_op.h" 125 #include "log2.h" 126 #include "lsp_lsf.h" 127 #include "reorder.h" 128 129 /*---------------------------------------------------------------------------- 130 ; MACROS 131 ; Define module specific macros here 132 ----------------------------------------------------------------------------*/ 133 extern Word32 L_add(Word32 L_var1, Word32 L_var2, Flag *pOverflow); 134 135 /*---------------------------------------------------------------------------- 136 ; DEFINES 137 ; Include all pre-processor statements here. Include conditional 138 ; compile variables also. 139 ----------------------------------------------------------------------------*/ 140 141 /*---------------------------------------------------------------------------- 142 ; LOCAL FUNCTION DEFINITIONS 143 ; Function Prototype declaration 144 ----------------------------------------------------------------------------*/ 145 146 /*---------------------------------------------------------------------------- 147 ; LOCAL VARIABLE DEFINITIONS 148 ; Variable declaration - defined here and used outside this module 149 ----------------------------------------------------------------------------*/ 150 151 152 /* 153 ------------------------------------------------------------------------------ 154 FUNCTION NAME: dtx_enc_init 155 ------------------------------------------------------------------------------ 156 INPUT AND OUTPUT DEFINITIONS 157 158 Inputs: 159 st = pointer to an array of pointers to structures of type 160 dtx_encState 161 162 Outputs: 163 pointer pointed to by st is set to the address of the allocated 164 memory 165 166 Returns: 167 return_value = 0, if initialization was successful; -1, otherwise (int) 168 169 Global Variables Used: 170 None 171 172 Local Variables Needed: 173 None 174 175 ------------------------------------------------------------------------------ 176 FUNCTION DESCRIPTION 177 178 This function allocates the state memory used by the dtx_enc function. 179 180 ------------------------------------------------------------------------------ 181 REQUIREMENTS 182 183 None 184 185 ------------------------------------------------------------------------------ 186 REFERENCES 187 188 dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 189 190 ------------------------------------------------------------------------------ 191 PSEUDO-CODE 192 193 int dtx_enc_init (dtx_encState **st) 194 { 195 dtx_encState* s; 196 197 if (st == (dtx_encState **) NULL){ 198 fprintf(stderr, "dtx_enc_init: invalid parameter\n"); 199 return -1; 200 } 201 202 *st = NULL; 203 204 // allocate memory 205 if ((s= (dtx_encState *) malloc(sizeof(dtx_encState))) == NULL){ 206 fprintf(stderr, "dtx_enc_init: can not malloc state structure\n"); 207 return -1; 208 } 209 210 dtx_enc_reset(s); 211 *st = s; 212 213 return 0; 214 } 215 216 ------------------------------------------------------------------------------ 217 RESOURCES USED [optional] 218 219 When the code is written for a specific target processor the 220 the resources used should be documented below. 221 222 HEAP MEMORY USED: x bytes 223 224 STACK MEMORY USED: x bytes 225 226 CLOCK CYCLES: (cycle count equation for this function) + (variable 227 used to represent cycle count for each subroutine 228 called) 229 where: (cycle count variable) = cycle count for [subroutine 230 name] 231 232 ------------------------------------------------------------------------------ 233 CAUTION [optional] 234 [State any special notes, constraints or cautions for users of this function] 235 236 ------------------------------------------------------------------------------ 237 */ 238 239 Word16 dtx_enc_init(dtx_encState **st) 240 { 241 dtx_encState* s; 242 243 if (st == (dtx_encState **) NULL) 244 { 245 return(-1); 246 } 247 248 *st = NULL; 249 250 /* allocate memory */ 251 if ((s = (dtx_encState *) malloc(sizeof(dtx_encState))) == NULL) 252 { 253 return(-1); 254 } 255 256 dtx_enc_reset(s); 257 *st = s; 258 259 return(0); 260 } 261 262 /****************************************************************************/ 263 264 /* 265 ------------------------------------------------------------------------------ 266 FUNCTION NAME: dtx_enc_reset 267 ------------------------------------------------------------------------------ 268 INPUT AND OUTPUT DEFINITIONS 269 270 Inputs: 271 st = pointer to structures of type dtx_encState 272 273 Outputs: 274 structure pointed to by st is initialized to its reset value 275 276 Returns: 277 return_value = 1, if reset was successful; -1, otherwise (int) 278 279 Global Variables Used: 280 None 281 282 Local Variables Needed: 283 lsp_init_data = table containing LSP initialization values; 284 table elements are constants of type Word16; 285 table length is M 286 287 ------------------------------------------------------------------------------ 288 FUNCTION DESCRIPTION 289 290 This function initializes the fields of the state memory used by dtx_enc 291 to their reset values. 292 293 ------------------------------------------------------------------------------ 294 REQUIREMENTS 295 296 None 297 298 ------------------------------------------------------------------------------ 299 REFERENCES 300 301 dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 302 303 ------------------------------------------------------------------------------ 304 PSEUDO-CODE 305 306 int dtx_enc_reset (dtx_encState *st) 307 { 308 Word16 i; 309 310 if (st == (dtx_encState *) NULL){ 311 fprintf(stderr, "dtx_enc_reset: invalid parameter\n"); 312 return -1; 313 } 314 315 st->hist_ptr = 0; 316 st->log_en_index = 0; 317 st->init_lsf_vq_index = 0; 318 st->lsp_index[0] = 0; 319 st->lsp_index[1] = 0; 320 st->lsp_index[2] = 0; 321 322 // Init lsp_hist[] 323 for(i = 0; i < DTX_HIST_SIZE; i++) 324 { 325 Copy(lsp_init_data, &st->lsp_hist[i * M], M); 326 } 327 328 // Reset energy history 329 Set_zero(st->log_en_hist, M); 330 331 st->dtxHangoverCount = DTX_HANG_CONST; 332 st->decAnaElapsedCount = 32767; 333 334 return 1; 335 } 336 337 ------------------------------------------------------------------------------ 338 RESOURCES USED [optional] 339 340 When the code is written for a specific target processor the 341 the resources used should be documented below. 342 343 HEAP MEMORY USED: x bytes 344 345 STACK MEMORY USED: x bytes 346 347 CLOCK CYCLES: (cycle count equation for this function) + (variable 348 used to represent cycle count for each subroutine 349 called) 350 where: (cycle count variable) = cycle count for [subroutine 351 name] 352 353 ------------------------------------------------------------------------------ 354 CAUTION [optional] 355 [State any special notes, constraints or cautions for users of this function] 356 357 ------------------------------------------------------------------------------ 358 */ 359 360 Word16 dtx_enc_reset(dtx_encState *st) 361 { 362 Word16 i; 363 364 if (st == (dtx_encState *) NULL) 365 { 366 return(-1); 367 } 368 369 st->hist_ptr = 0; 370 st->log_en_index = 0; 371 st->init_lsf_vq_index = 0; 372 st->lsp_index[0] = 0; 373 st->lsp_index[1] = 0; 374 st->lsp_index[2] = 0; 375 376 /* Init lsp_hist[] */ 377 for (i = 0; i < DTX_HIST_SIZE; i++) 378 { 379 memcpy(&st->lsp_hist[i * M], lsp_init_data, M*sizeof(Word16)); 380 } 381 382 /* Reset energy history */ 383 memset(st->log_en_hist, 0, sizeof(Word16)*M); 384 st->dtxHangoverCount = DTX_HANG_CONST; 385 st->decAnaElapsedCount = 32767; 386 387 return(1); 388 } 389 390 /****************************************************************************/ 391 392 /* 393 ------------------------------------------------------------------------------ 394 FUNCTION NAME: dtx_enc_exit 395 ------------------------------------------------------------------------------ 396 INPUT AND OUTPUT DEFINITIONS 397 398 Inputs: 399 st = pointer to an array of pointers to structures of type 400 dtx_encState 401 402 Outputs: 403 st points to the NULL address 404 405 Returns: 406 None 407 408 Global Variables Used: 409 None 410 411 Local Variables Needed: 412 None 413 414 ------------------------------------------------------------------------------ 415 FUNCTION DESCRIPTION 416 417 This function deallocates the state memory used by dtx_enc function. 418 419 ------------------------------------------------------------------------------ 420 REQUIREMENTS 421 422 None 423 424 ------------------------------------------------------------------------------ 425 REFERENCES 426 427 dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 428 429 ------------------------------------------------------------------------------ 430 PSEUDO-CODE 431 432 void dtx_enc_exit (dtx_encState **st) 433 { 434 if (st == NULL || *st == NULL) 435 return; 436 437 // deallocate memory 438 free(*st); 439 *st = NULL; 440 441 return; 442 } 443 444 ------------------------------------------------------------------------------ 445 RESOURCES USED [optional] 446 447 When the code is written for a specific target processor the 448 the resources used should be documented below. 449 450 HEAP MEMORY USED: x bytes 451 452 STACK MEMORY USED: x bytes 453 454 CLOCK CYCLES: (cycle count equation for this function) + (variable 455 used to represent cycle count for each subroutine 456 called) 457 where: (cycle count variable) = cycle count for [subroutine 458 name] 459 460 ------------------------------------------------------------------------------ 461 CAUTION [optional] 462 [State any special notes, constraints or cautions for users of this function] 463 464 ------------------------------------------------------------------------------ 465 */ 466 467 void dtx_enc_exit(dtx_encState **st) 468 { 469 if (st == NULL || *st == NULL) 470 { 471 return; 472 } 473 474 /* deallocate memory */ 475 free(*st); 476 *st = NULL; 477 478 return; 479 } 480 481 /****************************************************************************/ 482 483 /* 484 ------------------------------------------------------------------------------ 485 FUNCTION NAME: dtx_enc 486 ------------------------------------------------------------------------------ 487 INPUT AND OUTPUT DEFINITIONS 488 489 Inputs: 490 st = pointer to structures of type dtx_encState 491 computeSidFlag = compute SID flag of type Word16 492 qSt = pointer to structures of type Q_plsfState 493 predState = pointer to structures of type gc_predState 494 anap = pointer to an array of pointers to analysis parameters of 495 type Word16 496 497 Outputs: 498 structure pointed to by st contains the newly calculated SID 499 parameters 500 structure pointed to by predState contains the new logarithmic frame 501 energy 502 pointer pointed to by anap points to the location of the new 503 logarithmic frame energy and new LSPs 504 505 Returns: 506 return_value = 0 (int) 507 508 Global Variables Used: 509 None 510 511 Local Variables Needed: 512 None 513 514 ------------------------------------------------------------------------------ 515 FUNCTION DESCRIPTION 516 517 This function calculates the SID parameters when in the DTX mode. 518 519 ------------------------------------------------------------------------------ 520 REQUIREMENTS 521 522 None 523 524 ------------------------------------------------------------------------------ 525 REFERENCES 526 527 dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 528 529 ------------------------------------------------------------------------------ 530 PSEUDO-CODE 531 532 int dtx_enc(dtx_encState *st, // i/o : State struct 533 Word16 computeSidFlag, // i : compute SID 534 Q_plsfState *qSt, // i/o : Qunatizer state struct 535 gc_predState* predState, // i/o : State struct 536 Word16 **anap // o : analysis parameters 537 ) 538 { 539 Word16 i,j; 540 Word16 log_en; 541 Word16 lsf[M]; 542 Word16 lsp[M]; 543 Word16 lsp_q[M]; 544 Word32 L_lsp[M]; 545 546 // VOX mode computation of SID parameters 547 if ((computeSidFlag != 0) || 548 (st->log_en_index == 0)) 549 { 550 // compute new SID frame if safe i.e don't 551 // compute immediately after a talk spurt 552 log_en = 0; 553 for (i = 0; i < M; i++) 554 { 555 L_lsp[i] = 0; 556 } 557 558 // average energy and lsp 559 for (i = 0; i < DTX_HIST_SIZE; i++) 560 { 561 log_en = add(log_en, 562 shr(st->log_en_hist[i],2)); 563 564 for (j = 0; j < M; j++) 565 { 566 L_lsp[j] = L_add(L_lsp[j], 567 L_deposit_l(st->lsp_hist[i * M + j])); 568 } 569 } 570 571 log_en = shr(log_en, 1); 572 for (j = 0; j < M; j++) 573 { 574 lsp[j] = extract_l(L_shr(L_lsp[j], 3)); // divide by 8 575 } 576 577 // quantize logarithmic energy to 6 bits 578 st->log_en_index = add(log_en, 2560); // +2.5 in Q10 579 st->log_en_index = add(st->log_en_index, 128); // add 0.5/4 in Q10 580 st->log_en_index = shr(st->log_en_index, 8); 581 582 if (sub(st->log_en_index, 63) > 0) 583 { 584 st->log_en_index = 63; 585 } 586 if (st->log_en_index < 0) 587 { 588 st->log_en_index = 0; 589 } 590 591 // update gain predictor memory 592 log_en = shl(st->log_en_index, -2+10); // Q11 and divide by 4 593 log_en = sub(log_en, 2560); // add 2.5 in Q11 594 595 log_en = sub(log_en, 9000); 596 if (log_en > 0) 597 { 598 log_en = 0; 599 } 600 if (sub(log_en, -14436) < 0) 601 { 602 log_en = -14436; 603 } 604 605 // past_qua_en for other modes than MR122 606 predState->past_qua_en[0] = log_en; 607 predState->past_qua_en[1] = log_en; 608 predState->past_qua_en[2] = log_en; 609 predState->past_qua_en[3] = log_en; 610 611 // scale down by factor 20*log10(2) in Q15 612 log_en = mult(5443, log_en); 613 614 // past_qua_en for mode MR122 615 predState->past_qua_en_MR122[0] = log_en; 616 predState->past_qua_en_MR122[1] = log_en; 617 predState->past_qua_en_MR122[2] = log_en; 618 predState->past_qua_en_MR122[3] = log_en; 619 620 // make sure that LSP's are ordered 621 Lsp_lsf(lsp, lsf, M); 622 Reorder_lsf(lsf, LSF_GAP, M); 623 Lsf_lsp(lsf, lsp, M); 624 625 // Quantize lsp and put on parameter list 626 Q_plsf_3(qSt, MRDTX, lsp, lsp_q, st->lsp_index, 627 &st->init_lsf_vq_index); 628 } 629 630 *(*anap)++ = st->init_lsf_vq_index; // 3 bits 631 632 *(*anap)++ = st->lsp_index[0]; // 8 bits 633 *(*anap)++ = st->lsp_index[1]; // 9 bits 634 *(*anap)++ = st->lsp_index[2]; // 9 bits 635 636 637 *(*anap)++ = st->log_en_index; // 6 bits 638 // = 35 bits 639 640 return 0; 641 } 642 643 ------------------------------------------------------------------------------ 644 RESOURCES USED [optional] 645 646 When the code is written for a specific target processor the 647 the resources used should be documented below. 648 649 HEAP MEMORY USED: x bytes 650 651 STACK MEMORY USED: x bytes 652 653 CLOCK CYCLES: (cycle count equation for this function) + (variable 654 used to represent cycle count for each subroutine 655 called) 656 where: (cycle count variable) = cycle count for [subroutine 657 name] 658 659 ------------------------------------------------------------------------------ 660 CAUTION [optional] 661 [State any special notes, constraints or cautions for users of this function] 662 663 ------------------------------------------------------------------------------ 664 */ 665 666 void dtx_enc(dtx_encState *st, /* i/o : State struct */ 667 Word16 computeSidFlag, /* i : compute SID */ 668 Q_plsfState *qSt, /* i/o : Qunatizer state struct */ 669 gc_predState* predState, /* i/o : State struct */ 670 Word16 **anap, /* o : analysis parameters */ 671 Flag *pOverflow /* i/o : overflow indicator */ 672 ) 673 { 674 Word16 i, j; 675 Word16 temp; 676 Word16 log_en; 677 Word16 lsf[M]; 678 Word16 lsp[M]; 679 Word16 lsp_q[M]; 680 Word32 L_lsp[M]; 681 682 /* VOX mode computation of SID parameters */ 683 684 if ((computeSidFlag != 0) || 685 (st->log_en_index == 0)) 686 { 687 /* compute new SID frame if safe i.e don't 688 * compute immediately after a talk spurt */ 689 log_en = 0; 690 for (i = M - 1; i >= 0; i--) 691 { 692 L_lsp[i] = 0; 693 } 694 695 /* average energy and lsp */ 696 for (i = DTX_HIST_SIZE - 1; i >= 0; i--) 697 { 698 if (st->log_en_hist[i] < 0) 699 { 700 temp = ~((~(st->log_en_hist[i])) >> 2); 701 } 702 else 703 { 704 temp = st->log_en_hist[i] >> 2; 705 } 706 log_en = add(log_en, temp, pOverflow); 707 708 for (j = M - 1; j >= 0; j--) 709 { 710 L_lsp[j] = L_add(L_lsp[j], 711 (Word32)(st->lsp_hist[i * M + j]), 712 pOverflow); 713 } 714 } 715 716 if (log_en < 0) 717 { 718 log_en = ~((~log_en) >> 1); 719 } 720 else 721 { 722 log_en = log_en >> 1; 723 } 724 725 for (j = M - 1; j >= 0; j--) 726 { 727 /* divide by 8 */ 728 if (L_lsp[j] < 0) 729 { 730 lsp[j] = (Word16)(~((~L_lsp[j]) >> 3)); 731 } 732 else 733 { 734 lsp[j] = (Word16)(L_lsp[j] >> 3); 735 } 736 } 737 738 /* quantize logarithmic energy to 6 bits */ 739 /* +2.5 in Q10 */ 740 st->log_en_index = add(log_en, 2560, pOverflow); 741 /* add 0.5/4 in Q10 */ 742 st->log_en_index = add(st->log_en_index, 128, pOverflow); 743 if (st->log_en_index < 0) 744 { 745 st->log_en_index = ~((~st->log_en_index) >> 8); 746 } 747 else 748 { 749 st->log_en_index = st->log_en_index >> 8; 750 } 751 752 /*---------------------------------------------*/ 753 /* Limit to max and min allowable 6-bit values */ 754 /* Note: For assembly implementation, use the */ 755 /* following: */ 756 /* if(st->long_en_index >> 6 != 0) */ 757 /* { */ 758 /* if(st->long_en_index < 0) */ 759 /* { */ 760 /* st->long_en_index = 0 */ 761 /* } */ 762 /* else */ 763 /* { */ 764 /* st->long_en_index = 63 */ 765 /* } */ 766 /* } */ 767 /*---------------------------------------------*/ 768 if (st->log_en_index > 63) 769 { 770 st->log_en_index = 63; 771 } 772 else if (st->log_en_index < 0) 773 { 774 st->log_en_index = 0; 775 } 776 777 /* update gain predictor memory */ 778 /* Q11 and divide by 4 */ 779 log_en = (Word16)(((Word32) st->log_en_index) << (-2 + 10)); 780 781 log_en = sub(log_en, 11560, pOverflow); 782 783 if (log_en > 0) 784 { 785 log_en = 0; 786 } 787 else if (log_en < -14436) 788 { 789 log_en = -14436; 790 } 791 792 /* past_qua_en for other modes than MR122 */ 793 predState->past_qua_en[0] = log_en; 794 predState->past_qua_en[1] = log_en; 795 predState->past_qua_en[2] = log_en; 796 predState->past_qua_en[3] = log_en; 797 798 /* scale down by factor 20*log10(2) in Q15 */ 799 log_en = (Word16)(((Word32)(5443 * log_en)) >> 15); 800 801 /* past_qua_en for mode MR122 */ 802 predState->past_qua_en_MR122[0] = log_en; 803 predState->past_qua_en_MR122[1] = log_en; 804 predState->past_qua_en_MR122[2] = log_en; 805 predState->past_qua_en_MR122[3] = log_en; 806 807 /* make sure that LSP's are ordered */ 808 Lsp_lsf(lsp, lsf, M, pOverflow); 809 Reorder_lsf(lsf, LSF_GAP, M, pOverflow); 810 Lsf_lsp(lsf, lsp, M, pOverflow); 811 812 /* Quantize lsp and put on parameter list */ 813 Q_plsf_3(qSt, MRDTX, lsp, lsp_q, st->lsp_index, 814 &st->init_lsf_vq_index, pOverflow); 815 } 816 817 *(*anap)++ = st->init_lsf_vq_index; /* 3 bits */ 818 *(*anap)++ = st->lsp_index[0]; /* 8 bits */ 819 *(*anap)++ = st->lsp_index[1]; /* 9 bits */ 820 *(*anap)++ = st->lsp_index[2]; /* 9 bits */ 821 *(*anap)++ = st->log_en_index; /* 6 bits */ 822 /* = 35 bits */ 823 824 } 825 826 /****************************************************************************/ 827 828 829 /* 830 ------------------------------------------------------------------------------ 831 FUNCTION NAME: dtx_buffer 832 ------------------------------------------------------------------------------ 833 INPUT AND OUTPUT DEFINITIONS 834 835 Inputs: 836 st = pointer to structures of type dtx_encState 837 lsp_new = LSP vector whose elements are of type Word16; vector 838 length is M 839 speech = vector of speech samples of type Word16; vector length is 840 BFR_SIZE_GSM 841 842 Outputs: 843 structure pointed to by st contains the new LSPs and logarithmic 844 frame energy 845 846 Returns: 847 return_value = 0 (int) 848 849 Global Variables Used: 850 None 851 852 Local Variables Needed: 853 None 854 855 ------------------------------------------------------------------------------ 856 FUNCTION DESCRIPTION 857 858 This function handles the DTX buffer. 859 860 ------------------------------------------------------------------------------ 861 REQUIREMENTS 862 863 None 864 865 ------------------------------------------------------------------------------ 866 REFERENCES 867 868 dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 869 870 ------------------------------------------------------------------------------ 871 PSEUDO-CODE 872 873 int dtx_buffer(dtx_encState *st, // i/o : State struct 874 Word16 lsp_new[], // i : LSP vector 875 Word16 speech[] // i : speech samples 876 ) 877 { 878 Word16 i; 879 Word32 L_frame_en; 880 Word16 log_en_e; 881 Word16 log_en_m; 882 Word16 log_en; 883 884 // update pointer to circular buffer 885 st->hist_ptr = add(st->hist_ptr, 1); 886 if (sub(st->hist_ptr, DTX_HIST_SIZE) == 0) 887 { 888 st->hist_ptr = 0; 889 } 890 891 // copy lsp vector into buffer 892 Copy(lsp_new, &st->lsp_hist[st->hist_ptr * M], M); 893 894 // compute log energy based on frame energy 895 L_frame_en = 0; // Q0 896 for (i=0; i < L_FRAME; i++) 897 { 898 L_frame_en = L_mac(L_frame_en, speech[i], speech[i]); 899 } 900 Log2(L_frame_en, &log_en_e, &log_en_m); 901 902 // convert exponent and mantissa to Word16 Q10 903 log_en = shl(log_en_e, 10); // Q10 904 log_en = add(log_en, shr(log_en_m, 15-10)); 905 906 // divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193 907 log_en = sub(log_en, 8521); 908 909 // insert into log energy buffer with division by 2 910 log_en = shr(log_en, 1); 911 st->log_en_hist[st->hist_ptr] = log_en; // Q10 912 913 return 0; 914 } 915 916 ------------------------------------------------------------------------------ 917 RESOURCES USED [optional] 918 919 When the code is written for a specific target processor the 920 the resources used should be documented below. 921 922 HEAP MEMORY USED: x bytes 923 924 STACK MEMORY USED: x bytes 925 926 CLOCK CYCLES: (cycle count equation for this function) + (variable 927 used to represent cycle count for each subroutine 928 called) 929 where: (cycle count variable) = cycle count for [subroutine 930 name] 931 932 ------------------------------------------------------------------------------ 933 CAUTION [optional] 934 [State any special notes, constraints or cautions for users of this function] 935 936 ------------------------------------------------------------------------------ 937 */ 938 939 void dtx_buffer(dtx_encState *st, /* i/o : State struct */ 940 Word16 lsp_new[], /* i : LSP vector */ 941 Word16 speech[], /* i : speech samples */ 942 Flag *pOverflow /* i/o : overflow indicator */ 943 ) 944 { 945 946 Word16 i; 947 Word32 L_frame_en; 948 Word32 L_temp; 949 Word16 log_en_e; 950 Word16 log_en_m; 951 Word16 log_en; 952 Word16 *p_speech = &speech[0]; 953 954 /* update pointer to circular buffer */ 955 st->hist_ptr += 1; 956 957 if (st->hist_ptr == DTX_HIST_SIZE) 958 { 959 st->hist_ptr = 0; 960 } 961 962 /* copy lsp vector into buffer */ 963 memcpy(&st->lsp_hist[st->hist_ptr * M], lsp_new, M*sizeof(Word16)); 964 965 /* compute log energy based on frame energy */ 966 L_frame_en = 0; /* Q0 */ 967 968 for (i = L_FRAME; i != 0; i--) 969 { 970 L_frame_en += (((Word32) * p_speech) * *(p_speech)) << 1; 971 p_speech++; 972 if (L_frame_en < 0) 973 { 974 L_frame_en = MAX_32; 975 break; 976 } 977 } 978 979 Log2(L_frame_en, &log_en_e, &log_en_m, pOverflow); 980 981 /* convert exponent and mantissa to Word16 Q10 */ 982 /* Q10 */ 983 L_temp = ((Word32) log_en_e) << 10; 984 if (L_temp != (Word32)((Word16) L_temp)) 985 { 986 *pOverflow = 1; 987 log_en = (log_en_e > 0) ? MAX_16 : MIN_16; 988 } 989 else 990 { 991 log_en = (Word16) L_temp; 992 } 993 994 log_en += log_en_m >> (15 - 10); 995 996 /* divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193 */ 997 log_en -= 8521; 998 999 /* insert into log energy buffer with division by 2 */ 1000 1001 st->log_en_hist[st->hist_ptr] = log_en >> 1; /* Q10 */ 1002 1003 } 1004 1005 /****************************************************************************/ 1006 1007 /* 1008 ------------------------------------------------------------------------------ 1009 FUNCTION NAME: tx_dtx_handler 1010 ------------------------------------------------------------------------------ 1011 INPUT AND OUTPUT DEFINITIONS 1012 1013 Inputs: 1014 st = pointer to structures of type dtx_encState 1015 vad_flag = VAD decision flag of type Word16 1016 usedMode = pointer to the currently used mode of type enum Mode 1017 1018 Outputs: 1019 structure pointed to by st contains the newly calculated speech 1020 hangover 1021 1022 Returns: 1023 compute_new_sid_possible = flag to indicate a change in the 1024 used mode; store type is Word16 1025 1026 Global Variables Used: 1027 None 1028 1029 Local Variables Needed: 1030 None 1031 1032 ------------------------------------------------------------------------------ 1033 FUNCTION DESCRIPTION 1034 1035 This function adds extra speech hangover to analyze speech on the decoding 1036 side. 1037 1038 ------------------------------------------------------------------------------ 1039 REQUIREMENTS 1040 1041 None 1042 1043 ------------------------------------------------------------------------------ 1044 REFERENCES 1045 1046 dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 1047 1048 ------------------------------------------------------------------------------ 1049 PSEUDO-CODE 1050 1051 Word16 tx_dtx_handler(dtx_encState *st, // i/o : State struct 1052 Word16 vad_flag, // i : vad decision 1053 enum Mode *usedMode // i/o : mode changed or not 1054 ) 1055 { 1056 Word16 compute_new_sid_possible; 1057 1058 // this state machine is in synch with the GSMEFR txDtx machine 1059 st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1); 1060 1061 compute_new_sid_possible = 0; 1062 1063 if (vad_flag != 0) 1064 { 1065 st->dtxHangoverCount = DTX_HANG_CONST; 1066 } 1067 else 1068 { // non-speech 1069 if (st->dtxHangoverCount == 0) 1070 { // out of decoder analysis hangover 1071 st->decAnaElapsedCount = 0; 1072 *usedMode = MRDTX; 1073 compute_new_sid_possible = 1; 1074 } 1075 else 1076 { // in possible analysis hangover 1077 st->dtxHangoverCount = sub(st->dtxHangoverCount, 1); 1078 1079 // decAnaElapsedCount + dtxHangoverCount < DTX_ELAPSED_FRAMES_THRESH 1080 if (sub(add(st->decAnaElapsedCount, st->dtxHangoverCount), 1081 DTX_ELAPSED_FRAMES_THRESH) < 0) 1082 { 1083 *usedMode = MRDTX; 1084 // if short time since decoder update, do not add extra HO 1085 } 1086 // else 1087 // override VAD and stay in 1088 // speech mode *usedMode 1089 // and add extra hangover 1090 } 1091 } 1092 1093 return compute_new_sid_possible; 1094 } 1095 1096 ------------------------------------------------------------------------------ 1097 RESOURCES USED [optional] 1098 1099 When the code is written for a specific target processor the 1100 the resources used should be documented below. 1101 1102 HEAP MEMORY USED: x bytes 1103 1104 STACK MEMORY USED: x bytes 1105 1106 CLOCK CYCLES: (cycle count equation for this function) + (variable 1107 used to represent cycle count for each subroutine 1108 called) 1109 where: (cycle count variable) = cycle count for [subroutine 1110 name] 1111 1112 ------------------------------------------------------------------------------ 1113 CAUTION [optional] 1114 [State any special notes, constraints or cautions for users of this function] 1115 1116 ------------------------------------------------------------------------------ 1117 */ 1118 1119 Word16 tx_dtx_handler(dtx_encState *st, /* i/o : State struct */ 1120 Word16 vad_flag, /* i : vad decision */ 1121 enum Mode *usedMode, /* i/o : mode changed or not */ 1122 Flag *pOverflow /* i/o : overflow indicator */ 1123 ) 1124 { 1125 Word16 compute_new_sid_possible; 1126 Word16 count; 1127 1128 /* this state machine is in synch with the GSMEFR txDtx machine */ 1129 st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1, pOverflow); 1130 1131 compute_new_sid_possible = 0; 1132 1133 if (vad_flag != 0) 1134 { 1135 st->dtxHangoverCount = DTX_HANG_CONST; 1136 } 1137 else 1138 { /* non-speech */ 1139 if (st->dtxHangoverCount == 0) 1140 { /* out of decoder analysis hangover */ 1141 st->decAnaElapsedCount = 0; 1142 *usedMode = MRDTX; 1143 compute_new_sid_possible = 1; 1144 } 1145 else 1146 { /* in possible analysis hangover */ 1147 st->dtxHangoverCount -= 1; 1148 1149 /* decAnaElapsedCount + dtxHangoverCount < */ 1150 /* DTX_ELAPSED_FRAMES_THRESH */ 1151 count = add(st->decAnaElapsedCount, st->dtxHangoverCount, 1152 pOverflow); 1153 if (count < DTX_ELAPSED_FRAMES_THRESH) 1154 { 1155 *usedMode = MRDTX; 1156 /* if short time since decoder update, */ 1157 /* do not add extra HO */ 1158 } 1159 } 1160 } 1161 1162 return(compute_new_sid_possible); 1163 } 1164