16f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* 26f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 36f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * 46f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * Use of this source code is governed by a BSD-style license 56f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * that can be found in the LICENSE file in the root of the source 66f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * tree. An additional intellectual property rights grant can be found 76f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * in the file PATENTS. All contributing project authors may 86f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * be found in the AUTHORS file in the root of the source tree. 96f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin */ 106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#include "lpc_analysis.h" 126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#include "settings.h" 136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#include "codec.h" 146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#include "entropy_coding.h" 156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#include <math.h> 176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#include <string.h> 186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#define LEVINSON_EPS 1.0e-10 206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* window */ 236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* Matlab generation code: 246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * t = (1:256)/257; r = 1-(1-t).^.45; w = sin(r*pi).^3; w = w/sum(w); plot((1:256)/8, w); grid; 256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * for k=1:16, fprintf(1, '%.8f, ', w(k*16 + (-15:0))); fprintf(1, '\n'); end 266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin */ 276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinstatic const double kLpcCorrWindow[WINLEN] = { 286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00000000, 0.00000001, 0.00000004, 0.00000010, 0.00000020, 296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00000035, 0.00000055, 0.00000083, 0.00000118, 0.00000163, 306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00000218, 0.00000283, 0.00000361, 0.00000453, 0.00000558, 0.00000679, 316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00000817, 0.00000973, 0.00001147, 0.00001342, 0.00001558, 326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00001796, 0.00002058, 0.00002344, 0.00002657, 0.00002997, 336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00003365, 0.00003762, 0.00004190, 0.00004651, 0.00005144, 0.00005673, 346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00006236, 0.00006837, 0.00007476, 0.00008155, 0.00008875, 356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00009636, 0.00010441, 0.00011290, 0.00012186, 0.00013128, 366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00014119, 0.00015160, 0.00016252, 0.00017396, 0.00018594, 0.00019846, 376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00021155, 0.00022521, 0.00023946, 0.00025432, 0.00026978, 386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00028587, 0.00030260, 0.00031998, 0.00033802, 0.00035674, 396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00037615, 0.00039626, 0.00041708, 0.00043863, 0.00046092, 0.00048396, 406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00050775, 0.00053233, 0.00055768, 0.00058384, 0.00061080, 416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00063858, 0.00066720, 0.00069665, 0.00072696, 0.00075813, 426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00079017, 0.00082310, 0.00085692, 0.00089164, 0.00092728, 0.00096384, 436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00100133, 0.00103976, 0.00107914, 0.00111947, 0.00116077, 446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00120304, 0.00124630, 0.00129053, 0.00133577, 0.00138200, 456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00142924, 0.00147749, 0.00152676, 0.00157705, 0.00162836, 0.00168070, 466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00173408, 0.00178850, 0.00184395, 0.00190045, 0.00195799, 476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00201658, 0.00207621, 0.00213688, 0.00219860, 0.00226137, 486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00232518, 0.00239003, 0.00245591, 0.00252284, 0.00259079, 0.00265977, 496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00272977, 0.00280078, 0.00287280, 0.00294582, 0.00301984, 506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00309484, 0.00317081, 0.00324774, 0.00332563, 0.00340446, 516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00348421, 0.00356488, 0.00364644, 0.00372889, 0.00381220, 0.00389636, 526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00398135, 0.00406715, 0.00415374, 0.00424109, 0.00432920, 536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00441802, 0.00450754, 0.00459773, 0.00468857, 0.00478001, 546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00487205, 0.00496464, 0.00505775, 0.00515136, 0.00524542, 0.00533990, 556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00543476, 0.00552997, 0.00562548, 0.00572125, 0.00581725, 566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00591342, 0.00600973, 0.00610612, 0.00620254, 0.00629895, 576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00639530, 0.00649153, 0.00658758, 0.00668341, 0.00677894, 0.00687413, 586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00696891, 0.00706322, 0.00715699, 0.00725016, 0.00734266, 596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00743441, 0.00752535, 0.00761540, 0.00770449, 0.00779254, 606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00787947, 0.00796519, 0.00804963, 0.00813270, 0.00821431, 0.00829437, 616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00837280, 0.00844949, 0.00852436, 0.00859730, 0.00866822, 626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00873701, 0.00880358, 0.00886781, 0.00892960, 0.00898884, 636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00904542, 0.00909923, 0.00915014, 0.00919805, 0.00924283, 0.00928436, 646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00932252, 0.00935718, 0.00938821, 0.00941550, 0.00943890, 656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00945828, 0.00947351, 0.00948446, 0.00949098, 0.00949294, 666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00949020, 0.00948262, 0.00947005, 0.00945235, 0.00942938, 0.00940099, 676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00936704, 0.00932738, 0.00928186, 0.00923034, 0.00917268, 686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00910872, 0.00903832, 0.00896134, 0.00887763, 0.00878706, 696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00868949, 0.00858478, 0.00847280, 0.00835343, 0.00822653, 0.00809199, 706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00794970, 0.00779956, 0.00764145, 0.00747530, 0.00730103, 716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00711857, 0.00692787, 0.00672888, 0.00652158, 0.00630597, 726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00608208, 0.00584994, 0.00560962, 0.00536124, 0.00510493, 0.00484089, 736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00456935, 0.00429062, 0.00400505, 0.00371310, 0.00341532, 746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00311238, 0.00280511, 0.00249452, 0.00218184, 0.00186864, 756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 0.00155690, 0.00124918, 0.00094895, 0.00066112, 0.00039320, 0.00015881 766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}; 776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkindouble WebRtcIsac_LevDurb(double *a, double *k, double *r, int order) 796f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{ 806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double sum, alpha; 826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin int m, m_h, i; 836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin alpha = 0; //warning -DH 846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin a[0] = 1.0; 856f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin if (r[0] < LEVINSON_EPS) { /* if r[0] <= 0, set LPC coeff. to zero */ 866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (i = 0; i < order; i++) { 876f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin k[i] = 0; 886f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin a[i+1] = 0; 896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } else { 916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin a[1] = k[0] = -r[1]/r[0]; 926f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin alpha = r[0] + r[1] * k[0]; 936f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (m = 1; m < order; m++){ 946f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin sum = r[m + 1]; 956f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (i = 0; i < m; i++){ 966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin sum += a[i+1] * r[m - i]; 976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin k[m] = -sum / alpha; 996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin alpha += k[m] * sum; 1006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin m_h = (m + 1) >> 1; 1016f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (i = 0; i < m_h; i++){ 1026f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin sum = a[i+1] + k[m] * a[m - i]; 1036f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin a[m - i] += k[m] * a[i+1]; 1046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin a[i+1] = sum; 1056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 1066f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin a[m+1] = k[m]; 1076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 1086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 1096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin return alpha; 1106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin} 1116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 1126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 1136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin//was static before, but didn't work with MEX file 1146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid WebRtcIsac_GetVars(const double *input, const WebRtc_Word16 *pitchGains_Q12, 1156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double *oldEnergy, double *varscale) 1166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{ 1176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double nrg[4], chng, pg; 1186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin int k; 1196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 1206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double pitchGains[4]={0,0,0,0};; 1216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 1226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* Calculate energies of first and second frame halfs */ 1236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin nrg[0] = 0.0001; 1246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (k = QLOOKAHEAD/2; k < (FRAMESAMPLES_QUARTER + QLOOKAHEAD) / 2; k++) { 1256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin nrg[0] += input[k]*input[k]; 1266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 1276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin nrg[1] = 0.0001; 1286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for ( ; k < (FRAMESAMPLES_HALF + QLOOKAHEAD) / 2; k++) { 1296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin nrg[1] += input[k]*input[k]; 1306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 1316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin nrg[2] = 0.0001; 1326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for ( ; k < (FRAMESAMPLES*3/4 + QLOOKAHEAD) / 2; k++) { 1336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin nrg[2] += input[k]*input[k]; 1346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 1356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin nrg[3] = 0.0001; 1366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for ( ; k < (FRAMESAMPLES + QLOOKAHEAD) / 2; k++) { 1376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin nrg[3] += input[k]*input[k]; 1386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 1396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 1406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* Calculate average level change */ 1416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin chng = 0.25 * (fabs(10.0 * log10(nrg[3] / nrg[2])) + 1426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin fabs(10.0 * log10(nrg[2] / nrg[1])) + 1436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin fabs(10.0 * log10(nrg[1] / nrg[0])) + 1446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin fabs(10.0 * log10(nrg[0] / *oldEnergy))); 1456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 1466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 1476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* Find average pitch gain */ 1486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin pg = 0.0; 1496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (k=0; k<4; k++) 1506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin { 1516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin pitchGains[k] = ((float)pitchGains_Q12[k])/4096; 1526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin pg += pitchGains[k]; 1536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 1546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin pg *= 0.25; 1556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 1566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* If pitch gain is low and energy constant - increase noise level*/ 1576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* Matlab code: 1586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin pg = 0:.01:.45; plot(pg, 0.0 + 1.0 * exp( -1.0 * exp(-200.0 * pg.*pg.*pg) / (1.0 + 0.4 * 0) )) 1596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin */ 1606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *varscale = 0.0 + 1.0 * exp( -1.4 * exp(-200.0 * pg*pg*pg) / (1.0 + 0.4 * chng) ); 1616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 1626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *oldEnergy = nrg[3]; 1636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin} 1646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 1656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid 1666f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinWebRtcIsac_GetVarsUB( 1676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin const double* input, 1686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double* oldEnergy, 1696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double* varscale) 1706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{ 1716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double nrg[4], chng; 1726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin int k; 1736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 1746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* Calculate energies of first and second frame halfs */ 1756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin nrg[0] = 0.0001; 1766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (k = 0; k < (FRAMESAMPLES_QUARTER) / 2; k++) { 1776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin nrg[0] += input[k]*input[k]; 1786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 1796f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin nrg[1] = 0.0001; 1806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for ( ; k < (FRAMESAMPLES_HALF) / 2; k++) { 1816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin nrg[1] += input[k]*input[k]; 1826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 1836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin nrg[2] = 0.0001; 1846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for ( ; k < (FRAMESAMPLES*3/4) / 2; k++) { 1856f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin nrg[2] += input[k]*input[k]; 1866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 1876f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin nrg[3] = 0.0001; 1886f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for ( ; k < (FRAMESAMPLES) / 2; k++) { 1896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin nrg[3] += input[k]*input[k]; 1906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 1916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 1926f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* Calculate average level change */ 1936f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin chng = 0.25 * (fabs(10.0 * log10(nrg[3] / nrg[2])) + 1946f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin fabs(10.0 * log10(nrg[2] / nrg[1])) + 1956f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin fabs(10.0 * log10(nrg[1] / nrg[0])) + 1966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin fabs(10.0 * log10(nrg[0] / *oldEnergy))); 1976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 1986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 1996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* If pitch gain is low and energy constant - increase noise level*/ 2006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* Matlab code: 2016f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin pg = 0:.01:.45; plot(pg, 0.0 + 1.0 * exp( -1.0 * exp(-200.0 * pg.*pg.*pg) / (1.0 + 0.4 * 0) )) 2026f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin */ 2036f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *varscale = exp( -1.4 / (1.0 + 0.4 * chng) ); 2046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *oldEnergy = nrg[3]; 2066f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin} 2076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid WebRtcIsac_GetLpcCoefLb(double *inLo, double *inHi, MaskFiltstr *maskdata, 2096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double signal_noise_ratio, const WebRtc_Word16 *pitchGains_Q12, 2106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double *lo_coeff, double *hi_coeff) 2116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{ 2126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin int k, n, j, pos1, pos2; 2136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double varscale; 2146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double DataLo[WINLEN], DataHi[WINLEN]; 2166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double corrlo[ORDERLO+2], corrlo2[ORDERLO+1]; 2176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double corrhi[ORDERHI+1]; 2186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double k_veclo[ORDERLO], k_vechi[ORDERHI]; 2196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double a_LO[ORDERLO+1], a_HI[ORDERHI+1]; 2216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double tmp, res_nrg; 2226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double FwdA, FwdB; 2246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* hearing threshold level in dB; higher value gives more noise */ 2266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin const double HearThresOffset = -28.0; 2276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* bandwdith expansion factors for low- and high band */ 2296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin const double gammaLo = 0.9; 2306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin const double gammaHi = 0.8; 2316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* less-noise-at-low-frequencies factor */ 2336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double aa; 2346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* convert from dB to signal level */ 2376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin const double H_T_H = pow(10.0, 0.05 * HearThresOffset); 2386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double S_N_R = pow(10.0, 0.05 * signal_noise_ratio) / 3.46; /* divide by sqrt(12) */ 2396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* change quallevel depending on pitch gains and level fluctuations */ 2416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin WebRtcIsac_GetVars(inLo, pitchGains_Q12, &(maskdata->OldEnergy), &varscale); 2426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* less-noise-at-low-frequencies factor */ 2446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin aa = 0.35 * (0.5 + 0.5 * varscale); 2456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* replace data in buffer by new look-ahead data */ 2476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (pos1 = 0; pos1 < QLOOKAHEAD; pos1++) 2486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin maskdata->DataBufferLo[pos1 + WINLEN - QLOOKAHEAD] = inLo[pos1]; 2496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (k = 0; k < SUBFRAMES; k++) { 2516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* Update input buffer and multiply signal with window */ 2536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (pos1 = 0; pos1 < WINLEN - UPDATE/2; pos1++) { 2546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin maskdata->DataBufferLo[pos1] = maskdata->DataBufferLo[pos1 + UPDATE/2]; 2556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin maskdata->DataBufferHi[pos1] = maskdata->DataBufferHi[pos1 + UPDATE/2]; 2566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin DataLo[pos1] = maskdata->DataBufferLo[pos1] * kLpcCorrWindow[pos1]; 2576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin DataHi[pos1] = maskdata->DataBufferHi[pos1] * kLpcCorrWindow[pos1]; 2586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 2596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin pos2 = k * UPDATE/2; 2606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (n = 0; n < UPDATE/2; n++, pos1++) { 2616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin maskdata->DataBufferLo[pos1] = inLo[QLOOKAHEAD + pos2]; 2626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin maskdata->DataBufferHi[pos1] = inHi[pos2++]; 2636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin DataLo[pos1] = maskdata->DataBufferLo[pos1] * kLpcCorrWindow[pos1]; 2646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin DataHi[pos1] = maskdata->DataBufferHi[pos1] * kLpcCorrWindow[pos1]; 2656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 2666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* Get correlation coefficients */ 2686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin WebRtcIsac_AutoCorr(corrlo, DataLo, WINLEN, ORDERLO+1); /* computing autocorrelation */ 2696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin WebRtcIsac_AutoCorr(corrhi, DataHi, WINLEN, ORDERHI); 2706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* less noise for lower frequencies, by filtering/scaling autocorrelation sequences */ 2736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin corrlo2[0] = (1.0+aa*aa) * corrlo[0] - 2.0*aa * corrlo[1]; 2746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin tmp = (1.0 + aa*aa); 2756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (n = 1; n <= ORDERLO; n++) { 2766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin corrlo2[n] = tmp * corrlo[n] - aa * (corrlo[n-1] + corrlo[n+1]); 2776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 2786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin tmp = (1.0+aa) * (1.0+aa); 2796f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (n = 0; n <= ORDERHI; n++) { 2806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin corrhi[n] = tmp * corrhi[n]; 2816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 2826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* add white noise floor */ 2846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin corrlo2[0] += 1e-6; 2856f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin corrhi[0] += 1e-6; 2866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2876f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2886f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin FwdA = 0.01; 2896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin FwdB = 0.01; 2906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 2916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* recursive filtering of correlation over subframes */ 2926f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (n = 0; n <= ORDERLO; n++) { 2936f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin maskdata->CorrBufLo[n] = FwdA * maskdata->CorrBufLo[n] + corrlo2[n]; 2946f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin corrlo2[n] = ((1.0-FwdA)*FwdB) * maskdata->CorrBufLo[n] + (1.0-FwdB) * corrlo2[n]; 2956f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 2966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (n = 0; n <= ORDERHI; n++) { 2976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin maskdata->CorrBufHi[n] = FwdA * maskdata->CorrBufHi[n] + corrhi[n]; 2986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin corrhi[n] = ((1.0-FwdA)*FwdB) * maskdata->CorrBufHi[n] + (1.0-FwdB) * corrhi[n]; 2996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 3006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 3016f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* compute prediction coefficients */ 3026f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin WebRtcIsac_LevDurb(a_LO, k_veclo, corrlo2, ORDERLO); 3036f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin WebRtcIsac_LevDurb(a_HI, k_vechi, corrhi, ORDERHI); 3046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 3056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* bandwidth expansion */ 3066f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin tmp = gammaLo; 3076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (n = 1; n <= ORDERLO; n++) { 3086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin a_LO[n] *= tmp; 3096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin tmp *= gammaLo; 3106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 3116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 3126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* residual energy */ 3136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin res_nrg = 0.0; 3146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (j = 0; j <= ORDERLO; j++) { 3156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (n = 0; n <= j; n++) { 3166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin res_nrg += a_LO[j] * corrlo2[j-n] * a_LO[n]; 3176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 3186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (n = j+1; n <= ORDERLO; n++) { 3196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin res_nrg += a_LO[j] * corrlo2[n-j] * a_LO[n]; 3206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 3216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 3226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 3236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* add hearing threshold and compute the gain */ 3246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *lo_coeff++ = S_N_R / (sqrt(res_nrg) / varscale + H_T_H); 3256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 3266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* copy coefficients to output array */ 3276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (n = 1; n <= ORDERLO; n++) { 3286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *lo_coeff++ = a_LO[n]; 3296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 3306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 3316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 3326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* bandwidth expansion */ 3336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin tmp = gammaHi; 3346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (n = 1; n <= ORDERHI; n++) { 3356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin a_HI[n] *= tmp; 3366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin tmp *= gammaHi; 3376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 3386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 3396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* residual energy */ 3406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin res_nrg = 0.0; 3416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (j = 0; j <= ORDERHI; j++) { 3426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (n = 0; n <= j; n++) { 3436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin res_nrg += a_HI[j] * corrhi[j-n] * a_HI[n]; 3446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 3456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (n = j+1; n <= ORDERHI; n++) { 3466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin res_nrg += a_HI[j] * corrhi[n-j] * a_HI[n]; 3476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 3486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 3496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 3506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* add hearing threshold and compute of the gain */ 3516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *hi_coeff++ = S_N_R / (sqrt(res_nrg) / varscale + H_T_H); 3526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 3536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* copy coefficients to output array */ 3546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (n = 1; n <= ORDERHI; n++) { 3556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *hi_coeff++ = a_HI[n]; 3566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 3576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 3586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin} 3596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 3606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 3616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 3626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/****************************************************************************** 3636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * WebRtcIsac_GetLpcCoefUb() 3646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * 3656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * Compute LP coefficients and correlation coefficients. At 12 kHz LP 3666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * coefficients of the first and the last sub-frame is computed. At 16 kHz 3676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * LP coefficients of 4th, 8th and 12th sub-frames are computed. We always 3686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * compute correlation coefficients of all sub-frames. 3696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * 3706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * Inputs: 3716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * -inSignal : Input signal 3726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * -maskdata : a structure keeping signal from previous frame. 3736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * -bandwidth : specifies if the codec is in 0-16 kHz mode or 3746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * 0-12 kHz mode. 3756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * 3766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * Outputs: 3776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * -lpCoeff : pointer to a buffer where A-polynomials are 3786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * written to (first coeff is 1 and it is not 3796f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * written) 3806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * -corrMat : a matrix where correlation coefficients of each 3816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * sub-frame are written to one row. 3826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * -varscale : a scale used to compute LPC gains. 3836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin */ 3846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid 3856f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinWebRtcIsac_GetLpcCoefUb( 3866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double* inSignal, 3876f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin MaskFiltstr* maskdata, 3886f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double* lpCoeff, 3896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double corrMat[][UB_LPC_ORDER + 1], 3906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double* varscale, 3916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin WebRtc_Word16 bandwidth) 3926f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{ 3936f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin int frameCntr, activeFrameCntr, n, pos1, pos2; 3946f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin WebRtc_Word16 criterion1; 3956f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin WebRtc_Word16 criterion2; 3966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin WebRtc_Word16 numSubFrames = SUBFRAMES * (1 + (bandwidth == isac16kHz)); 3976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double data[WINLEN]; 3986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double corrSubFrame[UB_LPC_ORDER+2]; 3996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double reflecCoeff[UB_LPC_ORDER]; 4006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 4016f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double aPolynom[UB_LPC_ORDER+1]; 4026f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double tmp; 4036f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 4046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* bandwdith expansion factors */ 4056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin const double gamma = 0.9; 4066f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 4076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* change quallevel depending on pitch gains and level fluctuations */ 4086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin WebRtcIsac_GetVarsUB(inSignal, &(maskdata->OldEnergy), varscale); 4096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 4106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* replace data in buffer by new look-ahead data */ 4116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for(frameCntr = 0, activeFrameCntr = 0; frameCntr < numSubFrames; 4126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin frameCntr++) 4136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin { 4146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin if(frameCntr == SUBFRAMES) 4156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin { 4166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin // we are in 16 kHz 4176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin varscale++; 4186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin WebRtcIsac_GetVarsUB(&inSignal[FRAMESAMPLES_HALF], 4196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin &(maskdata->OldEnergy), varscale); 4206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 4216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* Update input buffer and multiply signal with window */ 4226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for(pos1 = 0; pos1 < WINLEN - UPDATE/2; pos1++) 4236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin { 4246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin maskdata->DataBufferLo[pos1] = maskdata->DataBufferLo[pos1 + 4256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin UPDATE/2]; 4266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin data[pos1] = maskdata->DataBufferLo[pos1] * kLpcCorrWindow[pos1]; 4276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 4286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin pos2 = frameCntr * UPDATE/2; 4296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for(n = 0; n < UPDATE/2; n++, pos1++, pos2++) 4306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin { 4316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin maskdata->DataBufferLo[pos1] = inSignal[pos2]; 4326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin data[pos1] = maskdata->DataBufferLo[pos1] * kLpcCorrWindow[pos1]; 4336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 4346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 4356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* Get correlation coefficients */ 4366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* computing autocorrelation */ 4376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin WebRtcIsac_AutoCorr(corrSubFrame, data, WINLEN, UB_LPC_ORDER+1); 4386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin memcpy(corrMat[frameCntr], corrSubFrame, 4396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin (UB_LPC_ORDER+1)*sizeof(double)); 4406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 4416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin criterion1 = ((frameCntr == 0) || (frameCntr == (SUBFRAMES - 1))) && 4426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin (bandwidth == isac12kHz); 4436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin criterion2 = (((frameCntr+1) % 4) == 0) && 4446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin (bandwidth == isac16kHz); 4456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin if(criterion1 || criterion2) 4466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin { 4476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* add noise */ 4486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin corrSubFrame[0] += 1e-6; 4496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* compute prediction coefficients */ 4506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin WebRtcIsac_LevDurb(aPolynom, reflecCoeff, corrSubFrame, 4516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin UB_LPC_ORDER); 4526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 4536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* bandwidth expansion */ 4546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin tmp = gamma; 4556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for (n = 1; n <= UB_LPC_ORDER; n++) 4566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin { 4576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *lpCoeff++ = aPolynom[n] * tmp; 4586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin tmp *= gamma; 4596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 4606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin activeFrameCntr++; 4616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 4626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 4636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin} 4646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 4656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 4666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 4676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/****************************************************************************** 4686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * WebRtcIsac_GetLpcGain() 4696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * 4706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * Compute the LPC gains for each sub-frame, given the LPC of each sub-frame 4716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * and the corresponding correlation coefficients. 4726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * 4736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * Inputs: 4746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * -signal_noise_ratio : the desired SNR in dB. 4756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * -numVecs : number of sub-frames 4766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * -corrMat : a matrix of correlation coefficients where 4776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * each row is a set of correlation coefficients of 4786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * one sub-frame. 4796f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * -varscale : a scale computed when WebRtcIsac_GetLpcCoefUb() 4806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * is called. 4816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * 4826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * Outputs: 4836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * -gain : pointer to a buffer where LP gains are written. 4846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * 4856f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin */ 4866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid 4876f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinWebRtcIsac_GetLpcGain( 4886f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double signal_noise_ratio, 4896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin const double* filtCoeffVecs, 4906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin int numVecs, 4916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double* gain, 4926f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double corrMat[][UB_LPC_ORDER + 1], 4936f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin const double* varscale) 4946f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{ 4956f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin WebRtc_Word16 j, n; 4966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin WebRtc_Word16 subFrameCntr; 4976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double aPolynom[ORDERLO + 1]; 4986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin double res_nrg; 4996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 5006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin const double HearThresOffset = -28.0; 5016f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin const double H_T_H = pow(10.0, 0.05 * HearThresOffset); 5026f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* divide by sqrt(12) = 3.46 */ 5036f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin const double S_N_R = pow(10.0, 0.05 * signal_noise_ratio) / 3.46; 5046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 5056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin aPolynom[0] = 1; 5066f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for(subFrameCntr = 0; subFrameCntr < numVecs; subFrameCntr++) 5076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin { 5086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin if(subFrameCntr == SUBFRAMES) 5096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin { 5106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin // we are in second half of a SWB frame. use new varscale 5116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin varscale++; 5126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 5136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin memcpy(&aPolynom[1], &filtCoeffVecs[(subFrameCntr * (UB_LPC_ORDER + 1)) + 5146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 1], sizeof(double) * UB_LPC_ORDER); 5156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 5166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* residual energy */ 5176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin res_nrg = 0.0; 5186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for(j = 0; j <= UB_LPC_ORDER; j++) 5196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin { 5206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for(n = 0; n <= j; n++) 5216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin { 5226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin res_nrg += aPolynom[j] * corrMat[subFrameCntr][j-n] * 5236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin aPolynom[n]; 5246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 5256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin for(n = j+1; n <= UB_LPC_ORDER; n++) 5266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin { 5276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin res_nrg += aPolynom[j] * corrMat[subFrameCntr][n-j] * 5286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin aPolynom[n]; 5296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 5306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 5316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin 5326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin /* add hearing threshold and compute the gain */ 5336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin gain[subFrameCntr] = S_N_R / (sqrt(res_nrg) / *varscale + H_T_H); 5346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin } 5356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin} 536