1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * entropy_coding.c 13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This file contains all functions used to arithmetically 15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * encode the iSAC bistream. 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <stddef.h> 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "arith_routins.h" 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "spectrum_ar_model_tables.h" 23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "pitch_gain_tables.h" 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "pitch_lag_tables.h" 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "entropy_coding.h" 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "lpc_tables.h" 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "settings.h" 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "signal_processing_library.h" 29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 306b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org/* 316b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org * Eenumerations for arguments to functions WebRtcIsacfix_MatrixProduct1() 326b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org * and WebRtcIsacfix_MatrixProduct2(). 336b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org*/ 346b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org 356b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.orgenum matrix_index_factor { 366b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTIndexFactor1 = 1, 376b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTIndexFactor2 = 2, 386b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTIndexFactor3 = SUBFRAMES, 396b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTIndexFactor4 = LPC_SHAPE_ORDER 406b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org}; 416b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org 426b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.orgenum matrix_index_step { 436b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTIndexStep1 = 1, 446b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTIndexStep2 = SUBFRAMES, 456b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTIndexStep3 = LPC_SHAPE_ORDER 466b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org}; 476b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org 486b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.orgenum matrixprod_loop_count { 496b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTLoopCount1 = SUBFRAMES, 506b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTLoopCount2 = 2, 516b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTLoopCount3 = LPC_SHAPE_ORDER 526b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org}; 536b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org 546b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.orgenum matrix1_shift_value { 556b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTMatrix1_shift0 = 0, 566b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTMatrix1_shift1 = 1, 576b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTMatrix1_shift5 = 5 586b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org}; 596b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org 606b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.orgenum matrixprod_init_case { 616b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTInitCase0 = 0, 626b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTInitCase1 = 1 636b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org}; 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org This function implements the fix-point correspondant function to lrint. 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 68fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org FLP: (int32_t)floor(flt+.499999999999) 69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org FIP: (fixVal+roundVal)>>qDomain 70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org where roundVal = 2^(qDomain-1) = 1<<(qDomain-1) 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org*/ 74fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic __inline int32_t CalcLrIntQ(int32_t fixVal, int16_t qDomain) { 75fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t intgr; 76fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t roundVal; 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 78fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org roundVal = WEBRTC_SPL_LSHIFT_W32((int32_t)1, qDomain-1); 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org intgr = WEBRTC_SPL_RSHIFT_W32(fixVal+roundVal, qDomain); 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return intgr; 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 85fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org __inline uint32_t stepwise(int32_t dinQ10) { 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 87fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t ind, diQ10, dtQ10; 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org diQ10 = dinQ10; 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (diQ10 < DPMIN_Q10) 91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org diQ10 = DPMIN_Q10; 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (diQ10 >= DPMAX_Q10) 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org diQ10 = DPMAX_Q10 - 1; 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dtQ10 = diQ10 - DPMIN_Q10;*/ /* Q10 + Q10 = Q10 */ 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* ind = (dtQ10 * 5) >> 10; */ /* 2^10 / 5 = 0.2 in Q10 */ 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Q10 -> Q0 */ 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* return rpointsFIX_Q10[ind]; 100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org*/ 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* logN(x) = logN(2)*log2(x) = 0.6931*log2(x). Output in Q8. */ 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* The input argument X to logN(X) is 2^17 times higher than the 106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org input floating point argument Y to log(Y), since the X value 107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org is a Q17 value. This can be compensated for after the call, by 108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org subraction a value Z for each Q-step. One Q-step means that 109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org X gets 2 thimes higher, i.e. Z = logN(2)*256 = 0.693147180559*256 = 110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 177.445678 should be subtracted (since logN() returns a Q8 value). 111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org For a X value in Q17, the value 177.445678*17 = 3017 should be 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org subtracted */ 113fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic int16_t CalcLogN(int32_t arg) { 114fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t zeros, log2, frac, logN; 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org zeros=WebRtcSpl_NormU32(arg); 117fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org frac=(int16_t)WEBRTC_SPL_RSHIFT_U32(WEBRTC_SPL_LSHIFT_W32(arg, zeros)&0x7FFFFFFF, 23); 118fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org log2=(int16_t)(WEBRTC_SPL_LSHIFT_W32(31-zeros, 8)+frac); // log2(x) in Q8 119fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org logN=(int16_t)WEBRTC_SPL_MUL_16_16_RSFT(log2,22713,15); //Q8*Q15 log(2) = 0.693147 = 22713 in Q15 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org logN=logN+11; //Scalar compensation which minimizes the (log(x)-logN(x))^2 error over all x. 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return logN; 123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org expN(x) = 2^(a*x), where a = log2(e) ~= 1.442695 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 129fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org Input: Q8 (int16_t) 130fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org Output: Q17 (int32_t) 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org a = log2(e) = log2(exp(1)) ~= 1.442695 ==> a = 23637 in Q14 (1.442688) 133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org To this value, 700 is added or subtracted in order to get an average error 134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nearer zero, instead of always same-sign. 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org*/ 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 137fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic int32_t CalcExpN(int16_t x) { 138fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t ax, axINT, axFRAC; 139fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t exp16; 140fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t exp; 141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (x>=0) { 143fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org // ax=(int16_t)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637-700, 14); //Q8 144fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org ax=(int16_t)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637, 14); //Q8 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org axINT = WEBRTC_SPL_RSHIFT_W16(ax, 8); //Q0 146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org axFRAC = ax&0x00FF; 147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org exp16 = WEBRTC_SPL_LSHIFT_W32(1, axINT); //Q0 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org axFRAC = axFRAC+256; //Q8 149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org exp = WEBRTC_SPL_MUL_16_16(exp16, axFRAC); // Q0*Q8 = Q8 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org exp = WEBRTC_SPL_LSHIFT_W32(exp, 9); //Q17 151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 152fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org // ax=(int16_t)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637+700, 14); //Q8 153fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org ax=(int16_t)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637, 14); //Q8 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ax = -ax; 155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org axINT = 1 + WEBRTC_SPL_RSHIFT_W16(ax, 8); //Q0 156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org axFRAC = 0x00FF - (ax&0x00FF); 157fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org exp16 = (int16_t) WEBRTC_SPL_RSHIFT_W32(32768, axINT); //Q15 158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org axFRAC = axFRAC+256; //Q8 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org exp = WEBRTC_SPL_MUL_16_16(exp16, axFRAC); // Q15*Q8 = Q23 160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org exp = WEBRTC_SPL_RSHIFT_W32(exp, 6); //Q17 161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return exp; 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* compute correlation from power spectrum */ 168fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic void CalcCorrelation(int32_t *PSpecQ12, int32_t *CorrQ7) 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 170fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t summ[FRAMESAMPLES/8]; 171fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t diff[FRAMESAMPLES/8]; 172fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t sum; 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k, n; 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < FRAMESAMPLES/8; k++) { 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org summ[k] = WEBRTC_SPL_RSHIFT_W32(PSpecQ12[k] + PSpecQ12[FRAMESAMPLES/4-1 - k] + 16, 5); 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org diff[k] = WEBRTC_SPL_RSHIFT_W32(PSpecQ12[k] - PSpecQ12[FRAMESAMPLES/4-1 - k] + 16, 5); 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 2; 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < FRAMESAMPLES/8; n++) 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += summ[n]; 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CorrQ7[0] = sum; 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < AR_ORDER; k += 2) { 186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < FRAMESAMPLES/8; n++) 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], diff[n]) + 256, 9); 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CorrQ7[k+1] = sum; 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=1; k<AR_ORDER; k+=2) { 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < FRAMESAMPLES/8; n++) 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], summ[n]) + 256, 9); 196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CorrQ7[k+1] = sum; 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* compute inverse AR power spectrum */ 202fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic void CalcInvArSpec(const int16_t *ARCoefQ12, 203fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int32_t gainQ10, 204fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t *CurveQ16) 205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 206fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t CorrQ11[AR_ORDER+1]; 207fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t sum, tmpGain; 208fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t diffQ16[FRAMESAMPLES/8]; 209fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int16_t *CS_ptrQ9; 210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k, n; 211fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t round, shftVal = 0, sh; 212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < AR_ORDER+1; n++) 215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]); /* Q24 */ 216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(sum, 6), 65) + 32768, 16); /* result in Q8 */ 217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CorrQ11[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, gainQ10) + 256, 9); 218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* To avoid overflow, we shift down gainQ10 if it is large. We will not lose any precision */ 220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(gainQ10>400000){ 221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3); 222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org round = 32; 223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shftVal = 6; 224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpGain = gainQ10; 226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org round = 256; 227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shftVal = 9; 228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 1; k < AR_ORDER+1; k++) { 231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 16384; 232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = k; n < AR_ORDER+1; n++) 233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += WEBRTC_SPL_MUL(ARCoefQ12[n-k], ARCoefQ12[n]); /* Q24 */ 234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = WEBRTC_SPL_RSHIFT_W32(sum, 15); 235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CorrQ11[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, tmpGain) + round, shftVal); 236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7); 238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < FRAMESAMPLES/8; n++) 239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CurveQ16[n] = sum; 240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 1; k < AR_ORDER; k += 2) { 242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < FRAMESAMPLES/8; n++) 243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CurveQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], CorrQ11[k+1]) + 2, 2); 244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CS_ptrQ9 = WebRtcIsacfix_kCos[0]; 247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* If CorrQ11[1] too large we avoid getting overflow in the calculation by shifting */ 249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sh=WebRtcSpl_NormW32(CorrQ11[1]); 250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (CorrQ11[1]==0) /* Use next correlation */ 251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sh=WebRtcSpl_NormW32(CorrQ11[2]); 252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (sh<9) 254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shftVal = 9 - sh; 255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shftVal = 0; 257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < FRAMESAMPLES/8; n++) 259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org diffQ16[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[1], shftVal)) + 2, 2); 260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 2; k < AR_ORDER; k += 2) { 261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CS_ptrQ9 = WebRtcIsacfix_kCos[k]; 262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < FRAMESAMPLES/8; n++) 263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org diffQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[k+1], shftVal)) + 2, 2); 264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<FRAMESAMPLES/8; k++) { 267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CurveQ16[FRAMESAMPLES/4-1 - k] = CurveQ16[k] - WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal); 268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CurveQ16[k] += WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal); 269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 272fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic void CalcRootInvArSpec(const int16_t *ARCoefQ12, 273fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int32_t gainQ10, 274fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint16_t *CurveQ8) 275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 276fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t CorrQ11[AR_ORDER+1]; 277fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t sum, tmpGain; 278fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t summQ16[FRAMESAMPLES/8]; 279fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t diffQ16[FRAMESAMPLES/8]; 280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 281fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int16_t *CS_ptrQ9; 282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k, n, i; 283fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t round, shftVal = 0, sh; 284fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t res, in_sqrt, newRes; 285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < AR_ORDER+1; n++) 288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]); /* Q24 */ 289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(sum, 6), 65) + 32768, 16); /* result in Q8 */ 290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CorrQ11[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, gainQ10) + 256, 9); 291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* To avoid overflow, we shift down gainQ10 if it is large. We will not lose any precision */ 293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(gainQ10>400000){ 294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3); 295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org round = 32; 296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shftVal = 6; 297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpGain = gainQ10; 299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org round = 256; 300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shftVal = 9; 301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 1; k < AR_ORDER+1; k++) { 304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 16384; 305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = k; n < AR_ORDER+1; n++) 306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += WEBRTC_SPL_MUL(ARCoefQ12[n-k], ARCoefQ12[n]); /* Q24 */ 307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = WEBRTC_SPL_RSHIFT_W32(sum, 15); 308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CorrQ11[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, tmpGain) + round, shftVal); 309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7); 311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < FRAMESAMPLES/8; n++) 312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org summQ16[n] = sum; 313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 1; k < (AR_ORDER); k += 2) { 315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < FRAMESAMPLES/8; n++) 3169cfe80329340de096ed8e7e2d8b109611d85b3d0bjornv@webrtc.org summQ16[n] += ((CorrQ11[k + 1] * WebRtcIsacfix_kCos[k][n]) + 2) >> 2; 317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CS_ptrQ9 = WebRtcIsacfix_kCos[0]; 320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* If CorrQ11[1] too large we avoid getting overflow in the calculation by shifting */ 322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sh=WebRtcSpl_NormW32(CorrQ11[1]); 323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (CorrQ11[1]==0) /* Use next correlation */ 324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sh=WebRtcSpl_NormW32(CorrQ11[2]); 325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (sh<9) 327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shftVal = 9 - sh; 328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shftVal = 0; 330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < FRAMESAMPLES/8; n++) 332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org diffQ16[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[1], shftVal)) + 2, 2); 333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 2; k < AR_ORDER; k += 2) { 334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CS_ptrQ9 = WebRtcIsacfix_kCos[k]; 335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < FRAMESAMPLES/8; n++) 336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org diffQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[k+1], shftVal)) + 2, 2); 337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org in_sqrt = summQ16[0] + WEBRTC_SPL_LSHIFT_W32(diffQ16[0], shftVal); 340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* convert to magnitude spectrum, by doing square-roots (modified from SPLIB) */ 342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org res = WEBRTC_SPL_LSHIFT_W32(1, WEBRTC_SPL_RSHIFT_W16(WebRtcSpl_GetSizeInBits(in_sqrt), 1)); 343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < FRAMESAMPLES/8; k++) 345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org in_sqrt = summQ16[k] + WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal); 347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org i = 10; 348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* make in_sqrt positive to prohibit sqrt of negative values */ 350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(in_sqrt<0) 351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org in_sqrt=-in_sqrt; 352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 3535b3e14c36bf3cf2a0cda2e25895f61b6e3df922dbjornv@webrtc.org newRes = (in_sqrt / res + res) >> 1; 354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org do 355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org res = newRes; 3575b3e14c36bf3cf2a0cda2e25895f61b6e3df922dbjornv@webrtc.org newRes = (in_sqrt / res + res) >> 1; 358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } while (newRes != res && i-- > 0); 359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 360fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org CurveQ8[k] = (int16_t)newRes; 361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = FRAMESAMPLES/8; k < FRAMESAMPLES/4; k++) { 363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org in_sqrt = summQ16[FRAMESAMPLES/4-1 - k] - WEBRTC_SPL_LSHIFT_W32(diffQ16[FRAMESAMPLES/4-1 - k], shftVal); 365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org i = 10; 366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* make in_sqrt positive to prohibit sqrt of negative values */ 368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(in_sqrt<0) 369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org in_sqrt=-in_sqrt; 370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 3715b3e14c36bf3cf2a0cda2e25895f61b6e3df922dbjornv@webrtc.org newRes = (in_sqrt / res + res) >> 1; 372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org do 373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org res = newRes; 3755b3e14c36bf3cf2a0cda2e25895f61b6e3df922dbjornv@webrtc.org newRes = (in_sqrt / res + res) >> 1; 376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } while (newRes != res && i-- > 0); 377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 378fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org CurveQ8[k] = (int16_t)newRes; 379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* generate array of dither samples in Q7 */ 386fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic void GenerateDitherQ7(int16_t *bufQ7, 387fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint32_t seed, 388fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t length, 389fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t AvgPitchGain_Q12) 390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 392fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t dither1_Q7, dither2_Q7, dither_gain_Q14, shft; 393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (AvgPitchGain_Q12 < 614) /* this threshold should be equal to that in decode_spec() */ 395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < length-2; k += 3) 397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 398fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org /* new random unsigned int32_t */ 399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515; 400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* fixed-point dither sample between -64 and 64 (Q7) */ 402fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org dither1_Q7 = (int16_t)WEBRTC_SPL_RSHIFT_W32((int32_t)seed + 16777216, 25); // * 128/4294967295 403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 404fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org /* new random unsigned int32_t */ 405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515; 406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* fixed-point dither sample between -64 and 64 */ 408fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org dither2_Q7 = (int16_t)WEBRTC_SPL_RSHIFT_W32(seed + 16777216, 25); 409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 410fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org shft = (int16_t)(WEBRTC_SPL_RSHIFT_U32(seed, 25) & 15); 411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (shft < 5) 412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k] = dither1_Q7; 414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k+1] = dither2_Q7; 415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k+2] = 0; 416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else if (shft < 10) 418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k] = dither1_Q7; 420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k+1] = 0; 421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k+2] = dither2_Q7; 422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k] = 0; 426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k+1] = dither1_Q7; 427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k+2] = dither2_Q7; 428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 433fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org dither_gain_Q14 = (int16_t)(22528 - WEBRTC_SPL_MUL(10, AvgPitchGain_Q12)); 434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* dither on half of the coefficients */ 436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < length-1; k += 2) 437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 438fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org /* new random unsigned int32_t */ 439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515; 440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* fixed-point dither sample between -64 and 64 */ 442fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org dither1_Q7 = (int16_t)WEBRTC_SPL_RSHIFT_W32((int32_t)seed + 16777216, 25); 443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* dither sample is placed in either even or odd index */ 445fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org shft = (int16_t)(WEBRTC_SPL_RSHIFT_U32(seed, 25) & 1); /* either 0 or 1 */ 446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 447fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org bufQ7[k + shft] = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(dither_gain_Q14, dither1_Q7) + 8192, 14); 448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k + 1 - shft] = 0; 449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 457b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * function to decode the complex spectrum from the bitstream 458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * returns the total number of bytes in the stream 459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 460fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsacfix_DecodeSpec(Bitstr_dec *streamdata, 461fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *frQ7, 462fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *fiQ7, 463fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t AvgPitchGain_Q12) 464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 465fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t data[FRAMESAMPLES]; 466fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t invARSpec2_Q16[FRAMESAMPLES/4]; 467fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t ARCoefQ12[AR_ORDER+1]; 468fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t RCQ15[AR_ORDER]; 469fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t gainQ10; 470fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t gain2_Q10; 471fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t len; 472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* create dither signal */ 475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GenerateDitherQ7(data, streamdata->W_upper, FRAMESAMPLES, AvgPitchGain_Q12); /* Dither is output in vector 'Data' */ 476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* decode model parameters */ 478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (WebRtcIsacfix_DecodeRcCoef(streamdata, RCQ15) < 0) 479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; 480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 482b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); 483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (WebRtcIsacfix_DecodeGain2(streamdata, &gain2_Q10) < 0) 485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; 486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* compute inverse AR power spectrum */ 488b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CalcInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); 489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* arithmetic decoding of spectrum */ 491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* 'data' input and output. Input = Dither */ 492fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org len = WebRtcIsacfix_DecLogisticMulti2(data, streamdata, invARSpec2_Q16, (int16_t)FRAMESAMPLES); 493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (len<1) 495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; 496b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 497b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* subtract dither and scale down spectral samples with low SNR */ 498b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (AvgPitchGain_Q12 <= 614) 499b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < FRAMESAMPLES; k += 4) 501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 502fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org gainQ10 = WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_LSHIFT_W32((int32_t)30, 10), 503fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org (int16_t)WEBRTC_SPL_RSHIFT_U32(invARSpec2_Q16[k>>2] + (uint32_t)2195456, 16)); 504fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org *frQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[ k ], gainQ10) + 512, 10); 505fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org *fiQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+1], gainQ10) + 512, 10); 506fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org *frQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+2], gainQ10) + 512, 10); 507fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org *fiQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+3], gainQ10) + 512, 10); 508b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 509b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 510b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 511b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 512b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < FRAMESAMPLES; k += 4) 513b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 514fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org gainQ10 = WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_LSHIFT_W32((int32_t)36, 10), 515fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org (int16_t)WEBRTC_SPL_RSHIFT_U32(invARSpec2_Q16[k>>2] + (uint32_t)2654208, 16)); 516fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org *frQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[ k ], gainQ10) + 512, 10); 517fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org *fiQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+1], gainQ10) + 512, 10); 518fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org *frQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+2], gainQ10) + 512, 10); 519fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org *fiQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+3], gainQ10) + 512, 10); 520b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 521b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 522b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 523b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return len; 524b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 525b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 526b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 527fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsacfix_EncodeSpec(const int16_t *fr, 528fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int16_t *fi, 529b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Bitstr_enc *streamdata, 530fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t AvgPitchGain_Q12) 531b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 532fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t dataQ7[FRAMESAMPLES]; 533fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t PSpec[FRAMESAMPLES/4]; 534fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint16_t invARSpecQ8[FRAMESAMPLES/4]; 535fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t CorrQ7[AR_ORDER+1]; 536fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t CorrQ7_norm[AR_ORDER+1]; 537fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t RCQ15[AR_ORDER]; 538fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t ARCoefQ12[AR_ORDER+1]; 539fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t gain2_Q10; 540fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t val; 541fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t nrg; 542fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint32_t sum; 543fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t lft_shft; 544fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t status; 545b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k, n, j; 546b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 547b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 548b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* create dither_float signal */ 549b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GenerateDitherQ7(dataQ7, streamdata->W_upper, FRAMESAMPLES, AvgPitchGain_Q12); 550b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 551b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* add dither and quantize, and compute power spectrum */ 552b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Vector dataQ7 contains Dither in Q7 */ 553b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < FRAMESAMPLES; k += 4) 554b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 555b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org val = ((*fr++ + dataQ7[k] + 64) & 0xFF80) - dataQ7[k]; /* Data = Dither */ 556b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dataQ7[k] = val; /* New value in Data */ 557b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = WEBRTC_SPL_UMUL(val, val); 558b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 559b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org val = ((*fi++ + dataQ7[k+1] + 64) & 0xFF80) - dataQ7[k+1]; /* Data = Dither */ 560b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dataQ7[k+1] = val; /* New value in Data */ 561b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += WEBRTC_SPL_UMUL(val, val); 562b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 563b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org val = ((*fr++ + dataQ7[k+2] + 64) & 0xFF80) - dataQ7[k+2]; /* Data = Dither */ 564b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dataQ7[k+2] = val; /* New value in Data */ 565b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += WEBRTC_SPL_UMUL(val, val); 566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 567b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org val = ((*fi++ + dataQ7[k+3] + 64) & 0xFF80) - dataQ7[k+3]; /* Data = Dither */ 568b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dataQ7[k+3] = val; /* New value in Data */ 569b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += WEBRTC_SPL_UMUL(val, val); 570b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 571b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PSpec[k>>2] = WEBRTC_SPL_RSHIFT_U32(sum, 2); 572b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 573b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 574b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* compute correlation from power spectrum */ 575b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CalcCorrelation(PSpec, CorrQ7); 576b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 577b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 578b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* find AR coefficients */ 579b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* number of bit shifts to 14-bit normalize CorrQ7[0] (leaving room for sign) */ 580b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lft_shft = WebRtcSpl_NormW32(CorrQ7[0]) - 18; 581b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 582b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (lft_shft > 0) { 583b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<AR_ORDER+1; k++) 584b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CorrQ7_norm[k] = WEBRTC_SPL_LSHIFT_W32(CorrQ7[k], lft_shft); 585b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 586b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<AR_ORDER+1; k++) 587b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CorrQ7_norm[k] = WEBRTC_SPL_RSHIFT_W32(CorrQ7[k], -lft_shft); 588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 589b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 590b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* find RC coefficients */ 591b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcSpl_AutoCorrToReflCoef(CorrQ7_norm, AR_ORDER, RCQ15); 592b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 593b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* quantize & code RC Coef */ 594b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = WebRtcIsacfix_EncodeRcCoef(RCQ15, streamdata); 595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (status < 0) { 596b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 597b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 598b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 599b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* RC -> AR coefficients */ 600b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); 601b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 602b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* compute ARCoef' * Corr * ARCoef in Q19 */ 603b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nrg = 0; 604b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j = 0; j <= AR_ORDER; j++) { 605b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n <= j; n++) 606b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nrg += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(ARCoefQ12[j], WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CorrQ7_norm[j-n], ARCoefQ12[n]) + 256, 9)) + 4, 3); 607b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = j+1; n <= AR_ORDER; n++) 608b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nrg += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(ARCoefQ12[j], WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CorrQ7_norm[n-j], ARCoefQ12[n]) + 256, 9)) + 4, 3); 609b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 610b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 611b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (lft_shft > 0) 612b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nrg = WEBRTC_SPL_RSHIFT_W32(nrg, lft_shft); 613b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 614b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nrg = WEBRTC_SPL_LSHIFT_W32(nrg, -lft_shft); 615b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 616b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(nrg>131072) 617b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES >> 2, nrg); /* also shifts 31 bits to the left! */ 618b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 619b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org gain2_Q10 = WEBRTC_SPL_RSHIFT_W32(FRAMESAMPLES, 2); 620b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 621b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* quantize & code gain2_Q10 */ 622b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (WebRtcIsacfix_EncodeGain2(&gain2_Q10, streamdata)) 623b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 624b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 625b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* compute inverse AR magnitude spectrum */ 626b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CalcRootInvArSpec(ARCoefQ12, gain2_Q10, invARSpecQ8); 627b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 628b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 629b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* arithmetic coding of spectrum */ 630fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org status = WebRtcIsacfix_EncLogisticMulti2(streamdata, dataQ7, invARSpecQ8, (int16_t)FRAMESAMPLES); 631b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ( status ) 632b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return( status ); 633b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 634b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 635b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 636b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 637b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 638b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Matlab's LAR definition */ 639fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic void Rc2LarFix(const int16_t *rcQ15, int32_t *larQ17, int16_t order) { 640b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 641b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* 642b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 643b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org This is a piece-wise implemenetation of a rc2lar-function (all values in the comment 644b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org are Q15 values and are based on [0 24956/32768 30000/32768 32500/32768], i.e. 645b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org [0.76159667968750 0.91552734375000 0.99182128906250] 646b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 647b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org x0 x1 a k x0(again) b 648b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ================================================================================== 649b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 0.00 0.76: 0 2.625997508581 0 0 650b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 0.76 0.91: 2.000012018559 7.284502668663 0.761596679688 -3.547841027073 651b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 0.91 0.99: 3.121320351712 31.115835041229 0.915527343750 -25.366077452148 652b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 0.99 1.00: 5.495270168700 686.663805654056 0.991821289063 -675.552510708011 653b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 654b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org The implementation is y(x)= a + (x-x0)*k, but this can be simplified to 655b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 656b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org y(x) = a-x0*k + x*k = b + x*k, where b = a-x0*k 657b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 658b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org akx=[0 2.625997508581 0 659b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2.000012018559 7.284502668663 0.761596679688 660b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 3.121320351712 31.115835041229 0.915527343750 661b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 5.495270168700 686.663805654056 0.991821289063]; 662b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 663b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org b = akx(:,1) - akx(:,3).*akx(:,2) 664b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 665b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org [ 0.0 666b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org -3.547841027073 667b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org -25.366077452148 668b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org -675.552510708011] 669b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 670b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 671b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 672b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 673fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t rc; 674fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t larAbsQ17; 675b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 676b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < order; k++) { 677b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 678b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rc = WEBRTC_SPL_ABS_W16(rcQ15[k]); //Q15 679b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 680b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Calculate larAbsQ17 in Q17 from rc in Q15 */ 681b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 682b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (rc<24956) { //0.7615966 in Q15 683b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // (Q15*Q13)>>11 = Q17 684b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org larAbsQ17 = WEBRTC_SPL_MUL_16_16_RSFT(rc, 21512, 11); 685b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (rc<30000) { //0.91552734375 in Q15 686b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Q17 + (Q15*Q12)>>10 = Q17 687b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org larAbsQ17 = -465024 + WEBRTC_SPL_MUL_16_16_RSFT(rc, 29837, 10); 688b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (rc<32500) { //0.99182128906250 in Q15 689b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Q17 + (Q15*Q10)>>8 = Q17 690b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org larAbsQ17 = -3324784 + WEBRTC_SPL_MUL_16_16_RSFT(rc, 31863, 8); 691b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 692b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Q17 + (Q15*Q5)>>3 = Q17 693b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org larAbsQ17 = -88546020 + WEBRTC_SPL_MUL_16_16_RSFT(rc, 21973, 3); 694b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 695b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 696b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (rcQ15[k]>0) { 697b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org larQ17[k] = larAbsQ17; 698b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 699b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org larQ17[k] = -larAbsQ17; 700b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 701b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 702b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 703b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 704b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 705fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic void Lar2RcFix(const int32_t *larQ17, int16_t *rcQ15, int16_t order) { 706b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 707b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* 708b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org This is a piece-wise implemenetation of a lar2rc-function 709b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org See comment in Rc2LarFix() about details. 710b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 711b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 712b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 713fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t larAbsQ11; 714fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t rc; 715b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 716b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < order; k++) { 717b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 718fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org larAbsQ11 = (int16_t) WEBRTC_SPL_ABS_W32(WEBRTC_SPL_RSHIFT_W32(larQ17[k]+32,6)); //Q11 719b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 720b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (larAbsQ11<4097) { //2.000012018559 in Q11 721b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Q11*Q16>>12 = Q15 722b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rc = WEBRTC_SPL_MUL_16_16_RSFT(larAbsQ11, 24957, 12); 723b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (larAbsQ11<6393) { //3.121320351712 in Q11 724b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // (Q11*Q17 + Q13)>>13 = Q15 725b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rc = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(larAbsQ11, 17993) + 130738688), 13); 726b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (larAbsQ11<11255) { //5.495270168700 in Q11 727b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // (Q11*Q19 + Q30)>>15 = Q15 728b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rc = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(larAbsQ11, 16850) + 875329820), 15); 729b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 730b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // (Q11*Q24>>16 + Q19)>>4 = Q15 731b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rc = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16_RSFT(larAbsQ11, 24433, 16)) + 515804), 4); 732b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 733b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 734b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (larQ17[k]<=0) { 735b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rc = -rc; 736b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 737b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 738fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org rcQ15[k] = (int16_t) rc; // Q15 739b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 740b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 741b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 742fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic void Poly2LarFix(int16_t *lowbandQ15, 743fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t orderLo, 744fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *hibandQ15, 745fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t orderHi, 746fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t Nsub, 747fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t *larsQ17) { 748b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 749b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k, n; 750fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t *outpQ17; 751fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t orderTot; 752fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t larQ17[MAX_ORDER]; // Size 7+6 is enough 753b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 754b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org orderTot = (orderLo + orderHi); 755b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outpQ17 = larsQ17; 756b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < Nsub; k++) { 757b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 758b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Rc2LarFix(lowbandQ15, larQ17, orderLo); 759b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 760b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < orderLo; n++) 761b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outpQ17[n] = larQ17[n]; //Q17 762b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 763b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Rc2LarFix(hibandQ15, larQ17, orderHi); 764b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 765b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < orderHi; n++) 766b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outpQ17[n + orderLo] = larQ17[n]; //Q17; 767b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 768b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outpQ17 += orderTot; 769b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lowbandQ15 += orderLo; 770b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org hibandQ15 += orderHi; 771b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 772b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 773b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 774b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 775fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic void Lar2polyFix(int32_t *larsQ17, 776fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *lowbandQ15, 777fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t orderLo, 778fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *hibandQ15, 779fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t orderHi, 780fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t Nsub) { 781b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 782b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k, n; 783fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t orderTot; 784fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *outplQ15, *outphQ15; 785fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t *inpQ17; 786fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t rcQ15[7+6]; 787b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 788b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org orderTot = (orderLo + orderHi); 789b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outplQ15 = lowbandQ15; 790b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outphQ15 = hibandQ15; 791b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inpQ17 = larsQ17; 792b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < Nsub; k++) { 793b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 794b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* gains not handled here as in the FLP version */ 795b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 796b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Low band */ 797b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Lar2RcFix(&inpQ17[0], rcQ15, orderLo); 798b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < orderLo; n++) 799b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outplQ15[n] = rcQ15[n]; // Refl. coeffs 800b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 801b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* High band */ 802b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Lar2RcFix(&inpQ17[orderLo], rcQ15, orderHi); 803b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < orderHi; n++) 804b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outphQ15[n] = rcQ15[n]; // Refl. coeffs 805b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 806b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inpQ17 += orderTot; 807b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outplQ15 += orderLo; 808b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outphQ15 += orderHi; 809b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 810b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 811b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 8126b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org/* 8136b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.orgFunction WebRtcIsacfix_MatrixProduct1C() does one form of matrix multiplication. 8146b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.orgIt first shifts input data of one matrix, determines the right indexes for the 8156b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.orgtwo matrixes, multiply them, and write the results into an output buffer. 8166b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org 8176b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.orgNote that two factors (or, multipliers) determine the initialization values of 8186b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.orgthe variable |matrix1_index| in the code. The relationship is 8196b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org|matrix1_index| = |matrix1_index_factor1| * |matrix1_index_factor2|, where 8206b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org|matrix1_index_factor1| is given by the argument while |matrix1_index_factor2| 8216b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.orgis determined by the value of argument |matrix1_index_init_case|; 8226b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org|matrix1_index_factor2| is the value of the outmost loop counter j (when 8236b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org|matrix1_index_init_case| is 0), or the value of the middle loop counter k (when 8246b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org|matrix1_index_init_case| is non-zero). 8256b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org 8266b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org|matrix0_index| is determined the same way. 8276b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org 8286b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.orgArguments: 8296b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix0[]: matrix0 data in Q15 domain. 8306b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix1[]: matrix1 data. 8316b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix_product[]: output data (matrix product). 8326b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix1_index_factor1: The first of two factors determining the 8336b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org initialization value of matrix1_index. 8346b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix0_index_factor1: The first of two factors determining the 8356b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org initialization value of matrix0_index. 8366b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix1_index_init_case: Case number for selecting the second of two 8376b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org factors determining the initialization value 8386b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org of matrix1_index and matrix0_index. 8396b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix1_index_step: Incremental step for matrix1_index. 8406b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix0_index_step: Incremental step for matrix0_index. 8416b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org inner_loop_count: Maximum count of the inner loop. 8426b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org mid_loop_count: Maximum count of the intermediate loop. 8436b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org shift: Left shift value for matrix1. 8446b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org*/ 8456b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.orgvoid WebRtcIsacfix_MatrixProduct1C(const int16_t matrix0[], 8466b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org const int32_t matrix1[], 8476b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org int32_t matrix_product[], 8486b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org const int matrix1_index_factor1, 8496b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org const int matrix0_index_factor1, 8506b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org const int matrix1_index_init_case, 8516b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org const int matrix1_index_step, 8526b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org const int matrix0_index_step, 8536b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org const int inner_loop_count, 8546b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org const int mid_loop_count, 8556b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org const int shift) { 8566b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org int j = 0, k = 0, n = 0; 8576b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org int matrix0_index = 0, matrix1_index = 0, matrix_prod_index = 0; 8586b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org int* matrix0_index_factor2 = &k; 8596b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org int* matrix1_index_factor2 = &j; 8606b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org if (matrix1_index_init_case != 0) { 8616b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix0_index_factor2 = &j; 8626b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix1_index_factor2 = &k; 8636b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org } 8646b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org 8656b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org for (j = 0; j < SUBFRAMES; j++) { 8666b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix_prod_index = mid_loop_count * j; 8676b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org for (k = 0; k < mid_loop_count; k++) { 8686b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org int32_t sum32 = 0; 8696b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix0_index = matrix0_index_factor1 * (*matrix0_index_factor2); 8706b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix1_index = matrix1_index_factor1 * (*matrix1_index_factor2); 8716b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org for (n = 0; n < inner_loop_count; n++) { 8726b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org sum32 += (WEBRTC_SPL_MUL_16_32_RSFT16(matrix0[matrix0_index], 8736b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix1[matrix1_index] << shift)); 8746b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix0_index += matrix0_index_step; 8756b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix1_index += matrix1_index_step; 8766b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org } 8776b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix_product[matrix_prod_index] = sum32; 8786b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix_prod_index++; 8796b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org } 8806b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org } 8816b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org} 8826b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org 8836b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org/* 8846b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.orgFunction WebRtcIsacfix_MatrixProduct2C() returns the product of two matrixes, 8856b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.orgone of which has two columns. It first has to determine the correct index of 8866b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.orgthe first matrix before doing the actual element multiplication. 8876b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org 8886b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.orgArguments: 8896b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix0[]: A matrix in Q15 domain. 8906b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix1[]: A matrix in Q21 domain. 8916b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix_product[]: Output data in Q17 domain. 8926b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix0_index_factor: A factor determining the initialization value 8936b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org of matrix0_index. 8946b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix0_index_step: Incremental step for matrix0_index. 8956b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org*/ 8966b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.orgvoid WebRtcIsacfix_MatrixProduct2C(const int16_t matrix0[], 8976b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org const int32_t matrix1[], 8986b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org int32_t matrix_product[], 8996b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org const int matrix0_index_factor, 9006b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org const int matrix0_index_step) { 9016b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org int j = 0, n = 0; 9026b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org int matrix1_index = 0, matrix0_index = 0, matrix_prod_index = 0; 9036b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org for (j = 0; j < SUBFRAMES; j++) { 9046b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org int32_t sum32 = 0, sum32_2 = 0; 9056b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix1_index = 0; 9066b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix0_index = matrix0_index_factor * j; 9076b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org for (n = SUBFRAMES; n > 0; n--) { 9086b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org sum32 += (WEBRTC_SPL_MUL_16_32_RSFT16(matrix0[matrix0_index], 9096b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix1[matrix1_index])); 9106b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org sum32_2 += (WEBRTC_SPL_MUL_16_32_RSFT16(matrix0[matrix0_index], 9116b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix1[matrix1_index + 1])); 9126b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix1_index += 2; 9136b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix0_index += matrix0_index_step; 9146b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org } 9156b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix_product[matrix_prod_index] = sum32 >> 3; 9166b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix_product[matrix_prod_index + 1] = sum32_2 >> 3; 9176b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org matrix_prod_index += 2; 9186b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org } 9196b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org} 9206b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org 921fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsacfix_DecodeLpc(int32_t *gain_lo_hiQ17, 922fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *LPCCoef_loQ15, 923fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *LPCCoef_hiQ15, 924b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Bitstr_dec *streamdata, 925fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *outmodel) { 926b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 927fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t larsQ17[KLT_ORDER_SHAPE]; // KLT_ORDER_GAIN+KLT_ORDER_SHAPE == (ORDERLO+ORDERHI)*SUBFRAMES 928b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int err; 929b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 930b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsacfix_DecodeLpcCoef(streamdata, larsQ17, gain_lo_hiQ17, outmodel); 931b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err<0) // error check 932b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_LPC; 933b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 934b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Lar2polyFix(larsQ17, LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES); 935b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 936b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 937b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 938b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 939b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* decode & dequantize LPC Coef */ 940b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint WebRtcIsacfix_DecodeLpcCoef(Bitstr_dec *streamdata, 941fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t *LPCCoefQ17, 942fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t *gain_lo_hiQ17, 943fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *outmodel) 944b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 945b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int j, k, n; 946b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int err; 947fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t pos, pos2, posg, poss; 948fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t gainpos; 949fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t model; 950fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t index_QQ[KLT_ORDER_SHAPE]; 951fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t tmpcoeffs_gQ17[KLT_ORDER_GAIN]; 952fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t tmpcoeffs2_gQ21[KLT_ORDER_GAIN]; 953fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t tmpcoeffs_sQ10[KLT_ORDER_SHAPE]; 954fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t tmpcoeffs_sQ17[KLT_ORDER_SHAPE]; 955fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t tmpcoeffs2_sQ18[KLT_ORDER_SHAPE]; 956fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t sumQQ; 957fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t sumQQ16; 958fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t tmp32; 959b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 960b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 961b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 962b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy decoding of model number */ 963b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsacfix_DecHistOneStepMulti(&model, streamdata, WebRtcIsacfix_kModelCdfPtr, WebRtcIsacfix_kModelInitIndex, 1); 964b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err<0) // error check 965b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 966b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 967b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy decoding of quantization indices */ 968b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsacfix_DecHistOneStepMulti(index_QQ, streamdata, WebRtcIsacfix_kCdfShapePtr[model], WebRtcIsacfix_kInitIndexShape[model], KLT_ORDER_SHAPE); 969b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err<0) // error check 970b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 971b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* find quantization levels for coefficients */ 972b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<KLT_ORDER_SHAPE; k++) { 973b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_sQ10[WebRtcIsacfix_kSelIndShape[k]] = WebRtcIsacfix_kLevelsShapeQ10[WebRtcIsacfix_kOfLevelsShape[model]+WebRtcIsacfix_kOffsetShape[model][k] + index_QQ[k]]; 974b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 975b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 976b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsacfix_DecHistOneStepMulti(index_QQ, streamdata, WebRtcIsacfix_kCdfGainPtr[model], WebRtcIsacfix_kInitIndexGain[model], KLT_ORDER_GAIN); 977b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err<0) // error check 978b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 979b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* find quantization levels for coefficients */ 980b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<KLT_ORDER_GAIN; k++) { 981b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_gQ17[WebRtcIsacfix_kSelIndGain[k]] = WebRtcIsacfix_kLevelsGainQ17[WebRtcIsacfix_kOfLevelsGain[model]+ WebRtcIsacfix_kOffsetGain[model][k] + index_QQ[k]]; 982b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 983b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 984b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 985b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* inverse KLT */ 986b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 987b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* left transform */ // Transpose matrix! 9886b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT1GainQ15[model], tmpcoeffs_gQ17, 9896b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org tmpcoeffs2_gQ21, kTIndexFactor2, kTIndexFactor2, 9906b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTInitCase0, kTIndexStep1, kTIndexStep1, 9916b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTLoopCount2, kTLoopCount2, kTMatrix1_shift5); 9926b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org 993b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org poss = 0; 994b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j=0; j<SUBFRAMES; j++) { 995b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<LPC_SHAPE_ORDER; k++) { 996b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sumQQ = 0; 9976b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org pos = LPC_SHAPE_ORDER * j; 9986b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org pos2 = LPC_SHAPE_ORDER * k; 999b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n=0; n<LPC_SHAPE_ORDER; n++) { 1000b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sumQQ += WEBRTC_SPL_MUL_16_16_RSFT(tmpcoeffs_sQ10[pos], WebRtcIsacfix_kT1ShapeQ15[model][pos2], 7); // (Q10*Q15)>>7 = Q18 1001b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++; 1002b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2++; 1003b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1004b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs2_sQ18[poss] = sumQQ; //Q18 1005b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org poss++; 1006b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1007b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1008b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1009b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* right transform */ // Transpose matrix 10106b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21, 10116b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org tmpcoeffs_gQ17, kTIndexFactor1, kTIndexStep2); 10126b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT2ShapeQ15[model], 10136b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org tmpcoeffs2_sQ18, tmpcoeffs_sQ17, kTIndexFactor1, kTIndexFactor1, 10146b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTInitCase1, kTIndexStep3, kTIndexStep2, kTLoopCount1, kTLoopCount3, 10156b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTMatrix1_shift0); 1016b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1017b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* scaling, mean addition, and gain restoration */ 1018b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org gainpos = 0; 1019b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg = 0;poss = 0;pos=0; 1020b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<SUBFRAMES; k++) { 1021b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1022b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* log gains */ 1023fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org sumQQ16 = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9 1024b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sumQQ16 += WebRtcIsacfix_kMeansGainQ8[model][posg]; 1025b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out 1026b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org gain_lo_hiQ17[gainpos] = sumQQ; //Q17 1027b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org gainpos++; 1028b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg++; 1029b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1030fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org sumQQ16 = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9 1031b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sumQQ16 += WebRtcIsacfix_kMeansGainQ8[model][posg]; 1032b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out 1033b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org gain_lo_hiQ17[gainpos] = sumQQ; //Q17 1034b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org gainpos++; 1035b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg++; 1036b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1037b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* lo band LAR coeffs */ 1038b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n=0; n<ORDERLO; n++, pos++, poss++) { 1039b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(31208, tmpcoeffs_sQ17[poss]); // (Q16*Q17)>>16 = Q17, with 1/2.1 = 0.47619047619 ~= 31208 in Q16 1040b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[model][poss]; // Q17+Q17 = Q17 1041b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoefQ17[pos] = tmp32; 1042b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1043b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1044b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* hi band LAR coeffs */ 1045b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n=0; n<ORDERHI; n++, pos++, poss++) { 1046b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp32 = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(18204, tmpcoeffs_sQ17[poss]), 3); // ((Q13*Q17)>>16)<<3 = Q17, with 1/0.45 = 2.222222222222 ~= 18204 in Q13 1047b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[model][poss]; // Q17+Q17 = Q17 1048b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoefQ17[pos] = tmp32; 1049b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1050b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1051b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1052b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1053b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *outmodel=model; 1054b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1055b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1056b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1057b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1058b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* estimate codel length of LPC Coef */ 1059fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic int EstCodeLpcCoef(int32_t *LPCCoefQ17, 1060fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t *gain_lo_hiQ17, 1061fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *model, 1062fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t *sizeQ11, 1063b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Bitstr_enc *streamdata, 1064b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISAC_SaveEncData_t* encData, 1065b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcode_obj *transcodingParam) { 1066b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int j, k, n; 1067fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t posQQ, pos2QQ, gainpos; 1068fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t pos, poss, posg, offsg; 1069fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t index_gQQ[KLT_ORDER_GAIN], index_sQQ[KLT_ORDER_SHAPE]; 1070fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t index_ovr_gQQ[KLT_ORDER_GAIN], index_ovr_sQQ[KLT_ORDER_SHAPE]; 1071fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t BitsQQ; 1072fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org 1073fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t tmpcoeffs_gQ6[KLT_ORDER_GAIN]; 1074fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t tmpcoeffs_gQ17[KLT_ORDER_GAIN]; 1075fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t tmpcoeffs_sQ17[KLT_ORDER_SHAPE]; 1076fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t tmpcoeffs2_gQ21[KLT_ORDER_GAIN]; 1077fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t tmpcoeffs2_sQ17[KLT_ORDER_SHAPE]; 1078fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t sumQQ; 1079fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t tmp32; 1080fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t sumQQ16; 1081b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int status = 0; 1082b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1083b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* write LAR coefficients to statistics file */ 1084b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save data for creation of multiple bitstreams (and transcoding) */ 1085b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (encData != NULL) { 1086b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<KLT_ORDER_GAIN; k++) { 1087b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org encData->LPCcoeffs_g[KLT_ORDER_GAIN*encData->startIdx + k] = gain_lo_hiQ17[k]; 1088b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1089b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1090b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1091b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* log gains, mean removal and scaling */ 1092b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg = 0;poss = 0;pos=0; gainpos=0; 1093b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1094b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<SUBFRAMES; k++) { 1095b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* log gains */ 1096b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1097b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* The input argument X to logN(X) is 2^17 times higher than the 1098b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org input floating point argument Y to log(Y), since the X value 1099b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org is a Q17 value. This can be compensated for after the call, by 1100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org subraction a value Z for each Q-step. One Q-step means that 1101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org X gets 2 times higher, i.e. Z = logN(2)*256 = 0.693147180559*256 = 1102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 177.445678 should be subtracted (since logN() returns a Q8 value). 1103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org For a X value in Q17, the value 177.445678*17 = 3017 should be 1104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org subtracted */ 1105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 1106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 1107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg++; gainpos++; 1108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 1110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 1111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg++; gainpos++; 1112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* lo band LAR coeffs */ 1114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n=0; n<ORDERLO; n++, poss++, pos++) { 1115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp32 = LPCCoefQ17[pos] - WebRtcIsacfix_kMeansShapeQ17[0][poss]; //Q17 1116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(17203, tmp32<<3); // tmp32 = 2.1*tmp32 1117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_sQ17[poss] = tmp32; //Q17 1118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* hi band LAR coeffs */ 1121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n=0; n<ORDERHI; n++, poss++, pos++) { 1122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp32 = LPCCoefQ17[pos] - WebRtcIsacfix_kMeansShapeQ17[0][poss]; //Q17 1123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(14746, tmp32<<1); // tmp32 = 0.45*tmp32 1124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_sQ17[poss] = tmp32; //Q17 1125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* KLT */ 1131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* left transform */ 1133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offsg = 0; 11346b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org posg = 0; 1135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j=0; j<SUBFRAMES; j++) { 11366b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org // Q21 = Q6 * Q15 11376b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org sumQQ = WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg], 11386b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][0]); 11396b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg + 1], 11406b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][2]); 11416b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org tmpcoeffs2_gQ21[posg] = sumQQ; 11426b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org posg++; 11436b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org 11446b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org // Q21 = Q6 * Q15 11456b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org sumQQ = WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg], 11466b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][1]); 11476b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg + 1], 11486b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][3]); 11496b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org tmpcoeffs2_gQ21[posg] = sumQQ; 11506b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org posg++; 11516b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org 1152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offsg += 2; 1153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11556b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT1ShapeQ15[0], tmpcoeffs_sQ17, 11566b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org tmpcoeffs2_sQ17, kTIndexFactor4, kTIndexFactor1, kTInitCase0, 11576b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTIndexStep1, kTIndexStep3, kTLoopCount3, kTLoopCount3, kTMatrix1_shift1); 11586b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org 1159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* right transform */ 11606b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21, 11616b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org tmpcoeffs_gQ17, kTIndexFactor3, kTIndexStep1); 11626b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org 11636b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT2ShapeQ15[0], tmpcoeffs2_sQ17, 11646b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org tmpcoeffs_sQ17, kTIndexFactor1, kTIndexFactor3, kTInitCase1, kTIndexStep3, 11656b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTIndexStep1, kTLoopCount1, kTLoopCount3, kTMatrix1_shift1); 1166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* quantize coefficients */ 1168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org BitsQQ = 0; 1170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok? 1171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posQQ = WebRtcIsacfix_kSelIndGain[k]; 1173fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org pos2QQ= (int16_t)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17); 1174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok? 1176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (index_gQQ[k] < 0) { 1177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_gQQ[k] = 0; 1178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) { 1180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k]; 1181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_ovr_gQQ[k] = WebRtcIsacfix_kOffsetGain[0][k]+index_gQQ[k]; 1183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posQQ = WebRtcIsacfix_kOfLevelsGain[0] + index_ovr_gQQ[k]; 1184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save data for creation of multiple bitstreams */ 1186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (encData != NULL) { 1187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org encData->LPCindex_g[KLT_ORDER_GAIN*encData->startIdx + k] = index_gQQ[k]; 1188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* determine number of bits */ 1191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sumQQ = WebRtcIsacfix_kCodeLenGainQ11[posQQ]; //Q11 1192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org BitsQQ += sumQQ; 1193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<KLT_ORDER_SHAPE; k++) //ATTN: ok? 1196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1197fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org index_sQQ[k] = (int16_t)(CalcLrIntQ(tmpcoeffs_sQ17[WebRtcIsacfix_kSelIndShape[k]], 17) + WebRtcIsacfix_kQuantMinShape[k]); //ATTN: ok? 1198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (index_sQQ[k] < 0) 1200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_sQQ[k] = 0; 1201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else if (index_sQQ[k] > WebRtcIsacfix_kMaxIndShape[k]) 1202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_sQQ[k] = WebRtcIsacfix_kMaxIndShape[k]; 1203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_ovr_sQQ[k] = WebRtcIsacfix_kOffsetShape[0][k]+index_sQQ[k]; 1204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posQQ = WebRtcIsacfix_kOfLevelsShape[0] + index_ovr_sQQ[k]; 1206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sumQQ = WebRtcIsacfix_kCodeLenShapeQ11[posQQ]; //Q11 1207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org BitsQQ += sumQQ; 1208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *model = 0; 1213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *sizeQ11=BitsQQ; 1214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy coding of model number */ 1216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = WebRtcIsacfix_EncHistMulti(streamdata, model, WebRtcIsacfix_kModelCdfPtr, 1); 1217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (status < 0) { 1218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 1219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy coding of quantization indices - shape only */ 1222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = WebRtcIsacfix_EncHistMulti(streamdata, index_sQQ, WebRtcIsacfix_kCdfShapePtr[0], KLT_ORDER_SHAPE); 1223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (status < 0) { 1224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 1225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save data for creation of multiple bitstreams */ 1228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (encData != NULL) { 1229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<KLT_ORDER_SHAPE; k++) 1230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org encData->LPCindex_s[KLT_ORDER_SHAPE*encData->startIdx + k] = index_sQQ[k]; 1232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* save the state of the bitstream object 'streamdata' for the possible bit-rate reduction */ 1235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam->full = streamdata->full; 1236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam->stream_index = streamdata->stream_index; 1237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam->streamval = streamdata->streamval; 1238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam->W_upper = streamdata->W_upper; 1239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam->beforeLastWord = streamdata->stream[streamdata->stream_index-1]; 1240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam->lastWord = streamdata->stream[streamdata->stream_index]; 1241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy coding of index */ 1243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = WebRtcIsacfix_EncHistMulti(streamdata, index_gQQ, WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN); 1244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (status < 0) { 1245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 1246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* find quantization levels for shape coefficients */ 1249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<KLT_ORDER_SHAPE; k++) { 1250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_sQ17[WebRtcIsacfix_kSelIndShape[k]] = WEBRTC_SPL_MUL(128, WebRtcIsacfix_kLevelsShapeQ10[WebRtcIsacfix_kOfLevelsShape[0]+index_ovr_sQQ[k]]); 1251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* inverse KLT */ 1254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* left transform */ // Transpose matrix! 12566b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT1ShapeQ15[0], tmpcoeffs_sQ17, 12576b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org tmpcoeffs2_sQ17, kTIndexFactor4, kTIndexFactor4, kTInitCase0, 12586b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTIndexStep1, kTIndexStep1, kTLoopCount3, kTLoopCount3, kTMatrix1_shift1); 1259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* right transform */ // Transpose matrix 12616b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT2ShapeQ15[0], tmpcoeffs2_sQ17, 12626b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org tmpcoeffs_sQ17, kTIndexFactor1, kTIndexFactor1, kTInitCase1, kTIndexStep3, 12636b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org kTIndexStep2, kTLoopCount1, kTLoopCount3, kTMatrix1_shift1); 1264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* scaling, mean addition, and gain restoration */ 1266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org poss = 0;pos=0; 1267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<SUBFRAMES; k++) { 1268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* lo band LAR coeffs */ 1270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n=0; n<ORDERLO; n++, pos++, poss++) { 1271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(31208, tmpcoeffs_sQ17[poss]); // (Q16*Q17)>>16 = Q17, with 1/2.1 = 0.47619047619 ~= 31208 in Q16 1272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[0][poss]; // Q17+Q17 = Q17 1273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoefQ17[pos] = tmp32; 1274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* hi band LAR coeffs */ 1277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n=0; n<ORDERHI; n++, pos++, poss++) { 1278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp32 = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(18204, tmpcoeffs_sQ17[poss]), 3); // ((Q13*Q17)>>16)<<3 = Q17, with 1/0.45 = 2.222222222222 ~= 18204 in Q13 1279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[0][poss]; // Q17+Q17 = Q17 1280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoefQ17[pos] = tmp32; 1281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org //to update tmpcoeffs_gQ17 to the proper state 1286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<KLT_ORDER_GAIN; k++) { 1287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_gQ17[WebRtcIsacfix_kSelIndGain[k]] = WebRtcIsacfix_kLevelsGainQ17[WebRtcIsacfix_kOfLevelsGain[0]+index_ovr_gQQ[k]]; 1288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* find quantization levels for coefficients */ 1293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* left transform */ 1295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offsg = 0; 1296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg = 0; 1297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j=0; j<SUBFRAMES; j++) { 12986b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org // (Q15 * Q17) >> (16 - 1) = Q17; Q17 << 4 = Q21. 12996b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org sumQQ = (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[0][0], 13006b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org tmpcoeffs_gQ17[offsg]) << 1); 13016b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[0][1], 13026b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org tmpcoeffs_gQ17[offsg + 1]) << 1); 13036b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org tmpcoeffs2_gQ21[posg] = WEBRTC_SPL_LSHIFT_W32(sumQQ, 4); 13046b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org posg++; 13056b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org 13066b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org sumQQ = (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[0][2], 13076b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org tmpcoeffs_gQ17[offsg]) << 1); 13086b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[0][3], 13096b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org tmpcoeffs_gQ17[offsg + 1]) << 1); 13106b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org tmpcoeffs2_gQ21[posg] = WEBRTC_SPL_LSHIFT_W32(sumQQ, 4); 13116b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org posg++; 1312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offsg += 2; 1313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* right transform */ // Transpose matrix 13166b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21, 13176b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org tmpcoeffs_gQ17, kTIndexFactor1, kTIndexStep2); 1318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* scaling, mean addition, and gain restoration */ 1320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg = 0; 1321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org gainpos = 0; 1322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<2*SUBFRAMES; k++) { 1323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1324fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org sumQQ16 = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9 1325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sumQQ16 += WebRtcIsacfix_kMeansGainQ8[0][posg]; 1326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out 1327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org gain_lo_hiQ17[gainpos] = sumQQ; //Q17 1328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org gainpos++; 1330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++;posg++; 1331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1336fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsacfix_EstCodeLpcGain(int32_t *gain_lo_hiQ17, 1337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Bitstr_enc *streamdata, 1338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISAC_SaveEncData_t* encData) { 13396b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org int j, k; 1340fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t posQQ, pos2QQ, gainpos; 1341fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t posg; 1342fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t index_gQQ[KLT_ORDER_GAIN]; 1343fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org 1344fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t tmpcoeffs_gQ6[KLT_ORDER_GAIN]; 1345fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t tmpcoeffs_gQ17[KLT_ORDER_GAIN]; 1346fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t tmpcoeffs2_gQ21[KLT_ORDER_GAIN]; 1347fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t sumQQ; 1348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int status = 0; 1349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* write LAR coefficients to statistics file */ 1351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save data for creation of multiple bitstreams (and transcoding) */ 1352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (encData != NULL) { 1353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<KLT_ORDER_GAIN; k++) { 1354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org encData->LPCcoeffs_g[KLT_ORDER_GAIN*encData->startIdx + k] = gain_lo_hiQ17[k]; 1355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* log gains, mean removal and scaling */ 13596b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org posg = 0; gainpos = 0; 1360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<SUBFRAMES; k++) { 1362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* log gains */ 1363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* The input argument X to logN(X) is 2^17 times higher than the 1365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org input floating point argument Y to log(Y), since the X value 1366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org is a Q17 value. This can be compensated for after the call, by 1367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org subraction a value Z for each Q-step. One Q-step means that 1368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org X gets 2 times higher, i.e. Z = logN(2)*256 = 0.693147180559*256 = 1369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 177.445678 should be subtracted (since logN() returns a Q8 value). 1370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org For a X value in Q17, the value 177.445678*17 = 3017 should be 1371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org subtracted */ 1372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 1373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 1374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg++; gainpos++; 1375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 1377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 1378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg++; gainpos++; 1379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* KLT */ 1383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* left transform */ 13856b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org posg = 0; 1386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j=0; j<SUBFRAMES; j++) { 13876b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org // Q21 = Q6 * Q15 13886b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org sumQQ = WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[j * 2], 13896b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][0]); 13906b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[j * 2 + 1], 13916b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][2]); 1392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs2_gQ21[posg] = sumQQ; 1393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg++; 1394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 13956b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org sumQQ = WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[j * 2], 13966b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][1]); 13976b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[j * 2 + 1], 13986b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][3]); 13996b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org tmpcoeffs2_gQ21[posg] = sumQQ; 1400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg++; 1401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 14036b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org /* right transform */ 14046b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21, 14056b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org tmpcoeffs_gQ17, kTIndexFactor3, kTIndexStep1); 14066b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org 1407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* quantize coefficients */ 1408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok? 1410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posQQ = WebRtcIsacfix_kSelIndGain[k]; 1412fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org pos2QQ= (int16_t)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17); 1413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok? 1415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (index_gQQ[k] < 0) { 1416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_gQQ[k] = 0; 1417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) { 1419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k]; 1420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save data for creation of multiple bitstreams */ 1423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (encData != NULL) { 1424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org encData->LPCindex_g[KLT_ORDER_GAIN*encData->startIdx + k] = index_gQQ[k]; 1425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy coding of index */ 1429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = WebRtcIsacfix_EncHistMulti(streamdata, index_gQQ, WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN); 1430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (status < 0) { 1431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 1432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1438fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsacfix_EncodeLpc(int32_t *gain_lo_hiQ17, 1439fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *LPCCoef_loQ15, 1440fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *LPCCoef_hiQ15, 1441fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *model, 1442fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t *sizeQ11, 1443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Bitstr_enc *streamdata, 1444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISAC_SaveEncData_t* encData, 1445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcode_obj *transcodeParam) 1446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int status = 0; 1448fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t larsQ17[KLT_ORDER_SHAPE]; // KLT_ORDER_SHAPE == (ORDERLO+ORDERHI)*SUBFRAMES 1449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // = (6+12)*6 == 108 1450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Poly2LarFix(LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES, larsQ17); 1452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 14536b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org status = EstCodeLpcCoef(larsQ17, gain_lo_hiQ17, model, sizeQ11, 14546b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org streamdata, encData, transcodeParam); 1455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (status < 0) { 1456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return (status); 1457b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Lar2polyFix(larsQ17, LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES); 1460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* decode & dequantize RC */ 1466fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsacfix_DecodeRcCoef(Bitstr_dec *streamdata, int16_t *RCQ15) 1467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k, err; 1469fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t index[AR_ORDER]; 1470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy decoding of quantization indices */ 1472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsacfix_DecHistOneStepMulti(index, streamdata, WebRtcIsacfix_kRcCdfPtr, WebRtcIsacfix_kRcInitInd, AR_ORDER); 1473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err<0) // error check 1474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 1475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* find quantization levels for reflection coefficients */ 1477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<AR_ORDER; k++) 1478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RCQ15[k] = *(WebRtcIsacfix_kRcLevPtr[k] + index[k]); 1480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1482b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* quantize & code RC */ 1488fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsacfix_EncodeRcCoef(int16_t *RCQ15, Bitstr_enc *streamdata) 1489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 1491fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t index[AR_ORDER]; 1492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int status; 1493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* quantize reflection coefficients (add noise feedback?) */ 1495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<AR_ORDER; k++) 1496b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1497b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index[k] = WebRtcIsacfix_kRcInitInd[k]; 1498b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1499b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (RCQ15[k] > WebRtcIsacfix_kRcBound[index[k]]) 1500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while (RCQ15[k] > WebRtcIsacfix_kRcBound[index[k] + 1]) 1502b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index[k]++; 1503b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1504b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 1505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1506b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while (RCQ15[k] < WebRtcIsacfix_kRcBound[--index[k]]) ; 1507b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1508b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1509b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RCQ15[k] = *(WebRtcIsacfix_kRcLevPtr[k] + index[k]); 1510b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1511b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1512b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1513b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy coding of quantization indices */ 1514b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = WebRtcIsacfix_EncHistMulti(streamdata, index, WebRtcIsacfix_kRcCdfPtr, AR_ORDER); 1515b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1516b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */ 1517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 1518b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1519b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1520b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1521b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* decode & dequantize squared Gain */ 1522fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsacfix_DecodeGain2(Bitstr_dec *streamdata, int32_t *gainQ10) 1523b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1524b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int err; 1525fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t index; 1526b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1527b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy decoding of quantization index */ 1528b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsacfix_DecHistOneStepMulti( 1529b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &index, 1530b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamdata, 1531b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsacfix_kGainPtr, 1532b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsacfix_kGainInitInd, 1533b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1); 1534b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* error check */ 1535b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err<0) { 1536b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 1537b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1538b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1539b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* find quantization level */ 1540b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *gainQ10 = WebRtcIsacfix_kGain2Lev[index]; 1541b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1542b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1543b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1544b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1545b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1546b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1547b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* quantize & code squared Gain */ 1548fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsacfix_EncodeGain2(int32_t *gainQ10, Bitstr_enc *streamdata) 1549b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1550fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t index; 1551b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int status = 0; 1552b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1553b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* find quantization index */ 1554b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index = WebRtcIsacfix_kGainInitInd[0]; 1555b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (*gainQ10 > WebRtcIsacfix_kGain2Bound[index]) 1556b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1557b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while (*gainQ10 > WebRtcIsacfix_kGain2Bound[index + 1]) 1558b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index++; 1559b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1560b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 1561b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1562b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while (*gainQ10 < WebRtcIsacfix_kGain2Bound[--index]) ; 1563b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1564b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1565b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* dequantize */ 1566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *gainQ10 = WebRtcIsacfix_kGain2Lev[index]; 1567b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1568b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy coding of quantization index */ 1569b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = WebRtcIsacfix_EncHistMulti(streamdata, &index, WebRtcIsacfix_kGainPtr, 1); 1570b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1571b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */ 1572b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 1573b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1574b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1575b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1576b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* code and decode Pitch Gains and Lags functions */ 1577b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1578b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* decode & dequantize Pitch Gains */ 1579fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsacfix_DecodePitchGain(Bitstr_dec *streamdata, int16_t *PitchGains_Q12) 1580b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1581b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int err; 1582fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t index_comb; 1583fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const uint16_t *pitch_gain_cdf_ptr[1]; 1584b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1585b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy decoding of quantization indices */ 1586b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *pitch_gain_cdf_ptr = WebRtcIsacfix_kPitchGainCdf; 1587b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsacfix_DecHistBisectMulti(&index_comb, streamdata, pitch_gain_cdf_ptr, WebRtcIsacfix_kCdfTableSizeGain, 1); 1588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* error check, Q_mean_Gain.. tables are of size 144 */ 1589b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((err < 0) || (index_comb < 0) || (index_comb >= 144)) 1590b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_PITCH_GAIN; 1591b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1592b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* unquantize back to pitch gains by table look-up */ 1593b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains_Q12[0] = WebRtcIsacfix_kPitchGain1[index_comb]; 1594b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains_Q12[1] = WebRtcIsacfix_kPitchGain2[index_comb]; 1595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains_Q12[2] = WebRtcIsacfix_kPitchGain3[index_comb]; 1596b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains_Q12[3] = WebRtcIsacfix_kPitchGain4[index_comb]; 1597b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1598b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1599b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1600b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1601b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1602b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* quantize & code Pitch Gains */ 1603fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsacfix_EncodePitchGain(int16_t *PitchGains_Q12, Bitstr_enc *streamdata, ISAC_SaveEncData_t* encData) 1604b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1605b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k,j; 1606fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t SQ15[PITCH_SUBFRAMES]; 1607fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t index[3]; 1608fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t index_comb; 1609fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const uint16_t *pitch_gain_cdf_ptr[1]; 1610fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t CQ17; 1611b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int status = 0; 1612b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1613b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1614b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* get the approximate arcsine (almost linear)*/ 1615b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<PITCH_SUBFRAMES; k++) 1616fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org SQ15[k] = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(PitchGains_Q12[k],33,2); //Q15 1617b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1618b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1619b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* find quantization index; only for the first three transform coefficients */ 1620b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<3; k++) 1621b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1622b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* transform */ 1623b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CQ17=0; 1624b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j=0; j<PITCH_SUBFRAMES; j++) { 1625b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CQ17 += WEBRTC_SPL_MUL_16_16_RSFT(WebRtcIsacfix_kTransform[k][j], SQ15[j],10); // Q17 1626b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1627b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1628fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org index[k] = (int16_t)((CQ17 + 8192)>>14); // Rounding and scaling with stepsize (=1/0.125=8) 1629b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1630b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* check that the index is not outside the boundaries of the table */ 1631b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (index[k] < WebRtcIsacfix_kLowerlimiGain[k]) index[k] = WebRtcIsacfix_kLowerlimiGain[k]; 1632b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else if (index[k] > WebRtcIsacfix_kUpperlimitGain[k]) index[k] = WebRtcIsacfix_kUpperlimitGain[k]; 1633b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index[k] -= WebRtcIsacfix_kLowerlimiGain[k]; 1634b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1635b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1636b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* calculate unique overall index */ 1637fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org index_comb = (int16_t)(WEBRTC_SPL_MUL(WebRtcIsacfix_kMultsGain[0], index[0]) + 1638b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_SPL_MUL(WebRtcIsacfix_kMultsGain[1], index[1]) + index[2]); 1639b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1640b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* unquantize back to pitch gains by table look-up */ 1641b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // (Y) 1642b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains_Q12[0] = WebRtcIsacfix_kPitchGain1[index_comb]; 1643b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains_Q12[1] = WebRtcIsacfix_kPitchGain2[index_comb]; 1644b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains_Q12[2] = WebRtcIsacfix_kPitchGain3[index_comb]; 1645b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains_Q12[3] = WebRtcIsacfix_kPitchGain4[index_comb]; 1646b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1647b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1648b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy coding of quantization pitch gains */ 1649b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *pitch_gain_cdf_ptr = WebRtcIsacfix_kPitchGainCdf; 1650b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = WebRtcIsacfix_EncHistMulti(streamdata, &index_comb, pitch_gain_cdf_ptr, 1); 1651b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (status < 0) { 1652b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 1653b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1654b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1655b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save data for creation of multiple bitstreams */ 1656b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (encData != NULL) { 1657b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org encData->pitchGain_index[encData->startIdx] = index_comb; 1658b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1659b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1660b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1661b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1662b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1663b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1664b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1665b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Pitch LAG */ 1666b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1667b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1668b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* decode & dequantize Pitch Lags */ 1669b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint WebRtcIsacfix_DecodePitchLag(Bitstr_dec *streamdata, 1670fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *PitchGain_Q12, 1671fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *PitchLags_Q7) 1672b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1673b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k, err; 1674fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t index[PITCH_SUBFRAMES]; 1675fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int16_t *mean_val2Q10, *mean_val4Q10; 1676b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1677fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int16_t *lower_limit; 1678fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const uint16_t *init_index; 1679fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const uint16_t *cdf_size; 1680fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const uint16_t **cdf; 1681b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1682fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t meangainQ12; 1683fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t CQ11, CQ10,tmp32a,tmp32b; 1684fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t shft,tmp16a,tmp16c; 1685b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1686b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org meangainQ12=0; 1687b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < 4; k++) 1688b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org meangainQ12 += PitchGain_Q12[k]; 1689b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1690b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org meangainQ12 = WEBRTC_SPL_RSHIFT_W32(meangainQ12, 2); // Get average 1691b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1692b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* voicing classificiation */ 1693b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (meangainQ12 <= 819) { // mean_gain < 0.2 1694b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shft = -1; // StepSize=2.0; 1695b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf = WebRtcIsacfix_kPitchLagPtrLo; 1696b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf_size = WebRtcIsacfix_kPitchLagSizeLo; 1697b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val2Q10 = WebRtcIsacfix_kMeanLag2Lo; 1698b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val4Q10 = WebRtcIsacfix_kMeanLag4Lo; 1699b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lower_limit = WebRtcIsacfix_kLowerLimitLo; 1700b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org init_index = WebRtcIsacfix_kInitIndLo; 1701b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (meangainQ12 <= 1638) { // mean_gain < 0.4 1702b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shft = 0; // StepSize=1.0; 1703b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf = WebRtcIsacfix_kPitchLagPtrMid; 1704b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf_size = WebRtcIsacfix_kPitchLagSizeMid; 1705b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val2Q10 = WebRtcIsacfix_kMeanLag2Mid; 1706b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val4Q10 = WebRtcIsacfix_kMeanLag4Mid; 1707b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lower_limit = WebRtcIsacfix_kLowerLimitMid; 1708b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org init_index = WebRtcIsacfix_kInitIndMid; 1709b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1710b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shft = 1; // StepSize=0.5; 1711b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf = WebRtcIsacfix_kPitchLagPtrHi; 1712b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf_size = WebRtcIsacfix_kPitchLagSizeHi; 1713b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val2Q10 = WebRtcIsacfix_kMeanLag2Hi; 1714b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val4Q10 = WebRtcIsacfix_kMeanLag4Hi; 1715b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lower_limit = WebRtcIsacfix_kLowerLimitHi; 1716b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org init_index = WebRtcIsacfix_kInitIndHi; 1717b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1718b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1719b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy decoding of quantization indices */ 1720b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsacfix_DecHistBisectMulti(index, streamdata, cdf, cdf_size, 1); 1721b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((err<0) || (index[0]<0)) // error check 1722b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG; 1723b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1724b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsacfix_DecHistOneStepMulti(index+1, streamdata, cdf+1, init_index, 3); 1725b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err<0) // error check 1726b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG; 1727b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1728b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1729b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* unquantize back to transform coefficients and do the inverse transform: S = T'*C */ 1730fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org CQ11 = ((int32_t)index[0] + lower_limit[0]); // Q0 1731b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CQ11 = WEBRTC_SPL_SHIFT_W32(CQ11,11-shft); // Scale with StepSize, Q11 1732b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<PITCH_SUBFRAMES; k++) { 1733b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp32a = WEBRTC_SPL_MUL_16_32_RSFT11(WebRtcIsacfix_kTransform[0][k], CQ11); 1734fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp16a = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32a, 5); 1735b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchLags_Q7[k] = tmp16a; 1736b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1737b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1738b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CQ10 = mean_val2Q10[index[1]]; 1739b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<PITCH_SUBFRAMES; k++) { 1740fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp32b = (int32_t) WEBRTC_SPL_MUL_16_16_RSFT((int16_t) WebRtcIsacfix_kTransform[1][k], (int16_t) CQ10,10); 1741fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp16c = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); 1742b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchLags_Q7[k] += tmp16c; 1743b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1744b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1745b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CQ10 = mean_val4Q10[index[3]]; 1746b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<PITCH_SUBFRAMES; k++) { 1747fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp32b = (int32_t) WEBRTC_SPL_MUL_16_16_RSFT((int16_t) WebRtcIsacfix_kTransform[3][k], (int16_t) CQ10,10); 1748fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp16c = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); 1749b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchLags_Q7[k] += tmp16c; 1750b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1751b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1752b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1753b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1754b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1755b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1756b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1757b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* quantize & code Pitch Lags */ 1758fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsacfix_EncodePitchLag(int16_t *PitchLagsQ7,int16_t *PitchGain_Q12, 1759b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Bitstr_enc *streamdata, ISAC_SaveEncData_t* encData) 1760b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1761b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k, j; 1762fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t index[PITCH_SUBFRAMES]; 1763fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t meangainQ12, CQ17; 1764fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t CQ11, CQ10,tmp32a; 1765fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org 1766fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int16_t *mean_val2Q10,*mean_val4Q10; 1767fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int16_t *lower_limit, *upper_limit; 1768fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const uint16_t **cdf; 1769fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t shft, tmp16a, tmp16b, tmp16c; 1770fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t tmp32b; 1771b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int status = 0; 1772b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1773b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* compute mean pitch gain */ 1774b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org meangainQ12=0; 1775b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < 4; k++) 1776b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org meangainQ12 += PitchGain_Q12[k]; 1777b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1778b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org meangainQ12 = WEBRTC_SPL_RSHIFT_W32(meangainQ12, 2); 1779b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1780b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save data for creation of multiple bitstreams */ 1781b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (encData != NULL) { 1782b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org encData->meanGain[encData->startIdx] = meangainQ12; 1783b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1784b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1785b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* voicing classificiation */ 1786b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (meangainQ12 <= 819) { // mean_gain < 0.2 1787b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shft = -1; // StepSize=2.0; 1788b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf = WebRtcIsacfix_kPitchLagPtrLo; 1789b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val2Q10 = WebRtcIsacfix_kMeanLag2Lo; 1790b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val4Q10 = WebRtcIsacfix_kMeanLag4Lo; 1791b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lower_limit = WebRtcIsacfix_kLowerLimitLo; 1792b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org upper_limit = WebRtcIsacfix_kUpperLimitLo; 1793b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (meangainQ12 <= 1638) { // mean_gain < 0.4 1794b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shft = 0; // StepSize=1.0; 1795b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf = WebRtcIsacfix_kPitchLagPtrMid; 1796b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val2Q10 = WebRtcIsacfix_kMeanLag2Mid; 1797b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val4Q10 = WebRtcIsacfix_kMeanLag4Mid; 1798b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lower_limit = WebRtcIsacfix_kLowerLimitMid; 1799b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org upper_limit = WebRtcIsacfix_kUpperLimitMid; 1800b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1801b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shft = 1; // StepSize=0.5; 1802b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf = WebRtcIsacfix_kPitchLagPtrHi; 1803b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val2Q10 = WebRtcIsacfix_kMeanLag2Hi; 1804b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val4Q10 = WebRtcIsacfix_kMeanLag4Hi; 1805b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lower_limit = WebRtcIsacfix_kLowerLimitHi; 1806b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org upper_limit = WebRtcIsacfix_kUpperLimitHi; 1807b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1808b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1809b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* find quantization index */ 1810b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<4; k++) 1811b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1812b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* transform */ 1813b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CQ17=0; 1814b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j=0; j<PITCH_SUBFRAMES; j++) 1815b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CQ17 += WEBRTC_SPL_MUL_16_16_RSFT(WebRtcIsacfix_kTransform[k][j], PitchLagsQ7[j],2); // Q17 1816b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1817b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CQ17 = WEBRTC_SPL_SHIFT_W32(CQ17,shft); // Scale with StepSize 1818b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1819b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* quantize */ 1820fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp16b = (int16_t) WEBRTC_SPL_RSHIFT_W32(CQ17 + 65536, 17 ); 1821b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index[k] = tmp16b; 1822b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1823b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* check that the index is not outside the boundaries of the table */ 1824b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (index[k] < lower_limit[k]) index[k] = lower_limit[k]; 1825b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else if (index[k] > upper_limit[k]) index[k] = upper_limit[k]; 1826b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index[k] -= lower_limit[k]; 1827b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1828b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save data for creation of multiple bitstreams */ 1829b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if(encData != NULL) { 1830b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org encData->pitchIndex[PITCH_SUBFRAMES*encData->startIdx + k] = index[k]; 1831b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1832b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1833b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1834b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* unquantize back to transform coefficients and do the inverse transform: S = T'*C */ 1835b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CQ11 = (index[0] + lower_limit[0]); // Q0 1836b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CQ11 = WEBRTC_SPL_SHIFT_W32(CQ11,11-shft); // Scale with StepSize, Q11 1837b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1838b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<PITCH_SUBFRAMES; k++) { 1839b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp32a = WEBRTC_SPL_MUL_16_32_RSFT11(WebRtcIsacfix_kTransform[0][k], CQ11); // Q12 1840fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp16a = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32a, 5);// Q7 1841b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchLagsQ7[k] = tmp16a; 1842b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1843b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1844b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CQ10 = mean_val2Q10[index[1]]; 1845b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<PITCH_SUBFRAMES; k++) { 1846fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp32b = (int32_t) WEBRTC_SPL_MUL_16_16_RSFT((int16_t) WebRtcIsacfix_kTransform[1][k], (int16_t) CQ10,10); 1847fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp16c = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q7 1848b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchLagsQ7[k] += tmp16c; 1849b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1850b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1851b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CQ10 = mean_val4Q10[index[3]]; 1852b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<PITCH_SUBFRAMES; k++) { 1853fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp32b = (int32_t) WEBRTC_SPL_MUL_16_16_RSFT((int16_t) WebRtcIsacfix_kTransform[3][k], (int16_t) CQ10,10); 1854fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp16c = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q7 1855b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchLagsQ7[k] += tmp16c; 1856b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1857b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1858b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy coding of quantization pitch lags */ 1859b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = WebRtcIsacfix_EncHistMulti(streamdata, index, cdf, PITCH_SUBFRAMES); 1860b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1861b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */ 1862b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 1863b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1864b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1865b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1866b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1867b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Routines for inband signaling of bandwitdh estimation */ 1868b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Histograms based on uniform distribution of indices */ 1869b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Move global variables later! */ 1870b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1871b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1872b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* cdf array for frame length indicator */ 1873fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgconst uint16_t kFrameLenCdf[4] = { 1874b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 0, 21845, 43690, 65535}; 1875b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1876b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* pointer to cdf array for frame length indicator */ 1877fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgconst uint16_t *kFrameLenCdfPtr[1] = {kFrameLenCdf}; 1878b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1879b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* initial cdf index for decoder of frame length indicator */ 1880fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgconst uint16_t kFrameLenInitIndex[1] = {1}; 1881b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1882b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1883b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint WebRtcIsacfix_DecodeFrameLen(Bitstr_dec *streamdata, 1884fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *framesamples) 1885b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1886b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1887b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int err; 1888fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t frame_mode; 1889b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1890b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = 0; 1891b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy decoding of frame length [1:30ms,2:60ms] */ 1892b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsacfix_DecHistOneStepMulti(&frame_mode, streamdata, kFrameLenCdfPtr, kFrameLenInitIndex, 1); 1893b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err<0) // error check 1894b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH; 1895b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1896b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch(frame_mode) { 1897b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case 1: 1898b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *framesamples = 480; /* 30ms */ 1899b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 1900b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case 2: 1901b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *framesamples = 960; /* 60ms */ 1902b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 1903b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org default: 1904b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = -ISAC_DISALLOWED_FRAME_MODE_DECODER; 1905b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1906b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1907b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 1908b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1909b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1910b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1911fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsacfix_EncodeFrameLen(int16_t framesamples, Bitstr_enc *streamdata) { 1912b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1913b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int status; 1914fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t frame_mode; 1915b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1916b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = 0; 1917b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame_mode = 0; 1918b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy coding of frame length [1:480 samples,2:960 samples] */ 1919b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch(framesamples) { 1920b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case 480: 1921b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame_mode = 1; 1922b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 1923b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case 960: 1924b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame_mode = 2; 1925b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 1926b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org default: 1927b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = - ISAC_DISALLOWED_FRAME_MODE_ENCODER; 1928b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1929b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1930b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (status < 0) 1931b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 1932b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1933b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = WebRtcIsacfix_EncHistMulti(streamdata, &frame_mode, kFrameLenCdfPtr, 1); 1934b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1935b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 1936b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1937b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1938b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* cdf array for estimated bandwidth */ 1939fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgconst uint16_t kBwCdf[25] = { 1940b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 0, 2731, 5461, 8192, 10923, 13653, 16384, 19114, 21845, 24576, 27306, 30037, 1941b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 32768, 35498, 38229, 40959, 43690, 46421, 49151, 51882, 54613, 57343, 60074, 1942b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 62804, 65535}; 1943b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1944b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* pointer to cdf array for estimated bandwidth */ 1945fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgconst uint16_t *kBwCdfPtr[1] = {kBwCdf}; 1946b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1947b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* initial cdf index for decoder of estimated bandwidth*/ 1948fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgconst uint16_t kBwInitIndex[1] = {7}; 1949b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1950b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1951fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsacfix_DecodeSendBandwidth(Bitstr_dec *streamdata, int16_t *BWno) { 1952b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1953b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int err; 1954fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t BWno32; 1955b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1956b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy decoding of sender's BW estimation [0..23] */ 1957b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsacfix_DecHistOneStepMulti(&BWno32, streamdata, kBwCdfPtr, kBwInitIndex, 1); 1958b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err<0) // error check 1959b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_BANDWIDTH; 1960fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org *BWno = (int16_t)BWno32; 1961b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 1962b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1963b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1964b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1965b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1966fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsacfix_EncodeReceiveBandwidth(int16_t *BWno, Bitstr_enc *streamdata) 1967b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1968b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int status = 0; 1969b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy encoding of receiver's BW estimation [0..23] */ 1970b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = WebRtcIsacfix_EncHistMulti(streamdata, BWno, kBwCdfPtr, 1); 1971b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1972b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 1973b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1974b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1975b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* estimate codel length of LPC Coef */ 1976fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgvoid WebRtcIsacfix_TranscodeLpcCoef(int32_t *gain_lo_hiQ17, 1977fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *index_gQQ) { 19786b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org int j, k; 1979fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t posQQ, pos2QQ; 1980fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t posg, offsg, gainpos; 1981fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t tmpcoeffs_gQ6[KLT_ORDER_GAIN]; 1982fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t tmpcoeffs_gQ17[KLT_ORDER_GAIN]; 1983fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t tmpcoeffs2_gQ21[KLT_ORDER_GAIN]; 1984fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t sumQQ; 1985b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1986b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1987b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* log gains, mean removal and scaling */ 19886b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org posg = 0; gainpos=0; 1989b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1990b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<SUBFRAMES; k++) { 1991b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* log gains */ 1992b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1993b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* The input argument X to logN(X) is 2^17 times higher than the 1994b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org input floating point argument Y to log(Y), since the X value 1995b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org is a Q17 value. This can be compensated for after the call, by 1996b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org subraction a value Z for each Q-step. One Q-step means that 1997b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org X gets 2 times higher, i.e. Z = logN(2)*256 = 0.693147180559*256 = 1998b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 177.445678 should be subtracted (since logN() returns a Q8 value). 1999b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org For a X value in Q17, the value 177.445678*17 = 3017 should be 2000b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org subtracted */ 2001b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 2002b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 2003b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg++; gainpos++; 2004b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2005b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 2006b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 2007b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg++; gainpos++; 2008b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2009b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2010b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2011b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2012b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* KLT */ 2013b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2014b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* left transform */ 2015715275c813e0169cd103f3ef15a69b8134dfa3f7kma@webrtc.org for (j = 0, offsg = 0; j < SUBFRAMES; j++, offsg += 2) { 2016d451969b3aa5714f092ce4b86c5b380e8218c89dkma@webrtc.org // Q21 = Q6 * Q15 2017d451969b3aa5714f092ce4b86c5b380e8218c89dkma@webrtc.org sumQQ = WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg], 2018d451969b3aa5714f092ce4b86c5b380e8218c89dkma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][0]); 2019d451969b3aa5714f092ce4b86c5b380e8218c89dkma@webrtc.org sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg + 1], 2020d451969b3aa5714f092ce4b86c5b380e8218c89dkma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][2]); 2021d451969b3aa5714f092ce4b86c5b380e8218c89dkma@webrtc.org tmpcoeffs2_gQ21[offsg] = sumQQ; 2022b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2023d451969b3aa5714f092ce4b86c5b380e8218c89dkma@webrtc.org // Q21 = Q6 * Q15 2024d451969b3aa5714f092ce4b86c5b380e8218c89dkma@webrtc.org sumQQ = WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg], 2025d451969b3aa5714f092ce4b86c5b380e8218c89dkma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][1]); 2026d451969b3aa5714f092ce4b86c5b380e8218c89dkma@webrtc.org sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg + 1], 2027d451969b3aa5714f092ce4b86c5b380e8218c89dkma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][3]); 2028d451969b3aa5714f092ce4b86c5b380e8218c89dkma@webrtc.org tmpcoeffs2_gQ21[offsg + 1] = sumQQ; 2029b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2030b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2031b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* right transform */ 20326b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21, 20336b12f9704ef671d4ec2ab14c531c967373c8b137kma@webrtc.org tmpcoeffs_gQ17, kTIndexFactor3, kTIndexStep1); 2034b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2035b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* quantize coefficients */ 2036b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok? 2037b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 2038b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posQQ = WebRtcIsacfix_kSelIndGain[k]; 2039fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org pos2QQ= (int16_t)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17); 2040b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2041b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok? 2042b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (index_gQQ[k] < 0) { 2043b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_gQQ[k] = 0; 2044b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2045b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) { 2046b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k]; 2047b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2048b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2049b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 2050