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* * 205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen* 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( 385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 isf_old[], 395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 indices[], 405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 isf_aver[] 415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ); 42e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 43e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic void find_frame_indices( 445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 isf_old_tx[], 455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 indices[], 465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen dtx_encState * st 475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ); 48e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 49e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 dithering_control( 505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen dtx_encState * st 515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ); 52e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 53e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/* excitation energy adjustment depending on speech coder mode used, Q7 */ 54e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 en_adjust[9] = 55e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 230, /* mode0 = 7k : -5.4dB */ 575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 179, /* mode1 = 9k : -4.2dB */ 585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 141, /* mode2 = 12k : -3.3dB */ 595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 128, /* mode3 = 14k : -3.0dB */ 605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 122, /* mode4 = 16k : -2.85dB */ 615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 115, /* mode5 = 18k : -2.7dB */ 625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 115, /* mode6 = 20k : -2.7dB */ 635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 115, /* mode7 = 23k : -2.7dB */ 645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 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{ 745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen dtx_encState *s; 755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (st == (dtx_encState **) NULL) 775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen fprintf(stderr, "dtx_enc_init: invalid parameter\n"); 795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen return -1; 805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *st = NULL; 825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* allocate memory */ 845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if ((s = (dtx_encState *)mem_malloc(pMemOP, sizeof(dtx_encState), 32, VO_INDEX_ENC_AMRWB)) == NULL) 855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen fprintf(stderr, "dtx_enc_init: can not malloc state structure\n"); 875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen return -1; 885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen dtx_enc_reset(s, isf_init); 905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *st = s; 915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 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{ 1015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 i; 1025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (st == (dtx_encState *) NULL) 1045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 1055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen fprintf(stderr, "dtx_enc_reset: invalid parameter\n"); 1065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen return -1; 1075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 1085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->hist_ptr = 0; 1095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->log_en_index = 0; 1105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Init isf_hist[] */ 1125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < DTX_HIST_SIZE; i++) 1135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 1145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Copy(isf_init, &st->isf_hist[i * M], M); 1155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 1165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->cng_seed = RANDOM_INITSEED; 1175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Reset energy history */ 1195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Set_zero(st->log_en_hist, DTX_HIST_SIZE); 1205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->dtxHangoverCount = DTX_HANG_CONST; 1225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->decAnaElapsedCount = 32767; 1235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < 28; i++) 1255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 1265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->D[i] = 0; 1275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 1285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < DTX_HIST_SIZE - 1; i++) 1305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 1315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->sumD[i] = 0; 1325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 1335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 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{ 1445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (st == NULL || *st == NULL) 1455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen return; 1465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* deallocate memory */ 1475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen mem_free(pMemOP, *st, VO_INDEX_ENC_AMRWB); 1485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *st = NULL; 1495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen return; 150e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 151e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 152e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 153e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/************************************************************************** 154e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 155e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function : dtx_enc 156e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 157e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard**************************************************************************/ 158e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardWord16 dtx_enc( 1595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen dtx_encState * st, /* i/o : State struct */ 1605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 isf[M], /* o : CN ISF vector */ 1615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 * exc2, /* o : CN excitation */ 1625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 ** prms 1635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 164e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 1655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 i, j; 1665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 indice[7]; 1675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 log_en, gain, level, exp, exp0, tmp; 1685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 log_en_int_e, log_en_int_m; 1695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 L_isf[M], ener32, level32; 1705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 isf_order[3]; 1715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 CN_dith; 1725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* VOX mode computation of SID parameters */ 1745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen log_en = 0; 1755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < M; i++) 1765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 1775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_isf[i] = 0; 1785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 1795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* average energy and isf */ 1805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < DTX_HIST_SIZE; i++) 1815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 1825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Division by DTX_HIST_SIZE = 8 has been done in dtx_buffer. log_en is in Q10 */ 1835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen log_en = add(log_en, st->log_en_hist[i]); 1845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 1865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen find_frame_indices(st->isf_hist, isf_order, st); 1875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen aver_isf_history(st->isf_hist, isf_order, L_isf); 1885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (j = 0; j < M; j++) 1905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 1915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen isf[j] = (Word16)(L_isf[j] >> 3); /* divide by 8 */ 1925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 1935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* quantize logarithmic energy to 6 bits (-6 : 66 dB) which corresponds to -2:22 in log2(E). */ 1955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* st->log_en_index = (short)( (log_en + 2.0) * 2.625 ); */ 1965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* increase dynamics to 7 bits (Q8) */ 1985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen log_en = (log_en >> 2); 1995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Add 2 in Q8 = 512 to get log2(E) between 0:24 */ 2015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen log_en = add(log_en, 512); 2025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Multiply by 2.625 to get full 6 bit range. 2.625 = 21504 in Q13. The result is in Q6 */ 2045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen log_en = mult(log_en, 21504); 2055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Quantize Energy */ 2075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->log_en_index = shr(log_en, 6); 2085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(st->log_en_index > 63) 2105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->log_en_index = 63; 2125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 2135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (st->log_en_index < 0) 2145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->log_en_index = 0; 2165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 2175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Quantize ISFs */ 2185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Qisf_ns(isf, isf, indice); 2195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Parm_serial(indice[0], 6, prms); 2225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Parm_serial(indice[1], 6, prms); 2235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Parm_serial(indice[2], 6, prms); 2245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Parm_serial(indice[3], 5, prms); 2255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Parm_serial(indice[4], 5, prms); 2265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Parm_serial((st->log_en_index), 6, prms); 2285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen CN_dith = dithering_control(st); 2305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Parm_serial(CN_dith, 1, prms); 2315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* level = (float)( pow( 2.0f, (float)st->log_en_index / 2.625 - 2.0 ) ); */ 2335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* log2(E) in Q9 (log2(E) lies in between -2:22) */ 2345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen log_en = shl(st->log_en_index, 15 - 6); 2355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Divide by 2.625; log_en will be between 0:24 */ 2375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen log_en = mult(log_en, 12483); 2385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* the result corresponds to log2(gain) in Q10 */ 2395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Find integer part */ 2415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen log_en_int_e = (log_en >> 10); 2425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Find fractional part */ 2445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen log_en_int_m = (Word16) (log_en & 0x3ff); 2455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen log_en_int_m = shl(log_en_int_m, 5); 2465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Subtract 2 from log_en in Q9, i.e divide the gain by 2 (energy by 4) */ 2485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Add 16 in order to have the result of pow2 in Q16 */ 2495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen log_en_int_e = add(log_en_int_e, 16 - 1); 2505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen level32 = Pow2(log_en_int_e, log_en_int_m); /* Q16 */ 2525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp0 = norm_l(level32); 2535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen level32 = (level32 << exp0); /* level in Q31 */ 2545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp0 = (15 - exp0); 2555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen level = extract_h(level32); /* level in Q15 */ 2565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* generate white noise vector */ 2585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < L_FRAME; i++) 2595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exc2[i] = (Random(&(st->cng_seed)) >> 4); 2615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 2625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* gain = level / sqrt(ener) * sqrt(L_FRAME) */ 2645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* energy of generated excitation */ 2665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ener32 = Dot_product12(exc2, exc2, L_FRAME, &exp); 267e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 2685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Isqrt_n(&ener32, &exp); 269e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 2705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen gain = extract_h(ener32); 271e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 2725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen gain = mult(level, gain); /* gain in Q15 */ 273e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 2745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp = add(exp0, exp); 275e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 2765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Multiply by sqrt(L_FRAME)=16, i.e. shift left by 4 */ 2775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp += 4; 278e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 2795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < L_FRAME; i++) 2805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen tmp = mult(exc2[i], gain); /* Q0 * Q15 */ 2825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exc2[i] = shl(tmp, exp); 2835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 284e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 2855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 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( 2945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen dtx_encState * st, /* i/o : State struct */ 2955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 isf_new[], /* i : isf vector */ 2965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 enr, /* i : residual energy (in L_FRAME) */ 2975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 codec_mode 2985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 299e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 3005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 log_en; 3015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 log_en_e; 3035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 log_en_m; 3045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->hist_ptr = add(st->hist_ptr, 1); 3055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(st->hist_ptr == DTX_HIST_SIZE) 3065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 3075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->hist_ptr = 0; 3085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 3095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* copy lsp vector into buffer */ 3105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Copy(isf_new, &st->isf_hist[st->hist_ptr * M], M); 3115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* log_en = (float)log10(enr*0.0059322)/(float)log10(2.0f); */ 3135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Log2(enr, &log_en_e, &log_en_m); 3145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* convert exponent and mantissa to Word16 Q7. Q7 is used to simplify averaging in dtx_enc */ 3165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen log_en = shl(log_en_e, 7); /* Q7 */ 3175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen log_en = add(log_en, shr(log_en_m, 15 - 7)); 3185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Find energy per sample by multiplying with 0.0059322, i.e subtract log2(1/0.0059322) = 7.39722 The 3205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * constant 0.0059322 takes into account windowings and analysis length from autocorrelation 3215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * computations; 7.39722 in Q7 = 947 */ 3225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Subtract 3 dB = 0.99658 in log2(E) = 127 in Q7. */ 3235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* log_en = sub( log_en, 947 + en_adjust[codec_mode] ); */ 3245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Find energy per sample (divide by L_FRAME=256), i.e subtract log2(256) = 8.0 (1024 in Q7) */ 3265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Subtract 3 dB = 0.99658 in log2(E) = 127 in Q7. */ 3275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen log_en = sub(log_en, add(1024, en_adjust[codec_mode])); 3295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Insert into the buffer */ 3315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->log_en_hist[st->hist_ptr] = log_en; 3325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 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 */ 3425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 vad_flag, /* i : vad decision */ 3435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 * usedMode /* i/o : mode changed or not */ 3445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 345e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 346e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 3475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* this state machine is in synch with the GSMEFR txDtx machine */ 3485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1); 3495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (vad_flag != 0) 3515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 3525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->dtxHangoverCount = DTX_HANG_CONST; 3535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } else 3545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { /* non-speech */ 3555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (st->dtxHangoverCount == 0) 3565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { /* out of decoder analysis hangover */ 3575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->decAnaElapsedCount = 0; 3585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *usedMode = MRDTX; 3595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } else 3605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { /* in possible analysis hangover */ 3615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->dtxHangoverCount = sub(st->dtxHangoverCount, 1); 3625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* decAnaElapsedCount + dtxHangoverCount < DTX_ELAPSED_FRAMES_THRESH */ 3645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (sub(add(st->decAnaElapsedCount, st->dtxHangoverCount), 3655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen DTX_ELAPSED_FRAMES_THRESH) < 0) 3665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 3675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *usedMode = MRDTX; 3685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* if short time since decoder update, do not add extra HO */ 3695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 3705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* else override VAD and stay in speech mode *usedMode and add extra hangover */ 3715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 3725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 3735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen return; 375e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 376e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 377e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 378e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 379e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic void aver_isf_history( 3805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 isf_old[], 3815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 indices[], 3825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 isf_aver[] 3835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 384e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 3855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 i, j, k; 3865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 isf_tmp[2 * M]; 3875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 L_tmp; 3885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Memorize in isf_tmp[][] the ISF vectors to be replaced by */ 3905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* the median ISF vector prior to the averaging */ 3915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (k = 0; k < 2; k++) 3925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 3935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if ((indices[k] + 1) != 0) 3945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 3955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < M; i++) 3965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 3975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen isf_tmp[k * M + i] = isf_old[indices[k] * M + i]; 3985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen isf_old[indices[k] * M + i] = isf_old[indices[2] * M + i]; 3995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Perform the ISF averaging */ 4045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (j = 0; j < M; j++) 4055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = 0; 4075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < DTX_HIST_SIZE; i++) 4095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = L_add(L_tmp, L_deposit_l(isf_old[i * M + j])); 4115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen isf_aver[j] = L_tmp; 4135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Retrieve from isf_tmp[][] the ISF vectors saved prior to averaging */ 4165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (k = 0; k < 2; k++) 4175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if ((indices[k] + 1) != 0) 4195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < M; i++) 4215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen isf_old[indices[k] * M + i] = isf_tmp[k * M + i]; 4235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen return; 428e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 429e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 430e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic void find_frame_indices( 4315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 isf_old_tx[], 4325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 indices[], 4335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen dtx_encState * st 4345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 435e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 4365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 L_tmp, summin, summax, summax2nd; 4375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 i, j, tmp; 4385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 ptr; 4395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Remove the effect of the oldest frame from the column */ 4415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* sum sumD[0..DTX_HIST_SIZE-1]. sumD[DTX_HIST_SIZE] is */ 4425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* not updated since it will be removed later. */ 4435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen tmp = DTX_HIST_SIZE_MIN_ONE; 4455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen j = -1; 4465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < DTX_HIST_SIZE_MIN_ONE; i++) 4475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen j = add(j, tmp); 4495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->sumD[i] = L_sub(st->sumD[i], st->D[j]); 4505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen tmp = sub(tmp, 1); 4515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Shift the column sum sumD. The element sumD[DTX_HIST_SIZE-1] */ 4545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* corresponding to the oldest frame is removed. The sum of */ 4555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* the distances between the latest isf and other isfs, */ 4565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* i.e. the element sumD[0], will be computed during this call. */ 4575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Hence this element is initialized to zero. */ 4585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = DTX_HIST_SIZE_MIN_ONE; i > 0; i--) 4605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->sumD[i] = st->sumD[i - 1]; 4625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->sumD[0] = 0; 4645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Remove the oldest frame from the distance matrix. */ 4665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Note that the distance matrix is replaced by a one- */ 4675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* dimensional array to save static memory. */ 4685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen tmp = 0; 4705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 27; i >= 12; i = (Word16) (i - tmp)) 4715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen tmp = add(tmp, 1); 4735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (j = tmp; j > 0; j--) 4745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->D[i - j + 1] = st->D[i - j - tmp]; 4765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Compute the first column of the distance matrix D */ 4805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* (squared Euclidean distances from isf1[] to isf_old_tx[][]). */ 4815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ptr = st->hist_ptr; 4835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 1; i < DTX_HIST_SIZE; i++) 4845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Compute the distance between the latest isf and the other isfs. */ 4865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ptr = sub(ptr, 1); 4875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (ptr < 0) 4885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ptr = DTX_HIST_SIZE_MIN_ONE; 4905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = 0; 4925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (j = 0; j < M; j++) 4935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen tmp = sub(isf_old_tx[st->hist_ptr * M + j], isf_old_tx[ptr * M + j]); 4955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = L_mac(L_tmp, tmp, tmp); 4965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->D[i - 1] = L_tmp; 4985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Update also the column sums. */ 5005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->sumD[0] = L_add(st->sumD[0], st->D[i - 1]); 5015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->sumD[i] = L_add(st->sumD[i], st->D[i - 1]); 5025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 5045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Find the minimum and maximum distances */ 5055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen summax = st->sumD[0]; 5065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen summin = st->sumD[0]; 5075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen indices[0] = 0; 5085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen indices[2] = 0; 5095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 1; i < DTX_HIST_SIZE; i++) 5105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (L_sub(st->sumD[i], summax) > 0) 5125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen indices[0] = i; 5145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen summax = st->sumD[i]; 5155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (L_sub(st->sumD[i], summin) < 0) 5175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen indices[2] = i; 5195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen summin = st->sumD[i]; 5205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 5235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Find the second largest distance */ 5245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen summax2nd = -2147483647L; 5255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen indices[1] = -1; 5265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < DTX_HIST_SIZE; i++) 5275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if ((L_sub(st->sumD[i], summax2nd) > 0) && (sub(i, indices[0]) != 0)) 5295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen indices[1] = i; 5315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen summax2nd = st->sumD[i]; 5325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 5355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < 3; i++) 5365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen indices[i] = sub(st->hist_ptr, indices[i]); 5385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (indices[i] < 0) 5395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen indices[i] = add(indices[i], DTX_HIST_SIZE); 5415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 5445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* If maximum distance/MED_THRESH is smaller than minimum distance */ 5455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* then the median ISF vector replacement is not performed */ 5465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen tmp = norm_l(summax); 5475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen summax = (summax << tmp); 5485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen summin = (summin << tmp); 5495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = L_mult(voround(summax), INV_MED_THRESH); 5505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(L_tmp <= summin) 5515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen indices[0] = -1; 5535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* If second largest distance/MED_THRESH is smaller than */ 5555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* minimum distance then the median ISF vector replacement is */ 5565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* not performed */ 5575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen summax2nd = L_shl(summax2nd, tmp); 5585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = L_mult(voround(summax2nd), INV_MED_THRESH); 5595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(L_tmp <= summin) 5605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen indices[1] = -1; 5625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen return; 564e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 565e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 566e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 dithering_control( 5675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen dtx_encState * st 5685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 569e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 5705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 tmp, mean, CN_dith, gain_diff; 5715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 i, ISF_diff; 5725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 5735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* determine how stationary the spectrum of background noise is */ 5745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ISF_diff = 0; 5755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < 8; i++) 5765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ISF_diff = L_add(ISF_diff, st->sumD[i]); 5785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if ((ISF_diff >> 26) > 0) 5805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen CN_dith = 1; 5825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } else 5835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen CN_dith = 0; 5855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 5875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* determine how stationary the energy of background noise is */ 5885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen mean = 0; 5895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < DTX_HIST_SIZE; i++) 5905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen mean = add(mean, st->log_en_hist[i]); 5925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen mean = (mean >> 3); 5945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen gain_diff = 0; 5955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < DTX_HIST_SIZE; i++) 5965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen tmp = abs_s(sub(st->log_en_hist[i], mean)); 5985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen gain_diff = add(gain_diff, tmp); 5995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 6005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (gain_diff > GAIN_THR) 6015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 6025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen CN_dith = 1; 6035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 6045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen return CN_dith; 605e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 606