1e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/* 2e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Copyright 2003-2010, VisualOn, Inc. 3e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** 4e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Licensed under the Apache License, Version 2.0 (the "License"); 5e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** you may not use this file except in compliance with the License. 6e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** You may obtain a copy of the License at 7e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** 8e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** http://www.apache.org/licenses/LICENSE-2.0 9e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** 10e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Unless required by applicable law or agreed to in writing, software 11e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** distributed under the License is distributed on an "AS IS" BASIS, 12e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** See the License for the specific language governing permissions and 14e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** limitations under the License. 15e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard */ 16e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 17e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*********************************************************************** 18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* File: dtx.c * 19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* * 20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Description:DTX functions * 21e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* * 22e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard************************************************************************/ 23e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 24e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include <stdio.h> 25e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include <stdlib.h> 26e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "typedef.h" 27e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "basic_op.h" 28e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "oper_32b.h" 29e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "math_op.h" 30e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "cnst.h" 31e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "acelp.h" /* prototype of functions */ 32e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "bits.h" 33e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "dtx.h" 34e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "log2.h" 35e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "mem_align.h" 36e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 37e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic void aver_isf_history( 38e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 isf_old[], 39e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 indices[], 40e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 isf_aver[] 41e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ); 42e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 43e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic void find_frame_indices( 44e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 isf_old_tx[], 45e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 indices[], 46e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard dtx_encState * st 47e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ); 48e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 49e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 dithering_control( 50e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard dtx_encState * st 51e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ); 52e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 53e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/* excitation energy adjustment depending on speech coder mode used, Q7 */ 54e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 en_adjust[9] = 55e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 56e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 230, /* mode0 = 7k : -5.4dB */ 57e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 179, /* mode1 = 9k : -4.2dB */ 58e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 141, /* mode2 = 12k : -3.3dB */ 59e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 128, /* mode3 = 14k : -3.0dB */ 60e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 122, /* mode4 = 16k : -2.85dB */ 61e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 115, /* mode5 = 18k : -2.7dB */ 62e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 115, /* mode6 = 20k : -2.7dB */ 63e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 115, /* mode7 = 23k : -2.7dB */ 64e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 115 /* mode8 = 24k : -2.7dB */ 65e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}; 66e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 67e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/************************************************************************** 68e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 69e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function : dtx_enc_init 70e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 71e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard**************************************************************************/ 72e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardWord16 dtx_enc_init(dtx_encState ** st, Word16 isf_init[], VO_MEM_OPERATOR *pMemOP) 73e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 74e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard dtx_encState *s; 75e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 76e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (st == (dtx_encState **) NULL) 77e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 78e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard fprintf(stderr, "dtx_enc_init: invalid parameter\n"); 79e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return -1; 80e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 81e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *st = NULL; 82e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 83e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* allocate memory */ 84e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if ((s = (dtx_encState *)mem_malloc(pMemOP, sizeof(dtx_encState), 32, VO_INDEX_ENC_AMRWB)) == NULL) 85e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 86e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard fprintf(stderr, "dtx_enc_init: can not malloc state structure\n"); 87e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return -1; 88e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 89e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard dtx_enc_reset(s, isf_init); 90e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *st = s; 91e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return 0; 92e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 93e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 94e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/************************************************************************** 95e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 96e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function : dtx_enc_reset 97e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 98e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard**************************************************************************/ 99e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardWord16 dtx_enc_reset(dtx_encState * st, Word16 isf_init[]) 100e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 101e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 i; 102e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 103e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (st == (dtx_encState *) NULL) 104e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 105e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard fprintf(stderr, "dtx_enc_reset: invalid parameter\n"); 106e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return -1; 107e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 108b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->hist_ptr = 0; 109b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->log_en_index = 0; 110e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 111e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Init isf_hist[] */ 112e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < DTX_HIST_SIZE; i++) 113e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 114e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Copy(isf_init, &st->isf_hist[i * M], M); 115e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 116b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->cng_seed = RANDOM_INITSEED; 117e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 118e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Reset energy history */ 119e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Set_zero(st->log_en_hist, DTX_HIST_SIZE); 120e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 121b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->dtxHangoverCount = DTX_HANG_CONST; 122b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->decAnaElapsedCount = 32767; 123e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 124e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < 28; i++) 125e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 126b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->D[i] = 0; 127e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 128e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 129e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < DTX_HIST_SIZE - 1; i++) 130e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 131b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->sumD[i] = 0; 132e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 133e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 134e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return 1; 135e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 136e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 137e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/************************************************************************** 138e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 139e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function : dtx_enc_exit 140e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 141e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard**************************************************************************/ 142e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid dtx_enc_exit(dtx_encState ** st, VO_MEM_OPERATOR *pMemOP) 143e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 144e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (st == NULL || *st == NULL) 145e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return; 146e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* deallocate memory */ 147e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mem_free(pMemOP, *st, VO_INDEX_ENC_AMRWB); 148e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *st = NULL; 149e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return; 150e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 151e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 152e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 153e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/************************************************************************** 154e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 155e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function : dtx_enc 156e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 157e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard**************************************************************************/ 158e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardWord16 dtx_enc( 159e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard dtx_encState * st, /* i/o : State struct */ 160e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 isf[M], /* o : CN ISF vector */ 161e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 * exc2, /* o : CN excitation */ 162e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 ** prms 163e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 164e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 165e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 i, j; 166e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 indice[7]; 167e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 log_en, gain, level, exp, exp0, tmp; 168e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 log_en_int_e, log_en_int_m; 169e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 L_isf[M], ener32, level32; 170e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 isf_order[3]; 171e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 CN_dith; 172e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 173e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* VOX mode computation of SID parameters */ 174e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard log_en = 0; 175e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < M; i++) 176e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 177e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_isf[i] = 0; 178e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 179e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* average energy and isf */ 180e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < DTX_HIST_SIZE; i++) 181e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 182e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Division by DTX_HIST_SIZE = 8 has been done in dtx_buffer. log_en is in Q10 */ 183e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard log_en = add(log_en, st->log_en_hist[i]); 184e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 185e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 186e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard find_frame_indices(st->isf_hist, isf_order, st); 187e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard aver_isf_history(st->isf_hist, isf_order, L_isf); 188e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 189e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (j = 0; j < M; j++) 190e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 191e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard isf[j] = (Word16)(L_isf[j] >> 3); /* divide by 8 */ 192e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 193e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 194e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* quantize logarithmic energy to 6 bits (-6 : 66 dB) which corresponds to -2:22 in log2(E). */ 195e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* st->log_en_index = (short)( (log_en + 2.0) * 2.625 ); */ 196e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 197e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* increase dynamics to 7 bits (Q8) */ 198e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard log_en = (log_en >> 2); 199e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 200e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Add 2 in Q8 = 512 to get log2(E) between 0:24 */ 201e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard log_en = add(log_en, 512); 202e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 203e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Multiply by 2.625 to get full 6 bit range. 2.625 = 21504 in Q13. The result is in Q6 */ 204e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard log_en = mult(log_en, 21504); 205e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 206e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Quantize Energy */ 207e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard st->log_en_index = shr(log_en, 6); 208e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 209e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(st->log_en_index > 63) 210e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 211e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard st->log_en_index = 63; 212e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 213e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (st->log_en_index < 0) 214e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 215e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard st->log_en_index = 0; 216e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 217e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Quantize ISFs */ 218e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Qisf_ns(isf, isf, indice); 219e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 220e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 221e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Parm_serial(indice[0], 6, prms); 222e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Parm_serial(indice[1], 6, prms); 223e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Parm_serial(indice[2], 6, prms); 224e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Parm_serial(indice[3], 5, prms); 225e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Parm_serial(indice[4], 5, prms); 226e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 227e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Parm_serial((st->log_en_index), 6, prms); 228e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 229e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard CN_dith = dithering_control(st); 230e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Parm_serial(CN_dith, 1, prms); 231e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 232e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* level = (float)( pow( 2.0f, (float)st->log_en_index / 2.625 - 2.0 ) ); */ 233e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* log2(E) in Q9 (log2(E) lies in between -2:22) */ 234e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard log_en = shl(st->log_en_index, 15 - 6); 235e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 236e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Divide by 2.625; log_en will be between 0:24 */ 237e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard log_en = mult(log_en, 12483); 238e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* the result corresponds to log2(gain) in Q10 */ 239e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 240e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Find integer part */ 241e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard log_en_int_e = (log_en >> 10); 242e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 243e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Find fractional part */ 244e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard log_en_int_m = (Word16) (log_en & 0x3ff); 245e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard log_en_int_m = shl(log_en_int_m, 5); 246e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 247e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Subtract 2 from log_en in Q9, i.e divide the gain by 2 (energy by 4) */ 248e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Add 16 in order to have the result of pow2 in Q16 */ 249e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard log_en_int_e = add(log_en_int_e, 16 - 1); 250e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 251e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard level32 = Pow2(log_en_int_e, log_en_int_m); /* Q16 */ 252e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard exp0 = norm_l(level32); 253e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard level32 = (level32 << exp0); /* level in Q31 */ 254e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard exp0 = (15 - exp0); 255e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard level = extract_h(level32); /* level in Q15 */ 256e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 257e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* generate white noise vector */ 258e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < L_FRAME; i++) 259e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 260e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard exc2[i] = (Random(&(st->cng_seed)) >> 4); 261e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 262e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 263e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* gain = level / sqrt(ener) * sqrt(L_FRAME) */ 264e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 265e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* energy of generated excitation */ 266e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ener32 = Dot_product12(exc2, exc2, L_FRAME, &exp); 267e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 268e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Isqrt_n(&ener32, &exp); 269e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 270e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard gain = extract_h(ener32); 271e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 272e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard gain = mult(level, gain); /* gain in Q15 */ 273e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 274e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard exp = add(exp0, exp); 275e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 276e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Multiply by sqrt(L_FRAME)=16, i.e. shift left by 4 */ 277e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard exp += 4; 278e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 279e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < L_FRAME; i++) 280e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 281e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard tmp = mult(exc2[i], gain); /* Q0 * Q15 */ 282b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard exc2[i] = shl(tmp, exp); 283e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 284e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 285e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return 0; 286e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 287e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 288e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/************************************************************************** 289e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 290e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function : dtx_buffer Purpose : handles the DTX buffer 291e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 292e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard**************************************************************************/ 293e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardWord16 dtx_buffer( 294e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard dtx_encState * st, /* i/o : State struct */ 295e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 isf_new[], /* i : isf vector */ 296e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 enr, /* i : residual energy (in L_FRAME) */ 297e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 codec_mode 298e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 299e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 300e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 log_en; 301e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 302e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 log_en_e; 303e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 log_en_m; 304b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->hist_ptr = add(st->hist_ptr, 1); 305e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(st->hist_ptr == DTX_HIST_SIZE) 306e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 307e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard st->hist_ptr = 0; 308e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 309e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* copy lsp vector into buffer */ 310e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Copy(isf_new, &st->isf_hist[st->hist_ptr * M], M); 311e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 312e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* log_en = (float)log10(enr*0.0059322)/(float)log10(2.0f); */ 313e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Log2(enr, &log_en_e, &log_en_m); 314e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 315e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* convert exponent and mantissa to Word16 Q7. Q7 is used to simplify averaging in dtx_enc */ 316e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard log_en = shl(log_en_e, 7); /* Q7 */ 317e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard log_en = add(log_en, shr(log_en_m, 15 - 7)); 318e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 319e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Find energy per sample by multiplying with 0.0059322, i.e subtract log2(1/0.0059322) = 7.39722 The 320e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * constant 0.0059322 takes into account windowings and analysis length from autocorrelation 321e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * computations; 7.39722 in Q7 = 947 */ 322e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Subtract 3 dB = 0.99658 in log2(E) = 127 in Q7. */ 323e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* log_en = sub( log_en, 947 + en_adjust[codec_mode] ); */ 324e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 325e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Find energy per sample (divide by L_FRAME=256), i.e subtract log2(256) = 8.0 (1024 in Q7) */ 326e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Subtract 3 dB = 0.99658 in log2(E) = 127 in Q7. */ 327e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 328e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard log_en = sub(log_en, add(1024, en_adjust[codec_mode])); 329e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 330e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Insert into the buffer */ 331e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard st->log_en_hist[st->hist_ptr] = log_en; 332e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return 0; 333e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 334e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 335e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/************************************************************************** 336e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 337e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function : tx_dtx_handler Purpose : adds extra speech hangover 338e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* to analyze speech on 339e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* the decoding side. 340e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard**************************************************************************/ 341e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid tx_dtx_handler(dtx_encState * st, /* i/o : State struct */ 342e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 vad_flag, /* i : vad decision */ 343e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 * usedMode /* i/o : mode changed or not */ 344e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 345e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 346e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 347e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* this state machine is in synch with the GSMEFR txDtx machine */ 348b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1); 349e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 350e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (vad_flag != 0) 351e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 352e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard st->dtxHangoverCount = DTX_HANG_CONST; 353e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } else 354e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { /* non-speech */ 355e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (st->dtxHangoverCount == 0) 356e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { /* out of decoder analysis hangover */ 357b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->decAnaElapsedCount = 0; 358b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard *usedMode = MRDTX; 359e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } else 360e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { /* in possible analysis hangover */ 361e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard st->dtxHangoverCount = sub(st->dtxHangoverCount, 1); 362e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 363e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* decAnaElapsedCount + dtxHangoverCount < DTX_ELAPSED_FRAMES_THRESH */ 364e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (sub(add(st->decAnaElapsedCount, st->dtxHangoverCount), 365e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard DTX_ELAPSED_FRAMES_THRESH) < 0) 366e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 367e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *usedMode = MRDTX; 368e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* if short time since decoder update, do not add extra HO */ 369e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 370e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* else override VAD and stay in speech mode *usedMode and add extra hangover */ 371e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 372e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 373e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 374e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return; 375e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 376e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 377e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 378e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 379e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic void aver_isf_history( 380e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 isf_old[], 381e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 indices[], 382e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 isf_aver[] 383e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 384e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 385e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 i, j, k; 386e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 isf_tmp[2 * M]; 387e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 L_tmp; 388e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 389e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Memorize in isf_tmp[][] the ISF vectors to be replaced by */ 390e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* the median ISF vector prior to the averaging */ 391e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (k = 0; k < 2; k++) 392e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 393e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if ((indices[k] + 1) != 0) 394e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 395e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < M; i++) 396e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 397b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard isf_tmp[k * M + i] = isf_old[indices[k] * M + i]; 398b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard isf_old[indices[k] * M + i] = isf_old[indices[2] * M + i]; 399e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 400e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 401e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 402e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 403e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Perform the ISF averaging */ 404e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (j = 0; j < M; j++) 405e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 406b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard L_tmp = 0; 407e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 408e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < DTX_HIST_SIZE; i++) 409e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 410e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp = L_add(L_tmp, L_deposit_l(isf_old[i * M + j])); 411e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 412b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard isf_aver[j] = L_tmp; 413e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 414e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 415e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Retrieve from isf_tmp[][] the ISF vectors saved prior to averaging */ 416e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (k = 0; k < 2; k++) 417e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 418e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if ((indices[k] + 1) != 0) 419e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 420e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < M; i++) 421e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 422e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard isf_old[indices[k] * M + i] = isf_tmp[k * M + i]; 423e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 424e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 425e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 426e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 427e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return; 428e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 429e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 430e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic void find_frame_indices( 431e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 isf_old_tx[], 432e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 indices[], 433e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard dtx_encState * st 434e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 435e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 436e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 L_tmp, summin, summax, summax2nd; 437e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 i, j, tmp; 438e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 ptr; 439e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 440e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Remove the effect of the oldest frame from the column */ 441e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* sum sumD[0..DTX_HIST_SIZE-1]. sumD[DTX_HIST_SIZE] is */ 442e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* not updated since it will be removed later. */ 443e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 444b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmp = DTX_HIST_SIZE_MIN_ONE; 445b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard j = -1; 446e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < DTX_HIST_SIZE_MIN_ONE; i++) 447e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 448e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard j = add(j, tmp); 449b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->sumD[i] = L_sub(st->sumD[i], st->D[j]); 450e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard tmp = sub(tmp, 1); 451e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 452e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 453e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Shift the column sum sumD. The element sumD[DTX_HIST_SIZE-1] */ 454e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* corresponding to the oldest frame is removed. The sum of */ 455e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* the distances between the latest isf and other isfs, */ 456e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* i.e. the element sumD[0], will be computed during this call. */ 457e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Hence this element is initialized to zero. */ 458e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 459e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = DTX_HIST_SIZE_MIN_ONE; i > 0; i--) 460e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 461b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->sumD[i] = st->sumD[i - 1]; 462e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 463b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->sumD[0] = 0; 464e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 465e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Remove the oldest frame from the distance matrix. */ 466e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Note that the distance matrix is replaced by a one- */ 467e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* dimensional array to save static memory. */ 468e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 469b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmp = 0; 470e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 27; i >= 12; i = (Word16) (i - tmp)) 471e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 472e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard tmp = add(tmp, 1); 473e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (j = tmp; j > 0; j--) 474e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 475b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->D[i - j + 1] = st->D[i - j - tmp]; 476e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 477e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 478e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 479e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Compute the first column of the distance matrix D */ 480e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* (squared Euclidean distances from isf1[] to isf_old_tx[][]). */ 481e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 482b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard ptr = st->hist_ptr; 483e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 1; i < DTX_HIST_SIZE; i++) 484e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 485e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Compute the distance between the latest isf and the other isfs. */ 486e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ptr = sub(ptr, 1); 487e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (ptr < 0) 488e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 489b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard ptr = DTX_HIST_SIZE_MIN_ONE; 490e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 491b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard L_tmp = 0; 492e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (j = 0; j < M; j++) 493e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 494e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard tmp = sub(isf_old_tx[st->hist_ptr * M + j], isf_old_tx[ptr * M + j]); 495e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp = L_mac(L_tmp, tmp, tmp); 496e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 497b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->D[i - 1] = L_tmp; 498e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 499e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Update also the column sums. */ 500b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->sumD[0] = L_add(st->sumD[0], st->D[i - 1]); 501b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->sumD[i] = L_add(st->sumD[i], st->D[i - 1]); 502e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 503e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 504e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Find the minimum and maximum distances */ 505b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard summax = st->sumD[0]; 506b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard summin = st->sumD[0]; 507b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard indices[0] = 0; 508b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard indices[2] = 0; 509e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 1; i < DTX_HIST_SIZE; i++) 510e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 511e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (L_sub(st->sumD[i], summax) > 0) 512e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 513b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard indices[0] = i; 514b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard summax = st->sumD[i]; 515e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 516e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (L_sub(st->sumD[i], summin) < 0) 517e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 518b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard indices[2] = i; 519b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard summin = st->sumD[i]; 520e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 521e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 522e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 523e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Find the second largest distance */ 524b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard summax2nd = -2147483647L; 525b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard indices[1] = -1; 526e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < DTX_HIST_SIZE; i++) 527e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 528e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if ((L_sub(st->sumD[i], summax2nd) > 0) && (sub(i, indices[0]) != 0)) 529e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 530b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard indices[1] = i; 531b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard summax2nd = st->sumD[i]; 532e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 533e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 534e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 535e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < 3; i++) 536e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 537b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard indices[i] = sub(st->hist_ptr, indices[i]); 538e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (indices[i] < 0) 539e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 540b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard indices[i] = add(indices[i], DTX_HIST_SIZE); 541e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 542e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 543e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 544e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* If maximum distance/MED_THRESH is smaller than minimum distance */ 545e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* then the median ISF vector replacement is not performed */ 546e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard tmp = norm_l(summax); 547e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard summax = (summax << tmp); 548e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard summin = (summin << tmp); 549e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp = L_mult(voround(summax), INV_MED_THRESH); 550e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(L_tmp <= summin) 551e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 552b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard indices[0] = -1; 553e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 554e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* If second largest distance/MED_THRESH is smaller than */ 555e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* minimum distance then the median ISF vector replacement is */ 556e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* not performed */ 557e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard summax2nd = L_shl(summax2nd, tmp); 558e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp = L_mult(voround(summax2nd), INV_MED_THRESH); 559e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(L_tmp <= summin) 560e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 561b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard indices[1] = -1; 562e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 563e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return; 564e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 565e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 566e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 dithering_control( 567e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard dtx_encState * st 568e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 569e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 570e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 tmp, mean, CN_dith, gain_diff; 571e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 i, ISF_diff; 572e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 573e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* determine how stationary the spectrum of background noise is */ 574e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ISF_diff = 0; 575e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < 8; i++) 576e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 577e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ISF_diff = L_add(ISF_diff, st->sumD[i]); 578e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 579e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if ((ISF_diff >> 26) > 0) 580e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 581e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard CN_dith = 1; 582e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } else 583e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 584e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard CN_dith = 0; 585e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 586e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 587e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* determine how stationary the energy of background noise is */ 588e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mean = 0; 589e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < DTX_HIST_SIZE; i++) 590e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 591e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mean = add(mean, st->log_en_hist[i]); 592e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 593e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mean = (mean >> 3); 594e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard gain_diff = 0; 595e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < DTX_HIST_SIZE; i++) 596e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 597e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard tmp = abs_s(sub(st->log_en_hist[i], mean)); 598e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard gain_diff = add(gain_diff, tmp); 599e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 600e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (gain_diff > GAIN_THR) 601e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 602e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard CN_dith = 1; 603e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 604e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return CN_dith; 605e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 606