1470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 2470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 4470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Use of this source code is governed by a BSD-style license 5470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * that can be found in the LICENSE file in the root of the source 6470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * tree. An additional intellectual property rights grant can be found 7470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * in the file PATENTS. All contributing project authors may 8470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * be found in the AUTHORS file in the root of the source tree. 9470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 10470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 11470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 12470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * entropy_coding.c 13470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 14470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This file contains all functions used to arithmetically 15470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * encode the iSAC bistream. 16470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 17470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 18470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 19470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include <stddef.h> 20470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 21470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "arith_routins.h" 22470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "spectrum_ar_model_tables.h" 23470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "pitch_gain_tables.h" 24470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "pitch_lag_tables.h" 25470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "entropy_coding.h" 26470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "lpc_tables.h" 27470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "settings.h" 28470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "signal_processing_library.h" 29470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org/* 3123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org * Eenumerations for arguments to functions WebRtcIsacfix_MatrixProduct1() 3223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org * and WebRtcIsacfix_MatrixProduct2(). 3323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org*/ 3423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 3523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgenum matrix_index_factor { 3623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTIndexFactor1 = 1, 3723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTIndexFactor2 = 2, 3823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTIndexFactor3 = SUBFRAMES, 3923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTIndexFactor4 = LPC_SHAPE_ORDER 4023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org}; 4123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 4223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgenum matrix_index_step { 4323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTIndexStep1 = 1, 4423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTIndexStep2 = SUBFRAMES, 4523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTIndexStep3 = LPC_SHAPE_ORDER 4623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org}; 4723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 4823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgenum matrixprod_loop_count { 4923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTLoopCount1 = SUBFRAMES, 5023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTLoopCount2 = 2, 5123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTLoopCount3 = LPC_SHAPE_ORDER 5223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org}; 5323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 5423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgenum matrix1_shift_value { 5523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTMatrix1_shift0 = 0, 5623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTMatrix1_shift1 = 1, 5723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTMatrix1_shift5 = 5 5823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org}; 5923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 6023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgenum matrixprod_init_case { 6123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTInitCase0 = 0, 6223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTInitCase1 = 1 6323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org}; 64470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 65470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 66470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com This function implements the fix-point correspondant function to lrint. 67470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 680946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org FLP: (int32_t)floor(flt+.499999999999) 69470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FIP: (fixVal+roundVal)>>qDomain 70470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 71470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com where roundVal = 2^(qDomain-1) = 1<<(qDomain-1) 72470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 73470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com*/ 740946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic __inline int32_t CalcLrIntQ(int32_t fixVal, int16_t qDomain) { 75a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org return (fixVal + (1 << (qDomain - 1))) >> qDomain; 76470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 77470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 78470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 790946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org __inline uint32_t stepwise(int32_t dinQ10) { 80470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 810946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t ind, diQ10, dtQ10; 82470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 83470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com diQ10 = dinQ10; 84470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (diQ10 < DPMIN_Q10) 85470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com diQ10 = DPMIN_Q10; 86470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (diQ10 >= DPMAX_Q10) 87470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com diQ10 = DPMAX_Q10 - 1; 88470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 89470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com dtQ10 = diQ10 - DPMIN_Q10;*/ /* Q10 + Q10 = Q10 */ 90470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* ind = (dtQ10 * 5) >> 10; */ /* 2^10 / 5 = 0.2 in Q10 */ 91470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* Q10 -> Q0 */ 92470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 93470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* return rpointsFIX_Q10[ind]; 94470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 95470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 96470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com*/ 97470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 98470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* logN(x) = logN(2)*log2(x) = 0.6931*log2(x). Output in Q8. */ 99470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* The input argument X to logN(X) is 2^17 times higher than the 100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com input floating point argument Y to log(Y), since the X value 101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com is a Q17 value. This can be compensated for after the call, by 102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subraction a value Z for each Q-step. One Q-step means that 103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com X gets 2 thimes higher, i.e. Z = logN(2)*256 = 0.693147180559*256 = 104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 177.445678 should be subtracted (since logN() returns a Q8 value). 105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com For a X value in Q17, the value 177.445678*17 = 3017 should be 106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subtracted */ 1070946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic int16_t CalcLogN(int32_t arg) { 1080946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t zeros, log2, frac, logN; 109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com zeros=WebRtcSpl_NormU32(arg); 111d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker frac = (int16_t)((uint32_t)((arg << zeros) & 0x7FFFFFFF) >> 23); 112d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker log2 = (int16_t)(((31 - zeros) << 8) + frac); // log2(x) in Q8 113f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker logN = (int16_t)(log2 * 22713 >> 15); // log(2) = 0.693147 = 22713 in Q15 114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com logN=logN+11; //Scalar compensation which minimizes the (log(x)-logN(x))^2 error over all x. 115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return logN; 117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com expN(x) = 2^(a*x), where a = log2(e) ~= 1.442695 122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1230946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org Input: Q8 (int16_t) 1240946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org Output: Q17 (int32_t) 125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com a = log2(e) = log2(exp(1)) ~= 1.442695 ==> a = 23637 in Q14 (1.442688) 127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com To this value, 700 is added or subtracted in order to get an average error 128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nearer zero, instead of always same-sign. 129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com*/ 130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1310946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic int32_t CalcExpN(int16_t x) { 132f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker int16_t axINT, axFRAC; 1330946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t exp16; 1340946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t exp; 135f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker int16_t ax = (int16_t)(x * 23637 >> 14); // Q8 136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (x>=0) { 138f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org axINT = ax >> 8; //Q0 139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com axFRAC = ax&0x00FF; 140d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker exp16 = 1 << axINT; // Q0 141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com axFRAC = axFRAC+256; //Q8 142bc2bb34419021fb3be4f87eb062cf0a9ed52675abjornv@webrtc.org exp = exp16 * axFRAC; // Q0*Q8 = Q8 143d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker exp <<= 9; // Q17 144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ax = -ax; 146f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org axINT = 1 + (ax >> 8); //Q0 147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com axFRAC = 0x00FF - (ax&0x00FF); 148a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org exp16 = (int16_t)(32768 >> axINT); // Q15 149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com axFRAC = axFRAC+256; //Q8 150bc2bb34419021fb3be4f87eb062cf0a9ed52675abjornv@webrtc.org exp = exp16 * axFRAC; // Q15*Q8 = Q23 151a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org exp >>= 6; // Q17 152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return exp; 155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* compute correlation from power spectrum */ 1590946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic void CalcCorrelation(int32_t *PSpecQ12, int32_t *CorrQ7) 160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1610946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t summ[FRAMESAMPLES/8]; 1620946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t diff[FRAMESAMPLES/8]; 1630946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t sum; 164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k, n; 165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < FRAMESAMPLES/8; k++) { 167a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org summ[k] = (PSpecQ12[k] + PSpecQ12[FRAMESAMPLES / 4 - 1 - k] + 16) >> 5; 168a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org diff[k] = (PSpecQ12[k] - PSpecQ12[FRAMESAMPLES / 4 - 1 - k] + 16) >> 5; 169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = 2; 172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum += summ[n]; 174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CorrQ7[0] = sum; 175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < AR_ORDER; k += 2) { 177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = 0; 178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 179a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org sum += (WebRtcIsacfix_kCos[k][n] * diff[n] + 256) >> 9; 180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CorrQ7[k+1] = sum; 181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=1; k<AR_ORDER; k+=2) { 184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = 0; 185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 186a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org sum += (WebRtcIsacfix_kCos[k][n] * summ[n] + 256) >> 9; 187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CorrQ7[k+1] = sum; 188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* compute inverse AR power spectrum */ 1930946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic void CalcInvArSpec(const int16_t *ARCoefQ12, 1940946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const int32_t gainQ10, 1950946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t *CurveQ16) 196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1970946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t CorrQ11[AR_ORDER+1]; 1980946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t sum, tmpGain; 1990946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t diffQ16[FRAMESAMPLES/8]; 2000946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const int16_t *CS_ptrQ9; 201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k, n; 2020946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t round, shftVal = 0, sh; 203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = 0; 205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < AR_ORDER+1; n++) 206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]); /* Q24 */ 207a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org sum = ((sum >> 6) * 65 + 32768) >> 16; /* Result in Q8. */ 208a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org CorrQ11[0] = (sum * gainQ10 + 256) >> 9; 209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* To avoid overflow, we shift down gainQ10 if it is large. We will not lose any precision */ 211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(gainQ10>400000){ 212a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org tmpGain = gainQ10 >> 3; 213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com round = 32; 214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shftVal = 6; 215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpGain = gainQ10; 217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com round = 256; 218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shftVal = 9; 219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 1; k < AR_ORDER+1; k++) { 222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = 16384; 223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = k; n < AR_ORDER+1; n++) 224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum += WEBRTC_SPL_MUL(ARCoefQ12[n-k], ARCoefQ12[n]); /* Q24 */ 225a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org sum >>= 15; 226a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org CorrQ11[k] = (sum * tmpGain + round) >> shftVal; 227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 228d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker sum = CorrQ11[0] << 7; 229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CurveQ16[n] = sum; 231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 1; k < AR_ORDER; k += 2) { 233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 234a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org CurveQ16[n] += (WebRtcIsacfix_kCos[k][n] * CorrQ11[k + 1] + 2) >> 2; 235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CS_ptrQ9 = WebRtcIsacfix_kCos[0]; 238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* If CorrQ11[1] too large we avoid getting overflow in the calculation by shifting */ 240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sh=WebRtcSpl_NormW32(CorrQ11[1]); 241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (CorrQ11[1]==0) /* Use next correlation */ 242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sh=WebRtcSpl_NormW32(CorrQ11[2]); 243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (sh<9) 245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shftVal = 9 - sh; 246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shftVal = 0; 248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 250a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org diffQ16[n] = (CS_ptrQ9[n] * (CorrQ11[1] >> shftVal) + 2) >> 2; 251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 2; k < AR_ORDER; k += 2) { 252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CS_ptrQ9 = WebRtcIsacfix_kCos[k]; 253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 254a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org diffQ16[n] += (CS_ptrQ9[n] * (CorrQ11[k + 1] >> shftVal) + 2) >> 2; 255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<FRAMESAMPLES/8; k++) { 258d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker int32_t diff_q16 = diffQ16[k] << shftVal; 259d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker CurveQ16[FRAMESAMPLES / 4 - 1 - k] = CurveQ16[k] - diff_q16; 260d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker CurveQ16[k] += diff_q16; 261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2640946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic void CalcRootInvArSpec(const int16_t *ARCoefQ12, 2650946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const int32_t gainQ10, 2660946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint16_t *CurveQ8) 267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2680946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t CorrQ11[AR_ORDER+1]; 2690946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t sum, tmpGain; 2700946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t summQ16[FRAMESAMPLES/8]; 2710946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t diffQ16[FRAMESAMPLES/8]; 272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2730946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const int16_t *CS_ptrQ9; 274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k, n, i; 2750946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t round, shftVal = 0, sh; 2760946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t res, in_sqrt, newRes; 277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = 0; 279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < AR_ORDER+1; n++) 280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]); /* Q24 */ 281a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org sum = ((sum >> 6) * 65 + 32768) >> 16; /* Result in Q8. */ 282a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org CorrQ11[0] = (sum * gainQ10 + 256) >> 9; 283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* To avoid overflow, we shift down gainQ10 if it is large. We will not lose any precision */ 285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(gainQ10>400000){ 286a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org tmpGain = gainQ10 >> 3; 287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com round = 32; 288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shftVal = 6; 289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpGain = gainQ10; 291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com round = 256; 292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shftVal = 9; 293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 1; k < AR_ORDER+1; k++) { 296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = 16384; 297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = k; n < AR_ORDER+1; n++) 298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum += WEBRTC_SPL_MUL(ARCoefQ12[n-k], ARCoefQ12[n]); /* Q24 */ 299a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org sum >>= 15; 300a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org CorrQ11[k] = (sum * tmpGain + round) >> shftVal; 301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 302d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker sum = CorrQ11[0] << 7; 303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com summQ16[n] = sum; 305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 1; k < (AR_ORDER); k += 2) { 307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 308926707b167e9bfb876c7c903dcefc41c84e5fedbbjornv@webrtc.org summQ16[n] += ((CorrQ11[k + 1] * WebRtcIsacfix_kCos[k][n]) + 2) >> 2; 309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CS_ptrQ9 = WebRtcIsacfix_kCos[0]; 312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* If CorrQ11[1] too large we avoid getting overflow in the calculation by shifting */ 314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sh=WebRtcSpl_NormW32(CorrQ11[1]); 315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (CorrQ11[1]==0) /* Use next correlation */ 316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sh=WebRtcSpl_NormW32(CorrQ11[2]); 317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (sh<9) 319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shftVal = 9 - sh; 320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shftVal = 0; 322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 324a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org diffQ16[n] = (CS_ptrQ9[n] * (CorrQ11[1] >> shftVal) + 2) >> 2; 325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 2; k < AR_ORDER; k += 2) { 326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CS_ptrQ9 = WebRtcIsacfix_kCos[k]; 327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 328a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org diffQ16[n] += (CS_ptrQ9[n] * (CorrQ11[k + 1] >> shftVal) + 2) >> 2; 329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 331d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker in_sqrt = summQ16[0] + (diffQ16[0] << shftVal); 332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* convert to magnitude spectrum, by doing square-roots (modified from SPLIB) */ 334f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org res = 1 << (WebRtcSpl_GetSizeInBits(in_sqrt) >> 1); 335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < FRAMESAMPLES/8; k++) 337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 338d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker in_sqrt = summQ16[k] + (diffQ16[k] << shftVal); 339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com i = 10; 340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* make in_sqrt positive to prohibit sqrt of negative values */ 342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(in_sqrt<0) 343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com in_sqrt=-in_sqrt; 344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 345df9fef6638b4b5ef7a6c9a3eb2b20e26aefc9746bjornv@webrtc.org newRes = (in_sqrt / res + res) >> 1; 346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com do 347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com res = newRes; 349df9fef6638b4b5ef7a6c9a3eb2b20e26aefc9746bjornv@webrtc.org newRes = (in_sqrt / res + res) >> 1; 350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } while (newRes != res && i-- > 0); 351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3520946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org CurveQ8[k] = (int16_t)newRes; 353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = FRAMESAMPLES/8; k < FRAMESAMPLES/4; k++) { 355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 356d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker in_sqrt = summQ16[FRAMESAMPLES / 4 - 1 - k] - 357d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker (diffQ16[FRAMESAMPLES / 4 - 1 - k] << shftVal); 358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com i = 10; 359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* make in_sqrt positive to prohibit sqrt of negative values */ 361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(in_sqrt<0) 362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com in_sqrt=-in_sqrt; 363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 364df9fef6638b4b5ef7a6c9a3eb2b20e26aefc9746bjornv@webrtc.org newRes = (in_sqrt / res + res) >> 1; 365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com do 366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com res = newRes; 368df9fef6638b4b5ef7a6c9a3eb2b20e26aefc9746bjornv@webrtc.org newRes = (in_sqrt / res + res) >> 1; 369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } while (newRes != res && i-- > 0); 370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3710946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org CurveQ8[k] = (int16_t)newRes; 372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* generate array of dither samples in Q7 */ 3790946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic void GenerateDitherQ7(int16_t *bufQ7, 3800946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint32_t seed, 3810946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t length, 3820946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t AvgPitchGain_Q12) 383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k; 3850946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t dither1_Q7, dither2_Q7, dither_gain_Q14, shft; 386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (AvgPitchGain_Q12 < 614) /* this threshold should be equal to that in decode_spec() */ 388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < length-2; k += 3) 390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3910946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org /* new random unsigned int32_t */ 392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515; 393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* fixed-point dither sample between -64 and 64 (Q7) */ 395a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org dither1_Q7 = (int16_t)(((int32_t)seed + 16777216) >> 25); 396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3970946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org /* new random unsigned int32_t */ 398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515; 399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* fixed-point dither sample between -64 and 64 */ 401a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org dither2_Q7 = (int16_t)((seed + 16777216) >> 25); 402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4030946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org shft = (int16_t)(WEBRTC_SPL_RSHIFT_U32(seed, 25) & 15); 404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (shft < 5) 405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k] = dither1_Q7; 407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k+1] = dither2_Q7; 408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k+2] = 0; 409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (shft < 10) 411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k] = dither1_Q7; 413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k+1] = 0; 414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k+2] = dither2_Q7; 415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k] = 0; 419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k+1] = dither1_Q7; 420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k+2] = dither2_Q7; 421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4260946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org dither_gain_Q14 = (int16_t)(22528 - WEBRTC_SPL_MUL(10, AvgPitchGain_Q12)); 427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* dither on half of the coefficients */ 429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < length-1; k += 2) 430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4310946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org /* new random unsigned int32_t */ 432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515; 433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* fixed-point dither sample between -64 and 64 */ 435a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org dither1_Q7 = (int16_t)(((int32_t)seed + 16777216) >> 25); 436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* dither sample is placed in either even or odd index */ 4380946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org shft = (int16_t)(WEBRTC_SPL_RSHIFT_U32(seed, 25) & 1); /* either 0 or 1 */ 439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 440a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org bufQ7[k + shft] = (int16_t)((dither_gain_Q14 * dither1_Q7 + 8192) >> 14); 441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k + 1 - shft] = 0; 442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * function to decode the complex spectrum from the bitstream 451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * returns the total number of bytes in the stream 452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 453aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kastingint WebRtcIsacfix_DecodeSpec(Bitstr_dec *streamdata, 454aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting int16_t *frQ7, 455aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting int16_t *fiQ7, 456aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting int16_t AvgPitchGain_Q12) 457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4580946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t data[FRAMESAMPLES]; 4590946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t invARSpec2_Q16[FRAMESAMPLES/4]; 4600946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t ARCoefQ12[AR_ORDER+1]; 4610946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t RCQ15[AR_ORDER]; 4620946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t gainQ10; 4630946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t gain2_Q10; 464aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting int len; 465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k; 466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* create dither signal */ 468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com GenerateDitherQ7(data, streamdata->W_upper, FRAMESAMPLES, AvgPitchGain_Q12); /* Dither is output in vector 'Data' */ 469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* decode model parameters */ 471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (WebRtcIsacfix_DecodeRcCoef(streamdata, RCQ15) < 0) 472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; 473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); 476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (WebRtcIsacfix_DecodeGain2(streamdata, &gain2_Q10) < 0) 478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; 479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* compute inverse AR power spectrum */ 481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CalcInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); 482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* arithmetic decoding of spectrum */ 484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* 'data' input and output. Input = Dither */ 4850946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org len = WebRtcIsacfix_DecLogisticMulti2(data, streamdata, invARSpec2_Q16, (int16_t)FRAMESAMPLES); 486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (len<1) 488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; 489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* subtract dither and scale down spectral samples with low SNR */ 491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (AvgPitchGain_Q12 <= 614) 492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < FRAMESAMPLES; k += 4) 494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 495d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker gainQ10 = WebRtcSpl_DivW32W16ResW16(30 << 10, 496d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker (int16_t)((uint32_t)(invARSpec2_Q16[k >> 2] + 2195456) >> 16)); 497a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org *frQ7++ = (int16_t)((data[k] * gainQ10 + 512) >> 10); 498a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org *fiQ7++ = (int16_t)((data[k + 1] * gainQ10 + 512) >> 10); 499a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org *frQ7++ = (int16_t)((data[k + 2] * gainQ10 + 512) >> 10); 500a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org *fiQ7++ = (int16_t)((data[k + 3] * gainQ10 + 512) >> 10); 501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < FRAMESAMPLES; k += 4) 506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 507d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker gainQ10 = WebRtcSpl_DivW32W16ResW16(36 << 10, 508d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker (int16_t)((uint32_t)(invARSpec2_Q16[k >> 2] + 2654208) >> 16)); 509a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org *frQ7++ = (int16_t)((data[k] * gainQ10 + 512) >> 10); 510a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org *fiQ7++ = (int16_t)((data[k + 1] * gainQ10 + 512) >> 10); 511a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org *frQ7++ = (int16_t)((data[k + 2] * gainQ10 + 512) >> 10); 512a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org *fiQ7++ = (int16_t)((data[k + 3] * gainQ10 + 512) >> 10); 513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return len; 517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5200946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint WebRtcIsacfix_EncodeSpec(const int16_t *fr, 5210946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const int16_t *fi, 522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Bitstr_enc *streamdata, 5230946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t AvgPitchGain_Q12) 524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5250946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t dataQ7[FRAMESAMPLES]; 5260946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t PSpec[FRAMESAMPLES/4]; 5270946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint16_t invARSpecQ8[FRAMESAMPLES/4]; 5280946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t CorrQ7[AR_ORDER+1]; 5290946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t CorrQ7_norm[AR_ORDER+1]; 5300946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t RCQ15[AR_ORDER]; 5310946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t ARCoefQ12[AR_ORDER+1]; 5320946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t gain2_Q10; 5330946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t val; 5340946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t nrg; 5350946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint32_t sum; 5360946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t lft_shft; 5370946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t status; 538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k, n, j; 539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* create dither_float signal */ 542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com GenerateDitherQ7(dataQ7, streamdata->W_upper, FRAMESAMPLES, AvgPitchGain_Q12); 543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* add dither and quantize, and compute power spectrum */ 545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Vector dataQ7 contains Dither in Q7 */ 546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < FRAMESAMPLES; k += 4) 547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com val = ((*fr++ + dataQ7[k] + 64) & 0xFF80) - dataQ7[k]; /* Data = Dither */ 549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com dataQ7[k] = val; /* New value in Data */ 550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = WEBRTC_SPL_UMUL(val, val); 551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com val = ((*fi++ + dataQ7[k+1] + 64) & 0xFF80) - dataQ7[k+1]; /* Data = Dither */ 553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com dataQ7[k+1] = val; /* New value in Data */ 554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum += WEBRTC_SPL_UMUL(val, val); 555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com val = ((*fr++ + dataQ7[k+2] + 64) & 0xFF80) - dataQ7[k+2]; /* Data = Dither */ 557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com dataQ7[k+2] = val; /* New value in Data */ 558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum += WEBRTC_SPL_UMUL(val, val); 559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com val = ((*fi++ + dataQ7[k+3] + 64) & 0xFF80) - dataQ7[k+3]; /* Data = Dither */ 561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com dataQ7[k+3] = val; /* New value in Data */ 562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum += WEBRTC_SPL_UMUL(val, val); 563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PSpec[k>>2] = WEBRTC_SPL_RSHIFT_U32(sum, 2); 565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* compute correlation from power spectrum */ 568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CalcCorrelation(PSpec, CorrQ7); 569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find AR coefficients */ 572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* number of bit shifts to 14-bit normalize CorrQ7[0] (leaving room for sign) */ 573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lft_shft = WebRtcSpl_NormW32(CorrQ7[0]) - 18; 574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (lft_shft > 0) { 576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<AR_ORDER+1; k++) 577d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker CorrQ7_norm[k] = CorrQ7[k] << lft_shft; 578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<AR_ORDER+1; k++) 580a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org CorrQ7_norm[k] = CorrQ7[k] >> -lft_shft; 581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find RC coefficients */ 584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcSpl_AutoCorrToReflCoef(CorrQ7_norm, AR_ORDER, RCQ15); 585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* quantize & code RC Coef */ 587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncodeRcCoef(RCQ15, streamdata); 588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (status < 0) { 589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* RC -> AR coefficients */ 593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); 594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* compute ARCoef' * Corr * ARCoef in Q19 */ 596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nrg = 0; 597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (j = 0; j <= AR_ORDER; j++) { 598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n <= j; n++) 599a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org nrg += (ARCoefQ12[j] * ((CorrQ7_norm[j - n] * ARCoefQ12[n] + 256) >> 9) + 600a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org 4) >> 3; 601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = j+1; n <= AR_ORDER; n++) 602a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org nrg += (ARCoefQ12[j] * ((CorrQ7_norm[n - j] * ARCoefQ12[n] + 256) >> 9) + 603a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org 4) >> 3; 604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (lft_shft > 0) 607a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org nrg >>= lft_shft; 608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 609d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker nrg <<= -lft_shft; 610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(nrg>131072) 612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES >> 2, nrg); /* also shifts 31 bits to the left! */ 613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 614a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org gain2_Q10 = FRAMESAMPLES >> 2; 615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* quantize & code gain2_Q10 */ 617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (WebRtcIsacfix_EncodeGain2(&gain2_Q10, streamdata)) 618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* compute inverse AR magnitude spectrum */ 621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CalcRootInvArSpec(ARCoefQ12, gain2_Q10, invARSpecQ8); 622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* arithmetic coding of spectrum */ 6250946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org status = WebRtcIsacfix_EncLogisticMulti2(streamdata, dataQ7, invARSpecQ8, (int16_t)FRAMESAMPLES); 626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ( status ) 627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return( status ); 628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* Matlab's LAR definition */ 6340946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic void Rc2LarFix(const int16_t *rcQ15, int32_t *larQ17, int16_t order) { 635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* 637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com This is a piece-wise implemenetation of a rc2lar-function (all values in the comment 639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com are Q15 values and are based on [0 24956/32768 30000/32768 32500/32768], i.e. 640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com [0.76159667968750 0.91552734375000 0.99182128906250] 641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com x0 x1 a k x0(again) b 643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ================================================================================== 644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 0.00 0.76: 0 2.625997508581 0 0 645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 0.76 0.91: 2.000012018559 7.284502668663 0.761596679688 -3.547841027073 646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 0.91 0.99: 3.121320351712 31.115835041229 0.915527343750 -25.366077452148 647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 0.99 1.00: 5.495270168700 686.663805654056 0.991821289063 -675.552510708011 648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com The implementation is y(x)= a + (x-x0)*k, but this can be simplified to 650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com y(x) = a-x0*k + x*k = b + x*k, where b = a-x0*k 652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com akx=[0 2.625997508581 0 654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2.000012018559 7.284502668663 0.761596679688 655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3.121320351712 31.115835041229 0.915527343750 656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5.495270168700 686.663805654056 0.991821289063]; 657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com b = akx(:,1) - akx(:,3).*akx(:,2) 659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com [ 0.0 661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com -3.547841027073 662470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com -25.366077452148 663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com -675.552510708011] 664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k; 6680946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t rc; 6690946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t larAbsQ17; 670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < order; k++) { 672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rc = WEBRTC_SPL_ABS_W16(rcQ15[k]); //Q15 674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Calculate larAbsQ17 in Q17 from rc in Q15 */ 676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (rc<24956) { //0.7615966 in Q15 678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (Q15*Q13)>>11 = Q17 679f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker larAbsQ17 = rc * 21512 >> 11; 680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else if (rc<30000) { //0.91552734375 in Q15 681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Q17 + (Q15*Q12)>>10 = Q17 682f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker larAbsQ17 = -465024 + (rc * 29837 >> 10); 683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else if (rc<32500) { //0.99182128906250 in Q15 684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Q17 + (Q15*Q10)>>8 = Q17 685f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker larAbsQ17 = -3324784 + (rc * 31863 >> 8); 686470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Q17 + (Q15*Q5)>>3 = Q17 688f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker larAbsQ17 = -88546020 + (rc * 21973 >> 3); 689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (rcQ15[k]>0) { 692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com larQ17[k] = larAbsQ17; 693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com larQ17[k] = -larAbsQ17; 695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 7000946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic void Lar2RcFix(const int32_t *larQ17, int16_t *rcQ15, int16_t order) { 701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* 703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com This is a piece-wise implemenetation of a lar2rc-function 704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com See comment in Rc2LarFix() about details. 705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k; 7080946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t larAbsQ11; 7090946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t rc; 710470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < order; k++) { 712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 713a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org larAbsQ11 = (int16_t)WEBRTC_SPL_ABS_W32((larQ17[k] + 32) >> 6); // Q11 714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (larAbsQ11<4097) { //2.000012018559 in Q11 716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Q11*Q16>>12 = Q15 717f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker rc = larAbsQ11 * 24957 >> 12; 718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else if (larAbsQ11<6393) { //3.121320351712 in Q11 719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (Q11*Q17 + Q13)>>13 = Q15 720a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org rc = (larAbsQ11 * 17993 + 130738688) >> 13; 721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else if (larAbsQ11<11255) { //5.495270168700 in Q11 722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (Q11*Q19 + Q30)>>15 = Q15 723a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org rc = (larAbsQ11 * 16850 + 875329820) >> 15; 724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (Q11*Q24>>16 + Q19)>>4 = Q15 726a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org rc = (((larAbsQ11 * 24433) >> 16) + 515804) >> 4; 727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (larQ17[k]<=0) { 730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rc = -rc; 731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 7330946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org rcQ15[k] = (int16_t) rc; // Q15 734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 7370946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic void Poly2LarFix(int16_t *lowbandQ15, 7380946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t orderLo, 7390946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *hibandQ15, 7400946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t orderHi, 7410946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t Nsub, 7420946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t *larsQ17) { 743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k, n; 7450946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t *outpQ17; 7460946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t orderTot; 7470946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t larQ17[MAX_ORDER]; // Size 7+6 is enough 748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com orderTot = (orderLo + orderHi); 750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com outpQ17 = larsQ17; 751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < Nsub; k++) { 752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Rc2LarFix(lowbandQ15, larQ17, orderLo); 754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < orderLo; n++) 756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com outpQ17[n] = larQ17[n]; //Q17 757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Rc2LarFix(hibandQ15, larQ17, orderHi); 759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < orderHi; n++) 761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com outpQ17[n + orderLo] = larQ17[n]; //Q17; 762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com outpQ17 += orderTot; 764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lowbandQ15 += orderLo; 765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com hibandQ15 += orderHi; 766470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 767470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 7700946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic void Lar2polyFix(int32_t *larsQ17, 7710946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *lowbandQ15, 7720946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t orderLo, 7730946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *hibandQ15, 7740946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t orderHi, 7750946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t Nsub) { 776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k, n; 7780946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t orderTot; 7790946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *outplQ15, *outphQ15; 7800946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t *inpQ17; 7810946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t rcQ15[7+6]; 782470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com orderTot = (orderLo + orderHi); 784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com outplQ15 = lowbandQ15; 785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com outphQ15 = hibandQ15; 786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com inpQ17 = larsQ17; 787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < Nsub; k++) { 788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* gains not handled here as in the FLP version */ 790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Low band */ 792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Lar2RcFix(&inpQ17[0], rcQ15, orderLo); 793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < orderLo; n++) 794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com outplQ15[n] = rcQ15[n]; // Refl. coeffs 795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* High band */ 797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Lar2RcFix(&inpQ17[orderLo], rcQ15, orderHi); 798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < orderHi; n++) 799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com outphQ15[n] = rcQ15[n]; // Refl. coeffs 800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com inpQ17 += orderTot; 802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com outplQ15 += orderLo; 803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com outphQ15 += orderHi; 804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 80723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org/* 80823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgFunction WebRtcIsacfix_MatrixProduct1C() does one form of matrix multiplication. 80923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgIt first shifts input data of one matrix, determines the right indexes for the 81023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgtwo matrixes, multiply them, and write the results into an output buffer. 81123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 81223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgNote that two factors (or, multipliers) determine the initialization values of 81323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgthe variable |matrix1_index| in the code. The relationship is 81423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org|matrix1_index| = |matrix1_index_factor1| * |matrix1_index_factor2|, where 81523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org|matrix1_index_factor1| is given by the argument while |matrix1_index_factor2| 81623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgis determined by the value of argument |matrix1_index_init_case|; 81723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org|matrix1_index_factor2| is the value of the outmost loop counter j (when 81823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org|matrix1_index_init_case| is 0), or the value of the middle loop counter k (when 81923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org|matrix1_index_init_case| is non-zero). 82023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 82123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org|matrix0_index| is determined the same way. 82223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 82323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgArguments: 82423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0[]: matrix0 data in Q15 domain. 82523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1[]: matrix1 data. 82623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix_product[]: output data (matrix product). 82723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1_index_factor1: The first of two factors determining the 82823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org initialization value of matrix1_index. 82923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0_index_factor1: The first of two factors determining the 83023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org initialization value of matrix0_index. 83123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1_index_init_case: Case number for selecting the second of two 83223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org factors determining the initialization value 83323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org of matrix1_index and matrix0_index. 83423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1_index_step: Incremental step for matrix1_index. 83523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0_index_step: Incremental step for matrix0_index. 83623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org inner_loop_count: Maximum count of the inner loop. 83723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org mid_loop_count: Maximum count of the intermediate loop. 83823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org shift: Left shift value for matrix1. 83923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org*/ 84023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgvoid WebRtcIsacfix_MatrixProduct1C(const int16_t matrix0[], 84123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int32_t matrix1[], 84223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int32_t matrix_product[], 84323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int matrix1_index_factor1, 84423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int matrix0_index_factor1, 84523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int matrix1_index_init_case, 84623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int matrix1_index_step, 84723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int matrix0_index_step, 84823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int inner_loop_count, 84923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int mid_loop_count, 85023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int shift) { 85123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int j = 0, k = 0, n = 0; 85223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int matrix0_index = 0, matrix1_index = 0, matrix_prod_index = 0; 85323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int* matrix0_index_factor2 = &k; 85423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int* matrix1_index_factor2 = &j; 85523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org if (matrix1_index_init_case != 0) { 85623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0_index_factor2 = &j; 85723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1_index_factor2 = &k; 85823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org } 85923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 86023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org for (j = 0; j < SUBFRAMES; j++) { 86123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix_prod_index = mid_loop_count * j; 86223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org for (k = 0; k < mid_loop_count; k++) { 86323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int32_t sum32 = 0; 86423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0_index = matrix0_index_factor1 * (*matrix0_index_factor2); 86523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1_index = matrix1_index_factor1 * (*matrix1_index_factor2); 86623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org for (n = 0; n < inner_loop_count; n++) { 86723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sum32 += (WEBRTC_SPL_MUL_16_32_RSFT16(matrix0[matrix0_index], 86823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1[matrix1_index] << shift)); 86923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0_index += matrix0_index_step; 87023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1_index += matrix1_index_step; 87123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org } 87223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix_product[matrix_prod_index] = sum32; 87323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix_prod_index++; 87423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org } 87523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org } 87623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org} 87723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 87823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org/* 87923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgFunction WebRtcIsacfix_MatrixProduct2C() returns the product of two matrixes, 88023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgone of which has two columns. It first has to determine the correct index of 88123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgthe first matrix before doing the actual element multiplication. 88223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 88323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgArguments: 88423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0[]: A matrix in Q15 domain. 88523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1[]: A matrix in Q21 domain. 88623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix_product[]: Output data in Q17 domain. 88723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0_index_factor: A factor determining the initialization value 88823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org of matrix0_index. 88923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0_index_step: Incremental step for matrix0_index. 89023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org*/ 89123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgvoid WebRtcIsacfix_MatrixProduct2C(const int16_t matrix0[], 89223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int32_t matrix1[], 89323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int32_t matrix_product[], 89423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int matrix0_index_factor, 89523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int matrix0_index_step) { 89623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int j = 0, n = 0; 89723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int matrix1_index = 0, matrix0_index = 0, matrix_prod_index = 0; 89823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org for (j = 0; j < SUBFRAMES; j++) { 89923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int32_t sum32 = 0, sum32_2 = 0; 90023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1_index = 0; 90123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0_index = matrix0_index_factor * j; 90223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org for (n = SUBFRAMES; n > 0; n--) { 90323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sum32 += (WEBRTC_SPL_MUL_16_32_RSFT16(matrix0[matrix0_index], 90423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1[matrix1_index])); 90523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sum32_2 += (WEBRTC_SPL_MUL_16_32_RSFT16(matrix0[matrix0_index], 90623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1[matrix1_index + 1])); 90723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1_index += 2; 90823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0_index += matrix0_index_step; 90923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org } 91023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix_product[matrix_prod_index] = sum32 >> 3; 91123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix_product[matrix_prod_index + 1] = sum32_2 >> 3; 91223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix_prod_index += 2; 91323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org } 91423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org} 91523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 9160946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint WebRtcIsacfix_DecodeLpc(int32_t *gain_lo_hiQ17, 9170946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *LPCCoef_loQ15, 9180946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *LPCCoef_hiQ15, 919470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Bitstr_dec *streamdata, 9200946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *outmodel) { 921470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 9220946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t larsQ17[KLT_ORDER_SHAPE]; // KLT_ORDER_GAIN+KLT_ORDER_SHAPE == (ORDERLO+ORDERHI)*SUBFRAMES 923470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int err; 924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecodeLpcCoef(streamdata, larsQ17, gain_lo_hiQ17, outmodel); 926470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (err<0) // error check 927470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -ISAC_RANGE_ERROR_DECODE_LPC; 928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Lar2polyFix(larsQ17, LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES); 930470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* decode & dequantize LPC Coef */ 935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_DecodeLpcCoef(Bitstr_dec *streamdata, 9360946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t *LPCCoefQ17, 9370946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t *gain_lo_hiQ17, 9380946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *outmodel) 939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int j, k, n; 941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int err; 9420946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t pos, pos2, posg, poss; 9430946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t gainpos; 9440946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t model; 9450946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t index_QQ[KLT_ORDER_SHAPE]; 9460946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t tmpcoeffs_gQ17[KLT_ORDER_GAIN]; 9470946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t tmpcoeffs2_gQ21[KLT_ORDER_GAIN]; 9480946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t tmpcoeffs_sQ10[KLT_ORDER_SHAPE]; 9490946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t tmpcoeffs_sQ17[KLT_ORDER_SHAPE]; 9500946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t tmpcoeffs2_sQ18[KLT_ORDER_SHAPE]; 9510946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t sumQQ; 9520946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t sumQQ16; 9530946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t tmp32; 954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy decoding of model number */ 958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecHistOneStepMulti(&model, streamdata, WebRtcIsacfix_kModelCdfPtr, WebRtcIsacfix_kModelInitIndex, 1); 959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (err<0) // error check 960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return err; 961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy decoding of quantization indices */ 963470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecHistOneStepMulti(index_QQ, streamdata, WebRtcIsacfix_kCdfShapePtr[model], WebRtcIsacfix_kInitIndexShape[model], KLT_ORDER_SHAPE); 964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (err<0) // error check 965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return err; 966470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find quantization levels for coefficients */ 967470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_SHAPE; k++) { 968470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_sQ10[WebRtcIsacfix_kSelIndShape[k]] = WebRtcIsacfix_kLevelsShapeQ10[WebRtcIsacfix_kOfLevelsShape[model]+WebRtcIsacfix_kOffsetShape[model][k] + index_QQ[k]]; 969470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 970470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecHistOneStepMulti(index_QQ, streamdata, WebRtcIsacfix_kCdfGainPtr[model], WebRtcIsacfix_kInitIndexGain[model], KLT_ORDER_GAIN); 972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (err<0) // error check 973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return err; 974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find quantization levels for coefficients */ 975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_GAIN; k++) { 976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ17[WebRtcIsacfix_kSelIndGain[k]] = WebRtcIsacfix_kLevelsGainQ17[WebRtcIsacfix_kOfLevelsGain[model]+ WebRtcIsacfix_kOffsetGain[model][k] + index_QQ[k]]; 977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* inverse KLT */ 981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* left transform */ // Transpose matrix! 98323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT1GainQ15[model], tmpcoeffs_gQ17, 98423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs2_gQ21, kTIndexFactor2, kTIndexFactor2, 98523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTInitCase0, kTIndexStep1, kTIndexStep1, 98623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTLoopCount2, kTLoopCount2, kTMatrix1_shift5); 98723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com poss = 0; 989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (j=0; j<SUBFRAMES; j++) { 990470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<LPC_SHAPE_ORDER; k++) { 991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ = 0; 99223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org pos = LPC_SHAPE_ORDER * j; 99323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org pos2 = LPC_SHAPE_ORDER * k; 994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n=0; n<LPC_SHAPE_ORDER; n++) { 995f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker sumQQ += tmpcoeffs_sQ10[pos] * 996f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker WebRtcIsacfix_kT1ShapeQ15[model][pos2] >> 7; // (Q10*Q15)>>7 = Q18 997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos++; 998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos2++; 999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs2_sQ18[poss] = sumQQ; //Q18 1001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com poss++; 1002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* right transform */ // Transpose matrix 100623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21, 100723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_gQ17, kTIndexFactor1, kTIndexStep2); 100823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT2ShapeQ15[model], 100923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs2_sQ18, tmpcoeffs_sQ17, kTIndexFactor1, kTIndexFactor1, 101023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTInitCase1, kTIndexStep3, kTIndexStep2, kTLoopCount1, kTLoopCount3, 101123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTMatrix1_shift0); 1012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1013470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* scaling, mean addition, and gain restoration */ 1014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gainpos = 0; 1015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg = 0;poss = 0;pos=0; 1016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<SUBFRAMES; k++) { 1017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* log gains */ 1019a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org // Divide by 4 and get Q17 to Q8, i.e. shift 2+9. 1020a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org sumQQ16 = (int16_t)(tmpcoeffs_gQ17[posg] >> 11); 1021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ16 += WebRtcIsacfix_kMeansGainQ8[model][posg]; 1022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out 1023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gain_lo_hiQ17[gainpos] = sumQQ; //Q17 1024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gainpos++; 1025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; 1026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1027a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org // Divide by 4 and get Q17 to Q8, i.e. shift 2+9. 1028a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org sumQQ16 = (int16_t)(tmpcoeffs_gQ17[posg] >> 11); 1029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ16 += WebRtcIsacfix_kMeansGainQ8[model][posg]; 1030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out 1031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gain_lo_hiQ17[gainpos] = sumQQ; //Q17 1032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gainpos++; 1033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; 1034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1035470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* lo band LAR coeffs */ 1036470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n=0; n<ORDERLO; n++, pos++, poss++) { 1037470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(31208, tmpcoeffs_sQ17[poss]); // (Q16*Q17)>>16 = Q17, with 1/2.1 = 0.47619047619 ~= 31208 in Q16 1038470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[model][poss]; // Q17+Q17 = Q17 1039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com LPCCoefQ17[pos] = tmp32; 1040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1041470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* hi band LAR coeffs */ 1043470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n=0; n<ORDERHI; n++, pos++, poss++) { 1044d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker // ((Q13*Q17)>>16)<<3 = Q17, with 1/0.45 = 2.222222222222 ~= 18204 in Q13 1045d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(18204, tmpcoeffs_sQ17[poss]) << 3; 1046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[model][poss]; // Q17+Q17 = Q17 1047470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com LPCCoefQ17[pos] = tmp32; 1048470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1052470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *outmodel=model; 1053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1054470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1055470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* estimate codel length of LPC Coef */ 10580946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic int EstCodeLpcCoef(int32_t *LPCCoefQ17, 10590946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t *gain_lo_hiQ17, 10600946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *model, 10610946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t *sizeQ11, 1062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Bitstr_enc *streamdata, 1063eb544460e47140d494dddf1217a698a1dcf4dee0pbos@webrtc.org IsacSaveEncoderData* encData, 1064470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com transcode_obj *transcodingParam) { 1065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int j, k, n; 10660946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t posQQ, pos2QQ, gainpos; 10670946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t pos, poss, posg, offsg; 10680946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t index_gQQ[KLT_ORDER_GAIN], index_sQQ[KLT_ORDER_SHAPE]; 10690946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t index_ovr_gQQ[KLT_ORDER_GAIN], index_ovr_sQQ[KLT_ORDER_SHAPE]; 10700946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t BitsQQ; 10710946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org 10720946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t tmpcoeffs_gQ6[KLT_ORDER_GAIN]; 10730946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t tmpcoeffs_gQ17[KLT_ORDER_GAIN]; 10740946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t tmpcoeffs_sQ17[KLT_ORDER_SHAPE]; 10750946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t tmpcoeffs2_gQ21[KLT_ORDER_GAIN]; 10760946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t tmpcoeffs2_sQ17[KLT_ORDER_SHAPE]; 10770946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t sumQQ; 10780946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t tmp32; 10790946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t sumQQ16; 1080470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int status = 0; 1081470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1082470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* write LAR coefficients to statistics file */ 1083470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Save data for creation of multiple bitstreams (and transcoding) */ 1084470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (encData != NULL) { 1085470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_GAIN; k++) { 1086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com encData->LPCcoeffs_g[KLT_ORDER_GAIN*encData->startIdx + k] = gain_lo_hiQ17[k]; 1087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1088470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1089470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* log gains, mean removal and scaling */ 1091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg = 0;poss = 0;pos=0; gainpos=0; 1092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1093470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<SUBFRAMES; k++) { 1094470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* log gains */ 1095470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1096470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* The input argument X to logN(X) is 2^17 times higher than the 1097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com input floating point argument Y to log(Y), since the X value 1098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com is a Q17 value. This can be compensated for after the call, by 1099470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subraction a value Z for each Q-step. One Q-step means that 1100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com X gets 2 times higher, i.e. Z = logN(2)*256 = 0.693147180559*256 = 1101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 177.445678 should be subtracted (since logN() returns a Q8 value). 1102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com For a X value in Q17, the value 177.445678*17 = 3017 should be 1103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subtracted */ 1104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 1105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 1106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; gainpos++; 1107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 1109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 1110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; gainpos++; 1111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* lo band LAR coeffs */ 1113470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n=0; n<ORDERLO; n++, poss++, pos++) { 1114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32 = LPCCoefQ17[pos] - WebRtcIsacfix_kMeansShapeQ17[0][poss]; //Q17 1115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(17203, tmp32<<3); // tmp32 = 2.1*tmp32 1116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_sQ17[poss] = tmp32; //Q17 1117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* hi band LAR coeffs */ 1120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n=0; n<ORDERHI; n++, poss++, pos++) { 1121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32 = LPCCoefQ17[pos] - WebRtcIsacfix_kMeansShapeQ17[0][poss]; //Q17 1122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(14746, tmp32<<1); // tmp32 = 0.45*tmp32 1123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_sQ17[poss] = tmp32; //Q17 1124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* KLT */ 1130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* left transform */ 1132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com offsg = 0; 113323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org posg = 0; 1134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (j=0; j<SUBFRAMES; j++) { 113523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org // Q21 = Q6 * Q15 1136bc2bb34419021fb3be4f87eb062cf0a9ed52675abjornv@webrtc.org sumQQ = tmpcoeffs_gQ6[offsg] * WebRtcIsacfix_kT1GainQ15[0][0] + 1137bc2bb34419021fb3be4f87eb062cf0a9ed52675abjornv@webrtc.org tmpcoeffs_gQ6[offsg + 1] * WebRtcIsacfix_kT1GainQ15[0][2]; 113823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs2_gQ21[posg] = sumQQ; 113923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org posg++; 114023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 114123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org // Q21 = Q6 * Q15 1142bc2bb34419021fb3be4f87eb062cf0a9ed52675abjornv@webrtc.org sumQQ = tmpcoeffs_gQ6[offsg] * WebRtcIsacfix_kT1GainQ15[0][1] + 1143bc2bb34419021fb3be4f87eb062cf0a9ed52675abjornv@webrtc.org tmpcoeffs_gQ6[offsg + 1] * WebRtcIsacfix_kT1GainQ15[0][3]; 114423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs2_gQ21[posg] = sumQQ; 114523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org posg++; 114623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 1147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com offsg += 2; 1148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 115023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT1ShapeQ15[0], tmpcoeffs_sQ17, 115123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs2_sQ17, kTIndexFactor4, kTIndexFactor1, kTInitCase0, 115223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTIndexStep1, kTIndexStep3, kTLoopCount3, kTLoopCount3, kTMatrix1_shift1); 115323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 1154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* right transform */ 115523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21, 115623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_gQ17, kTIndexFactor3, kTIndexStep1); 115723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 115823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT2ShapeQ15[0], tmpcoeffs2_sQ17, 115923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_sQ17, kTIndexFactor1, kTIndexFactor3, kTInitCase1, kTIndexStep3, 116023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTIndexStep1, kTLoopCount1, kTLoopCount3, kTMatrix1_shift1); 1161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* quantize coefficients */ 1163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com BitsQQ = 0; 1165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok? 1166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posQQ = WebRtcIsacfix_kSelIndGain[k]; 11680946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org pos2QQ= (int16_t)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17); 1169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok? 1171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (index_gQQ[k] < 0) { 1172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_gQQ[k] = 0; 1173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) { 1175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k]; 1176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_ovr_gQQ[k] = WebRtcIsacfix_kOffsetGain[0][k]+index_gQQ[k]; 1178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posQQ = WebRtcIsacfix_kOfLevelsGain[0] + index_ovr_gQQ[k]; 1179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Save data for creation of multiple bitstreams */ 1181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (encData != NULL) { 1182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com encData->LPCindex_g[KLT_ORDER_GAIN*encData->startIdx + k] = index_gQQ[k]; 1183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* determine number of bits */ 1186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ = WebRtcIsacfix_kCodeLenGainQ11[posQQ]; //Q11 1187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com BitsQQ += sumQQ; 1188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_SHAPE; k++) //ATTN: ok? 1191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 11920946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org index_sQQ[k] = (int16_t)(CalcLrIntQ(tmpcoeffs_sQ17[WebRtcIsacfix_kSelIndShape[k]], 17) + WebRtcIsacfix_kQuantMinShape[k]); //ATTN: ok? 1193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (index_sQQ[k] < 0) 1195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_sQQ[k] = 0; 1196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (index_sQQ[k] > WebRtcIsacfix_kMaxIndShape[k]) 1197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_sQQ[k] = WebRtcIsacfix_kMaxIndShape[k]; 1198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_ovr_sQQ[k] = WebRtcIsacfix_kOffsetShape[0][k]+index_sQQ[k]; 1199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posQQ = WebRtcIsacfix_kOfLevelsShape[0] + index_ovr_sQQ[k]; 1201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ = WebRtcIsacfix_kCodeLenShapeQ11[posQQ]; //Q11 1202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com BitsQQ += sumQQ; 1203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *model = 0; 1208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *sizeQ11=BitsQQ; 1209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy coding of model number */ 1211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncHistMulti(streamdata, model, WebRtcIsacfix_kModelCdfPtr, 1); 1212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (status < 0) { 1213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy coding of quantization indices - shape only */ 1217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncHistMulti(streamdata, index_sQQ, WebRtcIsacfix_kCdfShapePtr[0], KLT_ORDER_SHAPE); 1218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (status < 0) { 1219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Save data for creation of multiple bitstreams */ 1223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (encData != NULL) { 1224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_SHAPE; k++) 1225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com encData->LPCindex_s[KLT_ORDER_SHAPE*encData->startIdx + k] = index_sQQ[k]; 1227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* save the state of the bitstream object 'streamdata' for the possible bit-rate reduction */ 1230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com transcodingParam->full = streamdata->full; 1231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com transcodingParam->stream_index = streamdata->stream_index; 1232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com transcodingParam->streamval = streamdata->streamval; 1233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com transcodingParam->W_upper = streamdata->W_upper; 1234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com transcodingParam->beforeLastWord = streamdata->stream[streamdata->stream_index-1]; 1235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com transcodingParam->lastWord = streamdata->stream[streamdata->stream_index]; 1236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy coding of index */ 1238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncHistMulti(streamdata, index_gQQ, WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN); 1239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (status < 0) { 1240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find quantization levels for shape coefficients */ 1244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_SHAPE; k++) { 1245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_sQ17[WebRtcIsacfix_kSelIndShape[k]] = WEBRTC_SPL_MUL(128, WebRtcIsacfix_kLevelsShapeQ10[WebRtcIsacfix_kOfLevelsShape[0]+index_ovr_sQQ[k]]); 1246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* inverse KLT */ 1249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* left transform */ // Transpose matrix! 125123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT1ShapeQ15[0], tmpcoeffs_sQ17, 125223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs2_sQ17, kTIndexFactor4, kTIndexFactor4, kTInitCase0, 125323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTIndexStep1, kTIndexStep1, kTLoopCount3, kTLoopCount3, kTMatrix1_shift1); 1254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* right transform */ // Transpose matrix 125623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT2ShapeQ15[0], tmpcoeffs2_sQ17, 125723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_sQ17, kTIndexFactor1, kTIndexFactor1, kTInitCase1, kTIndexStep3, 125823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTIndexStep2, kTLoopCount1, kTLoopCount3, kTMatrix1_shift1); 1259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* scaling, mean addition, and gain restoration */ 1261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com poss = 0;pos=0; 1262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<SUBFRAMES; k++) { 1263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* lo band LAR coeffs */ 1265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n=0; n<ORDERLO; n++, pos++, poss++) { 1266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(31208, tmpcoeffs_sQ17[poss]); // (Q16*Q17)>>16 = Q17, with 1/2.1 = 0.47619047619 ~= 31208 in Q16 1267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[0][poss]; // Q17+Q17 = Q17 1268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com LPCCoefQ17[pos] = tmp32; 1269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* hi band LAR coeffs */ 1272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n=0; n<ORDERHI; n++, pos++, poss++) { 1273d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker // ((Q13*Q17)>>16)<<3 = Q17, with 1/0.45 = 2.222222222222 ~= 18204 in Q13 1274d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(18204, tmpcoeffs_sQ17[poss]) << 3; 1275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[0][poss]; // Q17+Q17 = Q17 1276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com LPCCoefQ17[pos] = tmp32; 1277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com //to update tmpcoeffs_gQ17 to the proper state 1282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_GAIN; k++) { 1283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ17[WebRtcIsacfix_kSelIndGain[k]] = WebRtcIsacfix_kLevelsGainQ17[WebRtcIsacfix_kOfLevelsGain[0]+index_ovr_gQQ[k]]; 1284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find quantization levels for coefficients */ 1289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* left transform */ 1291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com offsg = 0; 1292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg = 0; 1293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (j=0; j<SUBFRAMES; j++) { 129423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org // (Q15 * Q17) >> (16 - 1) = Q17; Q17 << 4 = Q21. 129523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sumQQ = (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[0][0], 129623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_gQ17[offsg]) << 1); 129723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[0][1], 129823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_gQ17[offsg + 1]) << 1); 1299d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker tmpcoeffs2_gQ21[posg] = sumQQ << 4; 130023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org posg++; 130123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 130223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sumQQ = (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[0][2], 130323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_gQ17[offsg]) << 1); 130423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[0][3], 130523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_gQ17[offsg + 1]) << 1); 1306d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker tmpcoeffs2_gQ21[posg] = sumQQ << 4; 130723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org posg++; 1308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com offsg += 2; 1309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* right transform */ // Transpose matrix 131223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21, 131323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_gQ17, kTIndexFactor1, kTIndexStep2); 1314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* scaling, mean addition, and gain restoration */ 1316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg = 0; 1317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gainpos = 0; 1318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<2*SUBFRAMES; k++) { 1319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1320a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org // Divide by 4 and get Q17 to Q8, i.e. shift 2+9. 1321a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org sumQQ16 = (int16_t)(tmpcoeffs_gQ17[posg] >> 11); 1322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ16 += WebRtcIsacfix_kMeansGainQ8[0][posg]; 1323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out 1324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gain_lo_hiQ17[gainpos] = sumQQ; //Q17 1325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gainpos++; 1327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos++;posg++; 1328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13330946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint WebRtcIsacfix_EstCodeLpcGain(int32_t *gain_lo_hiQ17, 1334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Bitstr_enc *streamdata, 1335eb544460e47140d494dddf1217a698a1dcf4dee0pbos@webrtc.org IsacSaveEncoderData* encData) { 133623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int j, k; 13370946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t posQQ, pos2QQ, gainpos; 13380946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t posg; 13390946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t index_gQQ[KLT_ORDER_GAIN]; 13400946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org 13410946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t tmpcoeffs_gQ6[KLT_ORDER_GAIN]; 13420946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t tmpcoeffs_gQ17[KLT_ORDER_GAIN]; 13430946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t tmpcoeffs2_gQ21[KLT_ORDER_GAIN]; 13440946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t sumQQ; 1345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int status = 0; 1346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* write LAR coefficients to statistics file */ 1348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Save data for creation of multiple bitstreams (and transcoding) */ 1349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (encData != NULL) { 1350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_GAIN; k++) { 1351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com encData->LPCcoeffs_g[KLT_ORDER_GAIN*encData->startIdx + k] = gain_lo_hiQ17[k]; 1352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* log gains, mean removal and scaling */ 135623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org posg = 0; gainpos = 0; 1357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<SUBFRAMES; k++) { 1359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* log gains */ 1360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* The input argument X to logN(X) is 2^17 times higher than the 1362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com input floating point argument Y to log(Y), since the X value 1363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com is a Q17 value. This can be compensated for after the call, by 1364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subraction a value Z for each Q-step. One Q-step means that 1365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com X gets 2 times higher, i.e. Z = logN(2)*256 = 0.693147180559*256 = 1366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 177.445678 should be subtracted (since logN() returns a Q8 value). 1367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com For a X value in Q17, the value 177.445678*17 = 3017 should be 1368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subtracted */ 1369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 1370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 1371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; gainpos++; 1372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 1374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 1375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; gainpos++; 1376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* KLT */ 1380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* left transform */ 138223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org posg = 0; 1383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (j=0; j<SUBFRAMES; j++) { 138423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org // Q21 = Q6 * Q15 1385bc2bb34419021fb3be4f87eb062cf0a9ed52675abjornv@webrtc.org sumQQ = tmpcoeffs_gQ6[j * 2] * WebRtcIsacfix_kT1GainQ15[0][0] + 1386bc2bb34419021fb3be4f87eb062cf0a9ed52675abjornv@webrtc.org tmpcoeffs_gQ6[j * 2 + 1] * WebRtcIsacfix_kT1GainQ15[0][2]; 1387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs2_gQ21[posg] = sumQQ; 1388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; 1389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1390bc2bb34419021fb3be4f87eb062cf0a9ed52675abjornv@webrtc.org sumQQ = tmpcoeffs_gQ6[j * 2] * WebRtcIsacfix_kT1GainQ15[0][1] + 1391bc2bb34419021fb3be4f87eb062cf0a9ed52675abjornv@webrtc.org tmpcoeffs_gQ6[j * 2 + 1] * WebRtcIsacfix_kT1GainQ15[0][3]; 139223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs2_gQ21[posg] = sumQQ; 1393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; 1394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 139623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org /* right transform */ 139723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21, 139823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_gQ17, kTIndexFactor3, kTIndexStep1); 139923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 1400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* quantize coefficients */ 1401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok? 1403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posQQ = WebRtcIsacfix_kSelIndGain[k]; 14050946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org pos2QQ= (int16_t)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17); 1406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok? 1408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (index_gQQ[k] < 0) { 1409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_gQQ[k] = 0; 1410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) { 1412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k]; 1413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Save data for creation of multiple bitstreams */ 1416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (encData != NULL) { 1417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com encData->LPCindex_g[KLT_ORDER_GAIN*encData->startIdx + k] = index_gQQ[k]; 1418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy coding of index */ 1422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncHistMulti(streamdata, index_gQQ, WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN); 1423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (status < 0) { 1424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 14310946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint WebRtcIsacfix_EncodeLpc(int32_t *gain_lo_hiQ17, 14320946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *LPCCoef_loQ15, 14330946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *LPCCoef_hiQ15, 14340946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *model, 14350946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t *sizeQ11, 1436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Bitstr_enc *streamdata, 1437eb544460e47140d494dddf1217a698a1dcf4dee0pbos@webrtc.org IsacSaveEncoderData* encData, 1438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com transcode_obj *transcodeParam) 1439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int status = 0; 14410946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t larsQ17[KLT_ORDER_SHAPE]; // KLT_ORDER_SHAPE == (ORDERLO+ORDERHI)*SUBFRAMES 1442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // = (6+12)*6 == 108 1443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Poly2LarFix(LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES, larsQ17); 1445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 144623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org status = EstCodeLpcCoef(larsQ17, gain_lo_hiQ17, model, sizeQ11, 144723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org streamdata, encData, transcodeParam); 1448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (status < 0) { 1449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return (status); 1450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Lar2polyFix(larsQ17, LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES); 1453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* decode & dequantize RC */ 14590946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint WebRtcIsacfix_DecodeRcCoef(Bitstr_dec *streamdata, int16_t *RCQ15) 1460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k, err; 14620946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t index[AR_ORDER]; 1463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy decoding of quantization indices */ 1465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecHistOneStepMulti(index, streamdata, WebRtcIsacfix_kRcCdfPtr, WebRtcIsacfix_kRcInitInd, AR_ORDER); 1466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (err<0) // error check 1467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return err; 1468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find quantization levels for reflection coefficients */ 1470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<AR_ORDER; k++) 1471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RCQ15[k] = *(WebRtcIsacfix_kRcLevPtr[k] + index[k]); 1473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* quantize & code RC */ 14810946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint WebRtcIsacfix_EncodeRcCoef(int16_t *RCQ15, Bitstr_enc *streamdata) 1482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k; 14840946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t index[AR_ORDER]; 1485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int status; 1486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* quantize reflection coefficients (add noise feedback?) */ 1488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<AR_ORDER; k++) 1489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index[k] = WebRtcIsacfix_kRcInitInd[k]; 1491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (RCQ15[k] > WebRtcIsacfix_kRcBound[index[k]]) 1493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com while (RCQ15[k] > WebRtcIsacfix_kRcBound[index[k] + 1]) 1495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index[k]++; 1496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 1498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com while (RCQ15[k] < WebRtcIsacfix_kRcBound[--index[k]]) ; 1500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RCQ15[k] = *(WebRtcIsacfix_kRcLevPtr[k] + index[k]); 1503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy coding of quantization indices */ 1507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncHistMulti(streamdata, index, WebRtcIsacfix_kRcCdfPtr, AR_ORDER); 1508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */ 1510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* decode & dequantize squared Gain */ 15150946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint WebRtcIsacfix_DecodeGain2(Bitstr_dec *streamdata, int32_t *gainQ10) 1516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int err; 15180946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t index; 1519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy decoding of quantization index */ 1521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecHistOneStepMulti( 1522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &index, 1523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamdata, 1524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcIsacfix_kGainPtr, 1525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcIsacfix_kGainInitInd, 1526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1); 1527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* error check */ 1528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (err<0) { 1529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return err; 1530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find quantization level */ 1533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *gainQ10 = WebRtcIsacfix_kGain2Lev[index]; 1534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* quantize & code squared Gain */ 15410946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint WebRtcIsacfix_EncodeGain2(int32_t *gainQ10, Bitstr_enc *streamdata) 1542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 15430946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t index; 1544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int status = 0; 1545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find quantization index */ 1547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index = WebRtcIsacfix_kGainInitInd[0]; 1548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (*gainQ10 > WebRtcIsacfix_kGain2Bound[index]) 1549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com while (*gainQ10 > WebRtcIsacfix_kGain2Bound[index + 1]) 1551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index++; 1552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 1554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com while (*gainQ10 < WebRtcIsacfix_kGain2Bound[--index]) ; 1556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* dequantize */ 1559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *gainQ10 = WebRtcIsacfix_kGain2Lev[index]; 1560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy coding of quantization index */ 1562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncHistMulti(streamdata, &index, WebRtcIsacfix_kGainPtr, 1); 1563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */ 1565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* code and decode Pitch Gains and Lags functions */ 1570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* decode & dequantize Pitch Gains */ 15720946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint WebRtcIsacfix_DecodePitchGain(Bitstr_dec *streamdata, int16_t *PitchGains_Q12) 1573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int err; 15750946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t index_comb; 15760946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const uint16_t *pitch_gain_cdf_ptr[1]; 1577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy decoding of quantization indices */ 1579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *pitch_gain_cdf_ptr = WebRtcIsacfix_kPitchGainCdf; 1580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecHistBisectMulti(&index_comb, streamdata, pitch_gain_cdf_ptr, WebRtcIsacfix_kCdfTableSizeGain, 1); 1581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* error check, Q_mean_Gain.. tables are of size 144 */ 15821617f65eecbd894b17870929a9ffec4d62078d89tina.legrand@webrtc.org if ((err < 0) || (index_comb < 0) || (index_comb >= 144)) 1583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -ISAC_RANGE_ERROR_DECODE_PITCH_GAIN; 1584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* unquantize back to pitch gains by table look-up */ 1586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchGains_Q12[0] = WebRtcIsacfix_kPitchGain1[index_comb]; 1587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchGains_Q12[1] = WebRtcIsacfix_kPitchGain2[index_comb]; 1588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchGains_Q12[2] = WebRtcIsacfix_kPitchGain3[index_comb]; 1589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchGains_Q12[3] = WebRtcIsacfix_kPitchGain4[index_comb]; 1590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* quantize & code Pitch Gains */ 1596eb544460e47140d494dddf1217a698a1dcf4dee0pbos@webrtc.orgint WebRtcIsacfix_EncodePitchGain(int16_t* PitchGains_Q12, 1597eb544460e47140d494dddf1217a698a1dcf4dee0pbos@webrtc.org Bitstr_enc* streamdata, 1598eb544460e47140d494dddf1217a698a1dcf4dee0pbos@webrtc.org IsacSaveEncoderData* encData) { 1599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k,j; 16000946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t SQ15[PITCH_SUBFRAMES]; 16010946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t index[3]; 16020946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t index_comb; 16030946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const uint16_t *pitch_gain_cdf_ptr[1]; 16040946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t CQ17; 1605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int status = 0; 1606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* get the approximate arcsine (almost linear)*/ 1609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<PITCH_SUBFRAMES; k++) 1610f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker SQ15[k] = (int16_t)(PitchGains_Q12[k] * 33 >> 2); // Q15 1611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find quantization index; only for the first three transform coefficients */ 1614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<3; k++) 1615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* transform */ 1617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ17=0; 1618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (j=0; j<PITCH_SUBFRAMES; j++) { 1619f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker CQ17 += WebRtcIsacfix_kTransform[k][j] * SQ15[j] >> 10; // Q17 1620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 16220946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org index[k] = (int16_t)((CQ17 + 8192)>>14); // Rounding and scaling with stepsize (=1/0.125=8) 1623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* check that the index is not outside the boundaries of the table */ 1625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (index[k] < WebRtcIsacfix_kLowerlimiGain[k]) index[k] = WebRtcIsacfix_kLowerlimiGain[k]; 1626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (index[k] > WebRtcIsacfix_kUpperlimitGain[k]) index[k] = WebRtcIsacfix_kUpperlimitGain[k]; 1627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index[k] -= WebRtcIsacfix_kLowerlimiGain[k]; 1628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* calculate unique overall index */ 16310946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org index_comb = (int16_t)(WEBRTC_SPL_MUL(WebRtcIsacfix_kMultsGain[0], index[0]) + 1632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_SPL_MUL(WebRtcIsacfix_kMultsGain[1], index[1]) + index[2]); 1633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* unquantize back to pitch gains by table look-up */ 1635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (Y) 1636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchGains_Q12[0] = WebRtcIsacfix_kPitchGain1[index_comb]; 1637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchGains_Q12[1] = WebRtcIsacfix_kPitchGain2[index_comb]; 1638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchGains_Q12[2] = WebRtcIsacfix_kPitchGain3[index_comb]; 1639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchGains_Q12[3] = WebRtcIsacfix_kPitchGain4[index_comb]; 1640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy coding of quantization pitch gains */ 1643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *pitch_gain_cdf_ptr = WebRtcIsacfix_kPitchGainCdf; 1644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncHistMulti(streamdata, &index_comb, pitch_gain_cdf_ptr, 1); 1645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (status < 0) { 1646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Save data for creation of multiple bitstreams */ 1650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (encData != NULL) { 1651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com encData->pitchGain_index[encData->startIdx] = index_comb; 1652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* Pitch LAG */ 1660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1662470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* decode & dequantize Pitch Lags */ 1663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_DecodePitchLag(Bitstr_dec *streamdata, 16640946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *PitchGain_Q12, 16650946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *PitchLags_Q7) 1666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k, err; 16680946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t index[PITCH_SUBFRAMES]; 16690946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const int16_t *mean_val2Q10, *mean_val4Q10; 1670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 16710946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const int16_t *lower_limit; 16720946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const uint16_t *init_index; 16730946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const uint16_t *cdf_size; 16740946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const uint16_t **cdf; 1675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 16760946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t meangainQ12; 16770946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t CQ11, CQ10,tmp32a,tmp32b; 1678728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting int16_t shft; 1679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com meangainQ12=0; 1681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < 4; k++) 1682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com meangainQ12 += PitchGain_Q12[k]; 1683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1684a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org meangainQ12 >>= 2; // Get average. 1685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1686470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* voicing classificiation */ 1687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (meangainQ12 <= 819) { // mean_gain < 0.2 1688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shft = -1; // StepSize=2.0; 1689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdf = WebRtcIsacfix_kPitchLagPtrLo; 1690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdf_size = WebRtcIsacfix_kPitchLagSizeLo; 1691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val2Q10 = WebRtcIsacfix_kMeanLag2Lo; 1692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val4Q10 = WebRtcIsacfix_kMeanLag4Lo; 1693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lower_limit = WebRtcIsacfix_kLowerLimitLo; 1694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com init_index = WebRtcIsacfix_kInitIndLo; 1695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else if (meangainQ12 <= 1638) { // mean_gain < 0.4 1696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shft = 0; // StepSize=1.0; 1697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdf = WebRtcIsacfix_kPitchLagPtrMid; 1698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdf_size = WebRtcIsacfix_kPitchLagSizeMid; 1699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val2Q10 = WebRtcIsacfix_kMeanLag2Mid; 1700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val4Q10 = WebRtcIsacfix_kMeanLag4Mid; 1701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lower_limit = WebRtcIsacfix_kLowerLimitMid; 1702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com init_index = WebRtcIsacfix_kInitIndMid; 1703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 1704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shft = 1; // StepSize=0.5; 1705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdf = WebRtcIsacfix_kPitchLagPtrHi; 1706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdf_size = WebRtcIsacfix_kPitchLagSizeHi; 1707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val2Q10 = WebRtcIsacfix_kMeanLag2Hi; 1708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val4Q10 = WebRtcIsacfix_kMeanLag4Hi; 1709470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lower_limit = WebRtcIsacfix_kLowerLimitHi; 1710470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com init_index = WebRtcIsacfix_kInitIndHi; 1711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy decoding of quantization indices */ 1714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecHistBisectMulti(index, streamdata, cdf, cdf_size, 1); 1715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((err<0) || (index[0]<0)) // error check 1716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG; 1717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecHistOneStepMulti(index+1, streamdata, cdf+1, init_index, 3); 1719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (err<0) // error check 1720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG; 1721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* unquantize back to transform coefficients and do the inverse transform: S = T'*C */ 17240946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org CQ11 = ((int32_t)index[0] + lower_limit[0]); // Q0 1725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ11 = WEBRTC_SPL_SHIFT_W32(CQ11,11-shft); // Scale with StepSize, Q11 1726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<PITCH_SUBFRAMES; k++) { 1727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32a = WEBRTC_SPL_MUL_16_32_RSFT11(WebRtcIsacfix_kTransform[0][k], CQ11); 1728728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting PitchLags_Q7[k] = (int16_t)(tmp32a >> 5); 1729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ10 = mean_val2Q10[index[1]]; 1732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<PITCH_SUBFRAMES; k++) { 1733f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker tmp32b = WebRtcIsacfix_kTransform[1][k] * (int16_t)CQ10 >> 10; 1734728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting PitchLags_Q7[k] += (int16_t)(tmp32b >> 5); 1735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ10 = mean_val4Q10[index[3]]; 1738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<PITCH_SUBFRAMES; k++) { 1739f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker tmp32b = WebRtcIsacfix_kTransform[3][k] * (int16_t)CQ10 >> 10; 1740728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting PitchLags_Q7[k] += (int16_t)(tmp32b >> 5); 1741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* quantize & code Pitch Lags */ 1749eb544460e47140d494dddf1217a698a1dcf4dee0pbos@webrtc.orgint WebRtcIsacfix_EncodePitchLag(int16_t* PitchLagsQ7, 1750eb544460e47140d494dddf1217a698a1dcf4dee0pbos@webrtc.org int16_t* PitchGain_Q12, 1751eb544460e47140d494dddf1217a698a1dcf4dee0pbos@webrtc.org Bitstr_enc* streamdata, 1752eb544460e47140d494dddf1217a698a1dcf4dee0pbos@webrtc.org IsacSaveEncoderData* encData) { 1753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k, j; 17540946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t index[PITCH_SUBFRAMES]; 17550946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t meangainQ12, CQ17; 17560946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t CQ11, CQ10,tmp32a; 17570946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org 17580946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const int16_t *mean_val2Q10,*mean_val4Q10; 17590946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const int16_t *lower_limit, *upper_limit; 17600946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org const uint16_t **cdf; 1761728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting int16_t shft, tmp16b; 17620946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t tmp32b; 1763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int status = 0; 1764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* compute mean pitch gain */ 1766470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com meangainQ12=0; 1767470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < 4; k++) 1768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com meangainQ12 += PitchGain_Q12[k]; 1769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1770a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org meangainQ12 >>= 2; 1771470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1772470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Save data for creation of multiple bitstreams */ 1773470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (encData != NULL) { 1774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com encData->meanGain[encData->startIdx] = meangainQ12; 1775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* voicing classificiation */ 1778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (meangainQ12 <= 819) { // mean_gain < 0.2 1779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shft = -1; // StepSize=2.0; 1780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdf = WebRtcIsacfix_kPitchLagPtrLo; 1781470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val2Q10 = WebRtcIsacfix_kMeanLag2Lo; 1782470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val4Q10 = WebRtcIsacfix_kMeanLag4Lo; 1783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lower_limit = WebRtcIsacfix_kLowerLimitLo; 1784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com upper_limit = WebRtcIsacfix_kUpperLimitLo; 1785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else if (meangainQ12 <= 1638) { // mean_gain < 0.4 1786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shft = 0; // StepSize=1.0; 1787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdf = WebRtcIsacfix_kPitchLagPtrMid; 1788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val2Q10 = WebRtcIsacfix_kMeanLag2Mid; 1789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val4Q10 = WebRtcIsacfix_kMeanLag4Mid; 1790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lower_limit = WebRtcIsacfix_kLowerLimitMid; 1791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com upper_limit = WebRtcIsacfix_kUpperLimitMid; 1792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 1793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shft = 1; // StepSize=0.5; 1794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdf = WebRtcIsacfix_kPitchLagPtrHi; 1795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val2Q10 = WebRtcIsacfix_kMeanLag2Hi; 1796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val4Q10 = WebRtcIsacfix_kMeanLag4Hi; 1797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lower_limit = WebRtcIsacfix_kLowerLimitHi; 1798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com upper_limit = WebRtcIsacfix_kUpperLimitHi; 1799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find quantization index */ 1802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<4; k++) 1803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* transform */ 1805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ17=0; 1806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (j=0; j<PITCH_SUBFRAMES; j++) 1807f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker CQ17 += WebRtcIsacfix_kTransform[k][j] * PitchLagsQ7[j] >> 2; // Q17 1808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ17 = WEBRTC_SPL_SHIFT_W32(CQ17,shft); // Scale with StepSize 1810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* quantize */ 1812a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org tmp16b = (int16_t)((CQ17 + 65536) >> 17); 1813470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index[k] = tmp16b; 1814470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* check that the index is not outside the boundaries of the table */ 1816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (index[k] < lower_limit[k]) index[k] = lower_limit[k]; 1817470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (index[k] > upper_limit[k]) index[k] = upper_limit[k]; 1818470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index[k] -= lower_limit[k]; 1819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Save data for creation of multiple bitstreams */ 1821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(encData != NULL) { 1822470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com encData->pitchIndex[PITCH_SUBFRAMES*encData->startIdx + k] = index[k]; 1823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1826470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* unquantize back to transform coefficients and do the inverse transform: S = T'*C */ 1827470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ11 = (index[0] + lower_limit[0]); // Q0 1828470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ11 = WEBRTC_SPL_SHIFT_W32(CQ11,11-shft); // Scale with StepSize, Q11 1829470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1830470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<PITCH_SUBFRAMES; k++) { 1831470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32a = WEBRTC_SPL_MUL_16_32_RSFT11(WebRtcIsacfix_kTransform[0][k], CQ11); // Q12 1832728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting PitchLagsQ7[k] = (int16_t)(tmp32a >> 5); // Q7. 1833470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1834470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1835470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ10 = mean_val2Q10[index[1]]; 1836470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<PITCH_SUBFRAMES; k++) { 1837f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker tmp32b = WebRtcIsacfix_kTransform[1][k] * (int16_t)CQ10 >> 10; 1838728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting PitchLagsQ7[k] += (int16_t)(tmp32b >> 5); // Q7. 1839470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1840470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1841470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ10 = mean_val4Q10[index[3]]; 1842470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<PITCH_SUBFRAMES; k++) { 1843f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker tmp32b = WebRtcIsacfix_kTransform[3][k] * (int16_t)CQ10 >> 10; 1844728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting PitchLagsQ7[k] += (int16_t)(tmp32b >> 5); // Q7. 1845470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1846470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1847470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy coding of quantization pitch lags */ 1848470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncHistMulti(streamdata, index, cdf, PITCH_SUBFRAMES); 1849470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1850470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */ 1851470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1852470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1853470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1854470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1855470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1856470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* Routines for inband signaling of bandwitdh estimation */ 1857470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* Histograms based on uniform distribution of indices */ 1858470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* Move global variables later! */ 1859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1860470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1861470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* cdf array for frame length indicator */ 18620946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgconst uint16_t kFrameLenCdf[4] = { 1863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 0, 21845, 43690, 65535}; 1864470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1865470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* pointer to cdf array for frame length indicator */ 18660946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgconst uint16_t *kFrameLenCdfPtr[1] = {kFrameLenCdf}; 1867470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1868470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* initial cdf index for decoder of frame length indicator */ 18690946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgconst uint16_t kFrameLenInitIndex[1] = {1}; 1870470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1872470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_DecodeFrameLen(Bitstr_dec *streamdata, 1873dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t *framesamples) 1874470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1875470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int err; 18770946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t frame_mode; 1878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = 0; 1880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy decoding of frame length [1:30ms,2:60ms] */ 1881470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecHistOneStepMulti(&frame_mode, streamdata, kFrameLenCdfPtr, kFrameLenInitIndex, 1); 1882470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (err<0) // error check 1883470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH; 1884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1885470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch(frame_mode) { 1886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case 1: 1887470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *framesamples = 480; /* 30ms */ 1888470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1889470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case 2: 1890470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *framesamples = 960; /* 60ms */ 1891470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1892470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com default: 1893470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = -ISAC_DISALLOWED_FRAME_MODE_DECODER; 1894470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1895470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1896470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return err; 1897470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1898470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1899470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 19000946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint WebRtcIsacfix_EncodeFrameLen(int16_t framesamples, Bitstr_enc *streamdata) { 1901470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1902470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int status; 19030946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t frame_mode; 1904470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1905470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = 0; 1906470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com frame_mode = 0; 1907470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy coding of frame length [1:480 samples,2:960 samples] */ 1908470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch(framesamples) { 1909470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case 480: 1910470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com frame_mode = 1; 1911470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1912470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case 960: 1913470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com frame_mode = 2; 1914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1915470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com default: 1916470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = - ISAC_DISALLOWED_FRAME_MODE_ENCODER; 1917470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1918470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1919470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (status < 0) 1920470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1921470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1922470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncHistMulti(streamdata, &frame_mode, kFrameLenCdfPtr, 1); 1923470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1926470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1927470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* cdf array for estimated bandwidth */ 19280946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgconst uint16_t kBwCdf[25] = { 1929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 0, 2731, 5461, 8192, 10923, 13653, 16384, 19114, 21845, 24576, 27306, 30037, 1930470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 32768, 35498, 38229, 40959, 43690, 46421, 49151, 51882, 54613, 57343, 60074, 1931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 62804, 65535}; 1932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* pointer to cdf array for estimated bandwidth */ 19340946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgconst uint16_t *kBwCdfPtr[1] = {kBwCdf}; 1935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* initial cdf index for decoder of estimated bandwidth*/ 19370946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgconst uint16_t kBwInitIndex[1] = {7}; 1938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 19400946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint WebRtcIsacfix_DecodeSendBandwidth(Bitstr_dec *streamdata, int16_t *BWno) { 1941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int err; 19430946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t BWno32; 1944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy decoding of sender's BW estimation [0..23] */ 1946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecHistOneStepMulti(&BWno32, streamdata, kBwCdfPtr, kBwInitIndex, 1); 1947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (err<0) // error check 1948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -ISAC_RANGE_ERROR_DECODE_BANDWIDTH; 19490946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org *BWno = (int16_t)BWno32; 1950470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return err; 1951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1952470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1953470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 19550946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint WebRtcIsacfix_EncodeReceiveBandwidth(int16_t *BWno, Bitstr_enc *streamdata) 1956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int status = 0; 1958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy encoding of receiver's BW estimation [0..23] */ 1959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncHistMulti(streamdata, BWno, kBwCdfPtr, 1); 1960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1963470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* estimate codel length of LPC Coef */ 19650946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgvoid WebRtcIsacfix_TranscodeLpcCoef(int32_t *gain_lo_hiQ17, 19660946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *index_gQQ) { 196723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int j, k; 19680946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t posQQ, pos2QQ; 19690946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t posg, offsg, gainpos; 19700946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t tmpcoeffs_gQ6[KLT_ORDER_GAIN]; 19710946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t tmpcoeffs_gQ17[KLT_ORDER_GAIN]; 19720946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t tmpcoeffs2_gQ21[KLT_ORDER_GAIN]; 19730946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t sumQQ; 1974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* log gains, mean removal and scaling */ 197723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org posg = 0; gainpos=0; 1978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<SUBFRAMES; k++) { 1980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* log gains */ 1981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* The input argument X to logN(X) is 2^17 times higher than the 1983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com input floating point argument Y to log(Y), since the X value 1984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com is a Q17 value. This can be compensated for after the call, by 1985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subraction a value Z for each Q-step. One Q-step means that 1986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com X gets 2 times higher, i.e. Z = logN(2)*256 = 0.693147180559*256 = 1987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 177.445678 should be subtracted (since logN() returns a Q8 value). 1988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com For a X value in Q17, the value 177.445678*17 = 3017 should be 1989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subtracted */ 1990470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 1991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 1992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; gainpos++; 1993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 1995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 1996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; gainpos++; 1997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* KLT */ 2002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* left transform */ 2004cf8e1081584a3e766a55b2eadf337090047ff14akma@webrtc.org for (j = 0, offsg = 0; j < SUBFRAMES; j++, offsg += 2) { 2005e5a81ed7939f7c530028b583fabfd54ceeb8a6f2kma@webrtc.org // Q21 = Q6 * Q15 2006bc2bb34419021fb3be4f87eb062cf0a9ed52675abjornv@webrtc.org sumQQ = tmpcoeffs_gQ6[offsg] * WebRtcIsacfix_kT1GainQ15[0][0] + 2007bc2bb34419021fb3be4f87eb062cf0a9ed52675abjornv@webrtc.org tmpcoeffs_gQ6[offsg + 1] * WebRtcIsacfix_kT1GainQ15[0][2]; 2008e5a81ed7939f7c530028b583fabfd54ceeb8a6f2kma@webrtc.org tmpcoeffs2_gQ21[offsg] = sumQQ; 2009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2010e5a81ed7939f7c530028b583fabfd54ceeb8a6f2kma@webrtc.org // Q21 = Q6 * Q15 2011bc2bb34419021fb3be4f87eb062cf0a9ed52675abjornv@webrtc.org sumQQ = tmpcoeffs_gQ6[offsg] * WebRtcIsacfix_kT1GainQ15[0][1] + 2012bc2bb34419021fb3be4f87eb062cf0a9ed52675abjornv@webrtc.org tmpcoeffs_gQ6[offsg + 1] * WebRtcIsacfix_kT1GainQ15[0][3]; 2013e5a81ed7939f7c530028b583fabfd54ceeb8a6f2kma@webrtc.org tmpcoeffs2_gQ21[offsg + 1] = sumQQ; 2014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* right transform */ 201723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21, 201823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_gQ17, kTIndexFactor3, kTIndexStep1); 2019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* quantize coefficients */ 2021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok? 2022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posQQ = WebRtcIsacfix_kSelIndGain[k]; 20240946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org pos2QQ= (int16_t)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17); 2025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok? 2027470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (index_gQQ[k] < 0) { 2028470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_gQQ[k] = 0; 2029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) { 2031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k]; 2032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2035