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/**************************************************************************************** 19Portions of this file are derived from the following 3GPP standard: 20 21 3GPP TS 26.173 22 ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec 23 Available from http://www.3gpp.org 24 25(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) 26Permission to distribute, modify and use this file under the standard license 27terms listed above has been obtained from the copyright holder. 28****************************************************************************************/ 29/* 30------------------------------------------------------------------------------ 31 32 33 34 Filename: dtx_decoder_amr_wb.cpp 35 36 Date: 05/08/2007 37 38------------------------------------------------------------------------------ 39 REVISION HISTORY 40 41 42 Description: 43 44------------------------------------------------------------------------------ 45 INPUT AND OUTPUT DEFINITIONS 46 47 48------------------------------------------------------------------------------ 49 FUNCTION DESCRIPTION 50 51 DTX functions 52 53------------------------------------------------------------------------------ 54 REQUIREMENTS 55 56 57------------------------------------------------------------------------------ 58 REFERENCES 59 60------------------------------------------------------------------------------ 61 PSEUDO-CODE 62 63------------------------------------------------------------------------------ 64*/ 65 66 67/*---------------------------------------------------------------------------- 68; INCLUDES 69----------------------------------------------------------------------------*/ 70 71#include "pv_amr_wb_type_defs.h" 72#include "pvamrwbdecoder_basic_op.h" 73#include "pvamrwb_math_op.h" 74#include "pvamrwbdecoder_cnst.h" 75#include "pvamrwbdecoder_acelp.h" /* prototype of functions */ 76#include "get_amr_wb_bits.h" 77#include "dtx.h" 78 79/*---------------------------------------------------------------------------- 80; MACROS 81; Define module specific macros here 82----------------------------------------------------------------------------*/ 83 84 85/*---------------------------------------------------------------------------- 86; DEFINES 87; Include all pre-processor statements here. Include conditional 88; compile variables also. 89----------------------------------------------------------------------------*/ 90 91/*---------------------------------------------------------------------------- 92; LOCAL FUNCTION DEFINITIONS 93; Function Prototype declaration 94----------------------------------------------------------------------------*/ 95 96/*---------------------------------------------------------------------------- 97; LOCAL STORE/BUFFER/POINTER DEFINITIONS 98; Variable declaration - defined here and used outside this module 99----------------------------------------------------------------------------*/ 100 101/*---------------------------------------------------------------------------- 102; EXTERNAL FUNCTION REFERENCES 103; Declare functions defined elsewhere and referenced in this module 104----------------------------------------------------------------------------*/ 105 106/*---------------------------------------------------------------------------- 107; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 108; Declare variables used in this module but defined elsewhere 109----------------------------------------------------------------------------*/ 110 111/*---------------------------------------------------------------------------- 112; FUNCTION CODE 113----------------------------------------------------------------------------*/ 114/* 115 * Function : dtx_dec_amr_wb_reset 116 */ 117int16 dtx_dec_amr_wb_reset(dtx_decState * st, const int16 isf_init[]) 118{ 119 int16 i; 120 121 122 if (st == (dtx_decState *) NULL) 123 { 124 /* dtx_dec_amr_wb_reset invalid parameter */ 125 return (-1); 126 } 127 st->since_last_sid = 0; 128 st->true_sid_period_inv = (1 << 13); /* 0.25 in Q15 */ 129 130 st->log_en = 3500; 131 st->old_log_en = 3500; 132 /* low level noise for better performance in DTX handover cases */ 133 134 st->cng_seed = RANDOM_INITSEED; 135 136 st->hist_ptr = 0; 137 138 /* Init isf_hist[] and decoder log frame energy */ 139 pv_memcpy((void *)st->isf, (void *)isf_init, M*sizeof(*isf_init)); 140 141 pv_memcpy((void *)st->isf_old, (void *)isf_init, M*sizeof(*isf_init)); 142 143 for (i = 0; i < DTX_HIST_SIZE; i++) 144 { 145 pv_memcpy((void *)&st->isf_hist[i * M], (void *)isf_init, M*sizeof(*isf_init)); 146 st->log_en_hist[i] = st->log_en; 147 } 148 149 st->dtxHangoverCount = DTX_HANG_CONST; 150 st->decAnaElapsedCount = 32767; 151 152 st->sid_frame = 0; 153 st->valid_data = 0; 154 st->dtxHangoverAdded = 0; 155 156 st->dtxGlobalState = SPEECH; 157 st->data_updated = 0; 158 159 st->dither_seed = RANDOM_INITSEED; 160 st->CN_dith = 0; 161 162 return 0; 163} 164 165 166/* 167 Table of new SPD synthesis states 168 169 | previous SPD_synthesis_state 170 Incoming | 171 frame_type | SPEECH | DTX | DTX_MUTE 172 --------------------------------------------------------------- 173 RX_SPEECH_GOOD , | | | 174 RX_SPEECH_PR_DEGRADED | SPEECH | SPEECH | SPEECH 175 ---------------------------------------------------------------- 176 RX_SPEECH_BAD, | SPEECH | DTX | DTX_MUTE 177 ---------------------------------------------------------------- 178 RX_SID_FIRST, | DTX | DTX/(DTX_MUTE)| DTX_MUTE 179 ---------------------------------------------------------------- 180 RX_SID_UPDATE, | DTX | DTX | DTX 181 ---------------------------------------------------------------- 182 RX_SID_BAD, | DTX | DTX/(DTX_MUTE)| DTX_MUTE 183 ---------------------------------------------------------------- 184 RX_NO_DATA, | SPEECH | DTX/(DTX_MUTE)| DTX_MUTE 185 RX_SPARE |(class2 garb.)| | 186 ---------------------------------------------------------------- 187*/ 188 189/*---------------------------------------------------------------------------- 190; FUNCTION CODE 191----------------------------------------------------------------------------*/ 192 193/* 194 * Function : dtx_dec_amr_wb 195 */ 196int16 dtx_dec_amr_wb( 197 dtx_decState * st, /* i/o : State struct */ 198 int16 * exc2, /* o : CN excitation */ 199 int16 new_state, /* i : New DTX state */ 200 int16 isf[], /* o : CN ISF vector */ 201 int16 ** prms 202) 203{ 204 int16 log_en_index; 205 int16 ind[7]; 206 int16 i, j; 207 int16 int_fac; 208 int16 gain; 209 210 int32 L_isf[M], L_log_en_int, level32, ener32; 211 int16 ptr; 212 int16 tmp_int_length; 213 int16 tmp, exp, exp0, log_en_int_e, log_en_int_m, level; 214 215 /* This function is called if synthesis state is not SPEECH the globally passed inputs to this function 216 * are st->sid_frame st->valid_data st->dtxHangoverAdded new_state (SPEECH, DTX, DTX_MUTE) */ 217 218 if ((st->dtxHangoverAdded != 0) && 219 (st->sid_frame != 0)) 220 { 221 /* sid_first after dtx hangover period */ 222 /* or sid_upd after dtxhangover */ 223 224 /* consider twice the last frame */ 225 ptr = st->hist_ptr + 1; 226 227 if (ptr == DTX_HIST_SIZE) 228 ptr = 0; 229 230 pv_memcpy((void *)&st->isf_hist[ptr * M], (void *)&st->isf_hist[st->hist_ptr * M], M*sizeof(*st->isf_hist)); 231 232 st->log_en_hist[ptr] = st->log_en_hist[st->hist_ptr]; 233 234 /* compute mean log energy and isf from decoded signal (SID_FIRST) */ 235 st->log_en = 0; 236 for (i = 0; i < M; i++) 237 { 238 L_isf[i] = 0; 239 } 240 241 /* average energy and isf */ 242 for (i = 0; i < DTX_HIST_SIZE; i++) 243 { 244 /* Division by DTX_HIST_SIZE = 8 has been done in dtx_buffer log_en is in Q10 */ 245 st->log_en = add_int16(st->log_en, st->log_en_hist[i]); 246 247 for (j = 0; j < M; j++) 248 { 249 L_isf[j] = add_int32(L_isf[j], (int32)(st->isf_hist[i * M + j])); 250 } 251 } 252 253 /* st->log_en in Q9 */ 254 st->log_en >>= 1; 255 256 /* Add 2 in Q9, in order to have only positive values for Pow2 */ 257 /* this value is subtracted back after Pow2 function */ 258 st->log_en += 1024; 259 260 if (st->log_en < 0) 261 st->log_en = 0; 262 263 for (j = 0; j < M; j++) 264 { 265 st->isf[j] = (int16)(L_isf[j] >> 3); /* divide by 8 */ 266 } 267 268 } 269 270 if (st->sid_frame != 0) 271 { 272 /* Set old SID parameters, always shift */ 273 /* even if there is no new valid_data */ 274 275 pv_memcpy((void *)st->isf_old, (void *)st->isf, M*sizeof(*st->isf)); 276 277 st->old_log_en = st->log_en; 278 279 if (st->valid_data != 0) /* new data available (no CRC) */ 280 { 281 /* st->true_sid_period_inv = 1.0f/st->since_last_sid; */ 282 /* Compute interpolation factor, since the division only works * for values of since_last_sid < 283 * 32 we have to limit the * interpolation to 32 frames */ 284 tmp_int_length = st->since_last_sid; 285 286 287 if (tmp_int_length > 32) 288 { 289 tmp_int_length = 32; 290 } 291 292 if (tmp_int_length >= 2) 293 { 294 st->true_sid_period_inv = div_16by16(1 << 10, shl_int16(tmp_int_length, 10)); 295 } 296 else 297 { 298 st->true_sid_period_inv = 1 << 14; /* 0.5 it Q15 */ 299 } 300 301 ind[0] = Serial_parm(6, prms); 302 ind[1] = Serial_parm(6, prms); 303 ind[2] = Serial_parm(6, prms); 304 ind[3] = Serial_parm(5, prms); 305 ind[4] = Serial_parm(5, prms); 306 307 Disf_ns(ind, st->isf); 308 309 log_en_index = Serial_parm(6, prms); 310 311 /* read background noise stationarity information */ 312 st->CN_dith = Serial_parm_1bit(prms); 313 314 /* st->log_en = (float)log_en_index / 2.625 - 2.0; */ 315 /* log2(E) in Q9 (log2(E) lies in between -2:22) */ 316 st->log_en = shl_int16(log_en_index, 15 - 6); 317 318 /* Divide by 2.625 */ 319 st->log_en = mult_int16(st->log_en, 12483); 320 /* Subtract 2 in Q9 is done later, after Pow2 function */ 321 322 /* no interpolation at startup after coder reset */ 323 /* or when SID_UPD has been received right after SPEECH */ 324 325 if ((st->data_updated == 0) || (st->dtxGlobalState == SPEECH)) 326 { 327 pv_memcpy((void *)st->isf_old, (void *)st->isf, M*sizeof(*st->isf)); 328 329 st->old_log_en = st->log_en; 330 } 331 } /* endif valid_data */ 332 } /* endif sid_frame */ 333 334 335 if ((st->sid_frame != 0) && (st->valid_data != 0)) 336 { 337 st->since_last_sid = 0; 338 } 339 /* Interpolate SID info */ 340 int_fac = shl_int16(st->since_last_sid, 10); /* Q10 */ 341 int_fac = mult_int16(int_fac, st->true_sid_period_inv); /* Q10 * Q15 -> Q10 */ 342 343 /* Maximize to 1.0 in Q10 */ 344 345 if (int_fac > 1024) 346 { 347 int_fac = 1024; 348 } 349 int_fac = shl_int16(int_fac, 4); /* Q10 -> Q14 */ 350 351 L_log_en_int = mul_16by16_to_int32(int_fac, st->log_en); /* Q14 * Q9 -> Q24 */ 352 353 for (i = 0; i < M; i++) 354 { 355 isf[i] = mult_int16(int_fac, st->isf[i]);/* Q14 * Q15 -> Q14 */ 356 } 357 358 int_fac = 16384 - int_fac; /* 1-k in Q14 */ 359 360 /* ( Q14 * Q9 -> Q24 ) + Q24 -> Q24 */ 361 L_log_en_int = mac_16by16_to_int32(L_log_en_int, int_fac, st->old_log_en); 362 363 for (i = 0; i < M; i++) 364 { 365 /* Q14 + (Q14 * Q15 -> Q14) -> Q14 */ 366 isf[i] = add_int16(isf[i], mult_int16(int_fac, st->isf_old[i])); 367 isf[i] = shl_int16(isf[i], 1); /* Q14 -> Q15 */ 368 } 369 370 /* If background noise is non-stationary, insert comfort noise dithering */ 371 if (st->CN_dith != 0) 372 { 373 CN_dithering(isf, &L_log_en_int, &st->dither_seed); 374 } 375 /* L_log_en_int corresponds to log2(E)+2 in Q24, i.e log2(gain)+1 in Q25 */ 376 /* Q25 -> Q16 */ 377 L_log_en_int >>= 9; 378 379 /* Find integer part */ 380 log_en_int_e = extract_h(L_log_en_int); 381 382 /* Find fractional part */ 383 log_en_int_m = (int16)(sub_int32(L_log_en_int, L_deposit_h(log_en_int_e)) >> 1); 384 385 /* Subtract 2 from L_log_en_int in Q9, i.e divide the gain by 2 (energy by 4) */ 386 /* Add 16 in order to have the result of pow2 in Q16 */ 387 log_en_int_e += 15; 388 389 /* level = (float)( pow( 2.0f, log_en ) ); */ 390 level32 = power_of_2(log_en_int_e, log_en_int_m); /* Q16 */ 391 392 exp0 = normalize_amr_wb(level32); 393 level32 <<= exp0; /* level in Q31 */ 394 exp0 = 15 - exp0; 395 level = (int16)(level32 >> 16); /* level in Q15 */ 396 397 /* generate white noise vector */ 398 for (i = 0; i < L_FRAME; i++) 399 { 400 exc2[i] = noise_gen_amrwb(&(st->cng_seed)) >> 4; 401 } 402 403 /* gain = level / sqrt(ener) * sqrt(L_FRAME) */ 404 405 /* energy of generated excitation */ 406 ener32 = Dot_product12(exc2, exc2, L_FRAME, &exp); 407 408 one_ov_sqrt_norm(&ener32, &exp); 409 410 gain = extract_h(ener32); 411 412 gain = mult_int16(level, gain); /* gain in Q15 */ 413 414 exp += exp0; 415 416 /* Multiply by sqrt(L_FRAME)=16, i.e. shift left by 4 */ 417 exp += 4; 418 419 for (i = 0; i < L_FRAME; i++) 420 { 421 tmp = mult_int16(exc2[i], gain); /* Q0 * Q15 */ 422 exc2[i] = shl_int16(tmp, exp); 423 } 424 425 426 if (new_state == DTX_MUTE) 427 { 428 /* mute comfort noise as it has been quite a long time since last SID update was performed */ 429 430 tmp_int_length = st->since_last_sid; 431 432 if (tmp_int_length > 32) 433 { 434 tmp_int_length = 32; 435 } 436 437 st->true_sid_period_inv = div_16by16(1 << 10, shl_int16(tmp_int_length, 10)); 438 439 st->since_last_sid = 0; 440 st->old_log_en = st->log_en; 441 /* subtract 1/8 in Q9 (energy), i.e -3/8 dB */ 442 st->log_en -= 64; 443 } 444 /* reset interpolation length timer if data has been updated. */ 445 446 if ((st->sid_frame != 0) && 447 ((st->valid_data != 0) || 448 ((st->valid_data == 0) && (st->dtxHangoverAdded) != 0))) 449 { 450 st->since_last_sid = 0; 451 st->data_updated = 1; 452 } 453 return 0; 454} 455 456 457/*---------------------------------------------------------------------------- 458; FUNCTION CODE 459----------------------------------------------------------------------------*/ 460 461void dtx_dec_amr_wb_activity_update( 462 dtx_decState * st, 463 int16 isf[], 464 int16 exc[]) 465{ 466 int16 i; 467 468 int32 L_frame_en; 469 int16 log_en_e, log_en_m, log_en; 470 471 472 st->hist_ptr++; 473 474 if (st->hist_ptr == DTX_HIST_SIZE) 475 { 476 st->hist_ptr = 0; 477 } 478 pv_memcpy((void *)&st->isf_hist[st->hist_ptr * M], (void *)isf, M*sizeof(*isf)); 479 480 481 /* compute log energy based on excitation frame energy in Q0 */ 482 L_frame_en = 0; 483 for (i = 0; i < L_FRAME; i++) 484 { 485 L_frame_en = mac_16by16_to_int32(L_frame_en, exc[i], exc[i]); 486 } 487 L_frame_en >>= 1; 488 489 /* log_en = (float)log10(L_frame_en/(float)L_FRAME)/(float)log10(2.0f); */ 490 amrwb_log_2(L_frame_en, &log_en_e, &log_en_m); 491 492 /* convert exponent and mantissa to int16 Q7. Q7 is used to simplify averaging in dtx_enc */ 493 log_en = shl_int16(log_en_e, 7); /* Q7 */ 494 log_en += log_en_m >> 8; 495 496 /* Divide by L_FRAME = 256, i.e subtract 8 in Q7 = 1024 */ 497 log_en -= 1024; 498 499 /* insert into log energy buffer */ 500 st->log_en_hist[st->hist_ptr] = log_en; 501 502 return; 503} 504 505 506/* 507 Table of new SPD synthesis states 508 509 | previous SPD_synthesis_state 510 Incoming | 511 frame_type | SPEECH | DTX | DTX_MUTE 512 --------------------------------------------------------------- 513 RX_SPEECH_GOOD , | | | 514 RX_SPEECH_PR_DEGRADED | SPEECH | SPEECH | SPEECH 515 ---------------------------------------------------------------- 516 RX_SPEECH_BAD, | SPEECH | DTX | DTX_MUTE 517 ---------------------------------------------------------------- 518 RX_SID_FIRST, | DTX | DTX/(DTX_MUTE)| DTX_MUTE 519 ---------------------------------------------------------------- 520 RX_SID_UPDATE, | DTX | DTX | DTX 521 ---------------------------------------------------------------- 522 RX_SID_BAD, | DTX | DTX/(DTX_MUTE)| DTX_MUTE 523 ---------------------------------------------------------------- 524 RX_NO_DATA, | SPEECH | DTX/(DTX_MUTE)| DTX_MUTE 525 RX_SPARE |(class2 garb.)| | 526 ---------------------------------------------------------------- 527*/ 528 529 530/*---------------------------------------------------------------------------- 531; FUNCTION CODE 532----------------------------------------------------------------------------*/ 533 534int16 rx_amr_wb_dtx_handler( 535 dtx_decState * st, /* i/o : State struct */ 536 int16 frame_type /* i : Frame type */ 537) 538{ 539 int16 newState; 540 int16 encState; 541 542 /* DTX if SID frame or previously in DTX{_MUTE} and (NO_RX OR BAD_SPEECH) */ 543 544 545 546 if ((frame_type == RX_SID_FIRST) || 547 (frame_type == RX_SID_UPDATE) || 548 (frame_type == RX_SID_BAD) || 549 (((st->dtxGlobalState == DTX) || 550 (st->dtxGlobalState == DTX_MUTE)) && 551 ((frame_type == RX_NO_DATA) || 552 (frame_type == RX_SPEECH_BAD) || 553 (frame_type == RX_SPEECH_LOST)))) 554 { 555 newState = DTX; 556 557 /* stay in mute for these input types */ 558 559 if ((st->dtxGlobalState == DTX_MUTE) && 560 ((frame_type == RX_SID_BAD) || 561 (frame_type == RX_SID_FIRST) || 562 (frame_type == RX_SPEECH_LOST) || 563 (frame_type == RX_NO_DATA))) 564 { 565 newState = DTX_MUTE; 566 } 567 /* evaluate if noise parameters are too old */ 568 /* since_last_sid is reset when CN parameters have been updated */ 569 st->since_last_sid = add_int16(st->since_last_sid, 1); 570 571 /* no update of sid parameters in DTX for a long while */ 572 573 if (st->since_last_sid > DTX_MAX_EMPTY_THRESH) 574 { 575 newState = DTX_MUTE; 576 } 577 } 578 else 579 { 580 newState = SPEECH; 581 st->since_last_sid = 0; 582 } 583 584 /* reset the decAnaElapsed Counter when receiving CNI data the first time, to robustify counter missmatch 585 * after handover this might delay the bwd CNI analysis in the new decoder slightly. */ 586 587 if ((st->data_updated == 0) && 588 (frame_type == RX_SID_UPDATE)) 589 { 590 st->decAnaElapsedCount = 0; 591 } 592 /* update the SPE-SPD DTX hangover synchronization */ 593 /* to know when SPE has added dtx hangover */ 594 st->decAnaElapsedCount = add_int16(st->decAnaElapsedCount, 1); 595 st->dtxHangoverAdded = 0; 596 597 598 if ((frame_type == RX_SID_FIRST) || 599 (frame_type == RX_SID_UPDATE) || 600 (frame_type == RX_SID_BAD) || 601 (frame_type == RX_NO_DATA)) 602 { 603 encState = DTX; 604 } 605 else 606 { 607 encState = SPEECH; 608 } 609 610 611 if (encState == SPEECH) 612 { 613 st->dtxHangoverCount = DTX_HANG_CONST; 614 } 615 else 616 { 617 618 if (st->decAnaElapsedCount > DTX_ELAPSED_FRAMES_THRESH) 619 { 620 st->dtxHangoverAdded = 1; 621 st->decAnaElapsedCount = 0; 622 st->dtxHangoverCount = 0; 623 } 624 else if (st->dtxHangoverCount == 0) 625 { 626 st->decAnaElapsedCount = 0; 627 } 628 else 629 { 630 st->dtxHangoverCount--; 631 } 632 } 633 634 if (newState != SPEECH) 635 { 636 /* DTX or DTX_MUTE CN data is not in a first SID, first SIDs are marked as SID_BAD but will do 637 * backwards analysis if a hangover period has been added according to the state machine above */ 638 639 st->sid_frame = 0; 640 st->valid_data = 0; 641 642 643 if (frame_type == RX_SID_FIRST) 644 { 645 st->sid_frame = 1; 646 } 647 else if (frame_type == RX_SID_UPDATE) 648 { 649 st->sid_frame = 1; 650 st->valid_data = 1; 651 } 652 else if (frame_type == RX_SID_BAD) 653 { 654 st->sid_frame = 1; 655 st->dtxHangoverAdded = 0; /* use old data */ 656 } 657 } 658 return newState; 659 /* newState is used by both SPEECH AND DTX synthesis routines */ 660} 661 662 663/*---------------------------------------------------------------------------- 664; FUNCTION CODE 665----------------------------------------------------------------------------*/ 666 667void aver_isf_history( 668 int16 isf_old[], 669 int16 indices[], 670 int32 isf_aver[] 671) 672{ 673 int16 i, j, k; 674 int16 isf_tmp[2 * M]; 675 int32 L_tmp; 676 677 /* Memorize in isf_tmp[][] the ISF vectors to be replaced by */ 678 /* the median ISF vector prior to the averaging */ 679 for (k = 0; k < 2; k++) 680 { 681 682 if (indices[k] + 1 != 0) 683 { 684 for (i = 0; i < M; i++) 685 { 686 isf_tmp[k * M + i] = isf_old[indices[k] * M + i]; 687 isf_old[indices[k] * M + i] = isf_old[indices[2] * M + i]; 688 } 689 } 690 } 691 692 /* Perform the ISF averaging */ 693 for (j = 0; j < M; j++) 694 { 695 L_tmp = 0; 696 697 for (i = 0; i < DTX_HIST_SIZE; i++) 698 { 699 L_tmp = add_int32(L_tmp, (int32)(isf_old[i * M + j])); 700 } 701 isf_aver[j] = L_tmp; 702 } 703 704 /* Retrieve from isf_tmp[][] the ISF vectors saved prior to averaging */ 705 for (k = 0; k < 2; k++) 706 { 707 708 if (indices[k] + 1 != 0) 709 { 710 for (i = 0; i < M; i++) 711 { 712 isf_old[indices[k] * M + i] = isf_tmp[k * M + i]; 713 } 714 } 715 } 716 717 return; 718} 719 720 721/*---------------------------------------------------------------------------- 722; FUNCTION CODE 723----------------------------------------------------------------------------*/ 724 725void find_frame_indices( 726 int16 isf_old_tx[], 727 int16 indices[], 728 dtx_encState * st 729) 730{ 731 int32 L_tmp, summin, summax, summax2nd; 732 int16 i, j, tmp; 733 int16 ptr; 734 735 /* Remove the effect of the oldest frame from the column */ 736 /* sum sumD[0..DTX_HIST_SIZE-1]. sumD[DTX_HIST_SIZE] is */ 737 /* not updated since it will be removed later. */ 738 739 tmp = DTX_HIST_SIZE_MIN_ONE; 740 j = -1; 741 for (i = 0; i < DTX_HIST_SIZE_MIN_ONE; i++) 742 { 743 j += tmp; 744 st->sumD[i] = sub_int32(st->sumD[i], st->D[j]); 745 tmp--; 746 } 747 748 /* Shift the column sum sumD. The element sumD[DTX_HIST_SIZE-1] */ 749 /* corresponding to the oldest frame is removed. The sum of */ 750 /* the distances between the latest isf and other isfs, */ 751 /* i.e. the element sumD[0], will be computed during this call. */ 752 /* Hence this element is initialized to zero. */ 753 754 for (i = DTX_HIST_SIZE_MIN_ONE; i > 0; i--) 755 { 756 st->sumD[i] = st->sumD[i - 1]; 757 } 758 st->sumD[0] = 0; 759 760 /* Remove the oldest frame from the distance matrix. */ 761 /* Note that the distance matrix is replaced by a one- */ 762 /* dimensional array to save static memory. */ 763 764 tmp = 0; 765 for (i = 27; i >= 12; i -= tmp) 766 { 767 tmp++; 768 for (j = tmp; j > 0; j--) 769 { 770 st->D[i - j + 1] = st->D[i - j - tmp]; 771 } 772 } 773 774 /* Compute the first column of the distance matrix D */ 775 /* (squared Euclidean distances from isf1[] to isf_old_tx[][]). */ 776 777 ptr = st->hist_ptr; 778 for (i = 1; i < DTX_HIST_SIZE; i++) 779 { 780 /* Compute the distance between the latest isf and the other isfs. */ 781 ptr--; 782 783 if (ptr < 0) 784 { 785 ptr = DTX_HIST_SIZE_MIN_ONE; 786 } 787 L_tmp = 0; 788 for (j = 0; j < M; j++) 789 { 790 tmp = sub_int16(isf_old_tx[st->hist_ptr * M + j], isf_old_tx[ptr * M + j]); 791 L_tmp = mac_16by16_to_int32(L_tmp, tmp, tmp); 792 } 793 st->D[i - 1] = L_tmp; 794 795 /* Update also the column sums. */ 796 st->sumD[0] = add_int32(st->sumD[0], st->D[i - 1]); 797 st->sumD[i] = add_int32(st->sumD[i], st->D[i - 1]); 798 } 799 800 /* Find the minimum and maximum distances */ 801 summax = st->sumD[0]; 802 summin = st->sumD[0]; 803 indices[0] = 0; 804 indices[2] = 0; 805 for (i = 1; i < DTX_HIST_SIZE; i++) 806 { 807 808 if (st->sumD[i] > summax) 809 { 810 indices[0] = i; 811 summax = st->sumD[i]; 812 } 813 814 if (st->sumD[i] < summin) 815 { 816 indices[2] = i; 817 summin = st->sumD[i]; 818 } 819 } 820 821 /* Find the second largest distance */ 822 summax2nd = -2147483647L; 823 indices[1] = -1; 824 for (i = 0; i < DTX_HIST_SIZE; i++) 825 { 826 827 if ((st->sumD[i] > summax2nd) && (i != indices[0])) 828 { 829 indices[1] = i; 830 summax2nd = st->sumD[i]; 831 } 832 } 833 834 for (i = 0; i < 3; i++) 835 { 836 indices[i] = sub_int16(st->hist_ptr, indices[i]); 837 838 if (indices[i] < 0) 839 { 840 indices[i] = add_int16(indices[i], DTX_HIST_SIZE); 841 } 842 } 843 844 /* If maximum distance/MED_THRESH is smaller than minimum distance */ 845 /* then the median ISF vector replacement is not performed */ 846 tmp = normalize_amr_wb(summax); 847 summax <<= tmp; 848 summin <<= tmp; 849 L_tmp = mul_16by16_to_int32(amr_wb_round(summax), INV_MED_THRESH); 850 851 if (L_tmp <= summin) 852 { 853 indices[0] = -1; 854 } 855 /* If second largest distance/MED_THRESH is smaller than */ 856 /* minimum distance then the median ISF vector replacement is */ 857 /* not performed */ 858 summax2nd = shl_int32(summax2nd, tmp); 859 L_tmp = mul_16by16_to_int32(amr_wb_round(summax2nd), INV_MED_THRESH); 860 861 if (L_tmp <= summin) 862 { 863 indices[1] = -1; 864 } 865 return; 866} 867 868 869/*---------------------------------------------------------------------------- 870; FUNCTION CODE 871----------------------------------------------------------------------------*/ 872 873int16 dithering_control(dtx_encState * st) 874{ 875 int16 i, tmp, mean, CN_dith, gain_diff; 876 int32 ISF_diff; 877 878 /* determine how stationary the spectrum of background noise is */ 879 ISF_diff = 0; 880 for (i = 0; i < 8; i++) 881 { 882 ISF_diff = add_int32(ISF_diff, st->sumD[i]); 883 } 884 if ((ISF_diff >> 26) > 0) 885 { 886 CN_dith = 1; 887 } 888 else 889 { 890 CN_dith = 0; 891 } 892 893 /* determine how stationary the energy of background noise is */ 894 mean = 0; 895 for (i = 0; i < DTX_HIST_SIZE; i++) 896 { 897 mean = add_int16(mean, st->log_en_hist[i]); 898 } 899 mean >>= 3; 900 gain_diff = 0; 901 for (i = 0; i < DTX_HIST_SIZE; i++) 902 { 903 tmp = sub_int16(st->log_en_hist[i], mean); 904 tmp = tmp - (tmp < 0); 905 906 gain_diff += tmp ^(tmp >> 15); /* tmp ^sign(tmp) */; 907 } 908 if (gain_diff > GAIN_THR) 909 { 910 CN_dith = 1; 911 } 912 return CN_dith; 913} 914 915 916/*---------------------------------------------------------------------------- 917; FUNCTION CODE 918----------------------------------------------------------------------------*/ 919 920void CN_dithering( 921 int16 isf[M], 922 int32 * L_log_en_int, 923 int16 * dither_seed 924) 925{ 926 int16 temp, temp1, i, dither_fac, rand_dith; 927 int16 rand_dith2; 928 929 /* Insert comfort noise dithering for energy parameter */ 930 rand_dith = noise_gen_amrwb(dither_seed) >> 1; 931 rand_dith2 = noise_gen_amrwb(dither_seed) >> 1; 932 rand_dith += rand_dith2; 933 *L_log_en_int = add_int32(*L_log_en_int, mul_16by16_to_int32(rand_dith, GAIN_FACTOR)); 934 935 if (*L_log_en_int < 0) 936 { 937 *L_log_en_int = 0; 938 } 939 /* Insert comfort noise dithering for spectral parameters (ISF-vector) */ 940 dither_fac = ISF_FACTOR_LOW; 941 942 rand_dith = noise_gen_amrwb(dither_seed) >> 1; 943 rand_dith2 = noise_gen_amrwb(dither_seed) >> 1; 944 rand_dith += rand_dith2; 945 temp = add_int16(isf[0], mult_int16_r(rand_dith, dither_fac)); 946 947 /* Make sure that isf[0] will not get negative values */ 948 if (temp < ISF_GAP) 949 { 950 isf[0] = ISF_GAP; 951 } 952 else 953 { 954 isf[0] = temp; 955 } 956 957 for (i = 1; i < M - 1; i++) 958 { 959 dither_fac = add_int16(dither_fac, ISF_FACTOR_STEP); 960 961 rand_dith = noise_gen_amrwb(dither_seed) >> 1; 962 rand_dith2 = noise_gen_amrwb(dither_seed) >> 1; 963 rand_dith += rand_dith2; 964 temp = add_int16(isf[i], mult_int16_r(rand_dith, dither_fac)); 965 temp1 = sub_int16(temp, isf[i - 1]); 966 967 /* Make sure that isf spacing remains at least ISF_DITH_GAP Hz */ 968 if (temp1 < ISF_DITH_GAP) 969 { 970 isf[i] = isf[i - 1] + ISF_DITH_GAP; 971 } 972 else 973 { 974 isf[i] = temp; 975 } 976 } 977 978 /* Make sure that isf[M-2] will not get values above 16384 */ 979 if (isf[M - 2] > 16384) 980 { 981 isf[M - 2] = 16384; 982 } 983 return; 984} 985