entropy_coding.c revision 23da8622c04ac843f7912dd33b4ad55f41422119
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 68470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FLP: (WebRtc_Word32)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*/ 74470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comstatic __inline WebRtc_Word32 CalcLrIntQ(WebRtc_Word32 fixVal, WebRtc_Word16 qDomain) { 75470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 intgr; 76470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 roundVal; 77470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 78470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com roundVal = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, qDomain-1); 79470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com intgr = WEBRTC_SPL_RSHIFT_W32(fixVal+roundVal, qDomain); 80470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 81470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return intgr; 82470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 83470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 84470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 85470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com __inline WebRtc_UWord32 stepwise(WebRtc_Word32 dinQ10) { 86470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 87470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 ind, diQ10, dtQ10; 88470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 89470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com diQ10 = dinQ10; 90470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (diQ10 < DPMIN_Q10) 91470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com diQ10 = DPMIN_Q10; 92470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (diQ10 >= DPMAX_Q10) 93470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com diQ10 = DPMAX_Q10 - 1; 94470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 95470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com dtQ10 = diQ10 - DPMIN_Q10;*/ /* Q10 + Q10 = Q10 */ 96470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* ind = (dtQ10 * 5) >> 10; */ /* 2^10 / 5 = 0.2 in Q10 */ 97470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* Q10 -> Q0 */ 98470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 99470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* return rpointsFIX_Q10[ind]; 100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com*/ 103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* logN(x) = logN(2)*log2(x) = 0.6931*log2(x). Output in Q8. */ 105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* The input argument X to logN(X) is 2^17 times higher than the 106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com input floating point argument Y to log(Y), since the X value 107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com is a Q17 value. This can be compensated for after the call, by 108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subraction a value Z for each Q-step. One Q-step means that 109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com X gets 2 thimes higher, i.e. Z = logN(2)*256 = 0.693147180559*256 = 110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 177.445678 should be subtracted (since logN() returns a Q8 value). 111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com For a X value in Q17, the value 177.445678*17 = 3017 should be 112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subtracted */ 113470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comstatic WebRtc_Word16 CalcLogN(WebRtc_Word32 arg) { 114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 zeros, log2, frac, logN; 115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com zeros=WebRtcSpl_NormU32(arg); 117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com frac=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(WEBRTC_SPL_LSHIFT_W32(arg, zeros)&0x7FFFFFFF, 23); 118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com log2=(WebRtc_Word16)(WEBRTC_SPL_LSHIFT_W32(31-zeros, 8)+frac); // log2(x) in Q8 119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com logN=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(log2,22713,15); //Q8*Q15 log(2) = 0.693147 = 22713 in Q15 120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com logN=logN+11; //Scalar compensation which minimizes the (log(x)-logN(x))^2 error over all x. 121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return logN; 123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com expN(x) = 2^(a*x), where a = log2(e) ~= 1.442695 128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Input: Q8 (WebRtc_Word16) 130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Output: Q17 (WebRtc_Word32) 131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com a = log2(e) = log2(exp(1)) ~= 1.442695 ==> a = 23637 in Q14 (1.442688) 133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com To this value, 700 is added or subtracted in order to get an average error 134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nearer zero, instead of always same-sign. 135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com*/ 136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comstatic WebRtc_Word32 CalcExpN(WebRtc_Word16 x) { 138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 ax, axINT, axFRAC; 139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 exp16; 140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 exp; 141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (x>=0) { 143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // ax=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637-700, 14); //Q8 144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ax=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637, 14); //Q8 145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com axINT = WEBRTC_SPL_RSHIFT_W16(ax, 8); //Q0 146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com axFRAC = ax&0x00FF; 147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com exp16 = WEBRTC_SPL_LSHIFT_W32(1, axINT); //Q0 148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com axFRAC = axFRAC+256; //Q8 149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com exp = WEBRTC_SPL_MUL_16_16(exp16, axFRAC); // Q0*Q8 = Q8 150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com exp = WEBRTC_SPL_LSHIFT_W32(exp, 9); //Q17 151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // ax=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637+700, 14); //Q8 153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ax=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637, 14); //Q8 154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ax = -ax; 155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com axINT = 1 + WEBRTC_SPL_RSHIFT_W16(ax, 8); //Q0 156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com axFRAC = 0x00FF - (ax&0x00FF); 157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com exp16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(32768, axINT); //Q15 158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com axFRAC = axFRAC+256; //Q8 159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com exp = WEBRTC_SPL_MUL_16_16(exp16, axFRAC); // Q15*Q8 = Q23 160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com exp = WEBRTC_SPL_RSHIFT_W32(exp, 6); //Q17 161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return exp; 164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* compute correlation from power spectrum */ 168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comstatic void CalcCorrelation(WebRtc_Word32 *PSpecQ12, WebRtc_Word32 *CorrQ7) 169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 summ[FRAMESAMPLES/8]; 171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 diff[FRAMESAMPLES/8]; 172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 sum; 173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k, n; 174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < FRAMESAMPLES/8; k++) { 176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com summ[k] = WEBRTC_SPL_RSHIFT_W32(PSpecQ12[k] + PSpecQ12[FRAMESAMPLES/4-1 - k] + 16, 5); 177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com diff[k] = WEBRTC_SPL_RSHIFT_W32(PSpecQ12[k] - PSpecQ12[FRAMESAMPLES/4-1 - k] + 16, 5); 178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = 2; 181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum += summ[n]; 183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CorrQ7[0] = sum; 184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < AR_ORDER; k += 2) { 186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = 0; 187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], diff[n]) + 256, 9); 189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CorrQ7[k+1] = sum; 190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=1; k<AR_ORDER; k+=2) { 193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = 0; 194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], summ[n]) + 256, 9); 196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CorrQ7[k+1] = sum; 197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* compute inverse AR power spectrum */ 202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comstatic void CalcInvArSpec(const WebRtc_Word16 *ARCoefQ12, 203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_Word32 gainQ10, 204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 *CurveQ16) 205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 CorrQ11[AR_ORDER+1]; 207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 sum, tmpGain; 208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 diffQ16[FRAMESAMPLES/8]; 209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_Word16 *CS_ptrQ9; 210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k, n; 211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 round, shftVal = 0, sh; 212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = 0; 214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < AR_ORDER+1; n++) 215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]); /* Q24 */ 216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(sum, 6), 65) + 32768, 16); /* result in Q8 */ 217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CorrQ11[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, gainQ10) + 256, 9); 218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* To avoid overflow, we shift down gainQ10 if it is large. We will not lose any precision */ 220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(gainQ10>400000){ 221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3); 222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com round = 32; 223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shftVal = 6; 224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpGain = gainQ10; 226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com round = 256; 227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shftVal = 9; 228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 1; k < AR_ORDER+1; k++) { 231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = 16384; 232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = k; n < AR_ORDER+1; n++) 233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum += WEBRTC_SPL_MUL(ARCoefQ12[n-k], ARCoefQ12[n]); /* Q24 */ 234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = WEBRTC_SPL_RSHIFT_W32(sum, 15); 235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CorrQ11[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, tmpGain) + round, shftVal); 236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7); 238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CurveQ16[n] = sum; 240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 1; k < AR_ORDER; k += 2) { 242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CurveQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], CorrQ11[k+1]) + 2, 2); 244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CS_ptrQ9 = WebRtcIsacfix_kCos[0]; 247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* If CorrQ11[1] too large we avoid getting overflow in the calculation by shifting */ 249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sh=WebRtcSpl_NormW32(CorrQ11[1]); 250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (CorrQ11[1]==0) /* Use next correlation */ 251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sh=WebRtcSpl_NormW32(CorrQ11[2]); 252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (sh<9) 254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shftVal = 9 - sh; 255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shftVal = 0; 257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com diffQ16[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[1], shftVal)) + 2, 2); 260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 2; k < AR_ORDER; k += 2) { 261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CS_ptrQ9 = WebRtcIsacfix_kCos[k]; 262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com diffQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[k+1], shftVal)) + 2, 2); 264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<FRAMESAMPLES/8; k++) { 267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CurveQ16[FRAMESAMPLES/4-1 - k] = CurveQ16[k] - WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal); 268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CurveQ16[k] += WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal); 269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comstatic void CalcRootInvArSpec(const WebRtc_Word16 *ARCoefQ12, 273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_Word32 gainQ10, 274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 *CurveQ8) 275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 CorrQ11[AR_ORDER+1]; 277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 sum, tmpGain; 278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 summQ16[FRAMESAMPLES/8]; 279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 diffQ16[FRAMESAMPLES/8]; 280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_Word16 *CS_ptrQ9; 282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k, n, i; 283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 round, shftVal = 0, sh; 284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 res, in_sqrt, newRes; 285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = 0; 287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < AR_ORDER+1; n++) 288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]); /* Q24 */ 289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(sum, 6), 65) + 32768, 16); /* result in Q8 */ 290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CorrQ11[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, gainQ10) + 256, 9); 291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* To avoid overflow, we shift down gainQ10 if it is large. We will not lose any precision */ 293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(gainQ10>400000){ 294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3); 295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com round = 32; 296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shftVal = 6; 297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpGain = gainQ10; 299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com round = 256; 300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shftVal = 9; 301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 1; k < AR_ORDER+1; k++) { 304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = 16384; 305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = k; n < AR_ORDER+1; n++) 306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum += WEBRTC_SPL_MUL(ARCoefQ12[n-k], ARCoefQ12[n]); /* Q24 */ 307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = WEBRTC_SPL_RSHIFT_W32(sum, 15); 308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CorrQ11[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, tmpGain) + round, shftVal); 309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7); 311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com summQ16[n] = sum; 313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 1; k < (AR_ORDER); k += 2) { 315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com summQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_32_16(CorrQ11[k+1],WebRtcIsacfix_kCos[k][n]) + 2, 2); 317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CS_ptrQ9 = WebRtcIsacfix_kCos[0]; 320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* If CorrQ11[1] too large we avoid getting overflow in the calculation by shifting */ 322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sh=WebRtcSpl_NormW32(CorrQ11[1]); 323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (CorrQ11[1]==0) /* Use next correlation */ 324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sh=WebRtcSpl_NormW32(CorrQ11[2]); 325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (sh<9) 327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shftVal = 9 - sh; 328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shftVal = 0; 330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com diffQ16[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[1], shftVal)) + 2, 2); 333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 2; k < AR_ORDER; k += 2) { 334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CS_ptrQ9 = WebRtcIsacfix_kCos[k]; 335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < FRAMESAMPLES/8; n++) 336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com diffQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[k+1], shftVal)) + 2, 2); 337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com in_sqrt = summQ16[0] + WEBRTC_SPL_LSHIFT_W32(diffQ16[0], shftVal); 340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* convert to magnitude spectrum, by doing square-roots (modified from SPLIB) */ 342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com res = WEBRTC_SPL_LSHIFT_W32(1, WEBRTC_SPL_RSHIFT_W16(WebRtcSpl_GetSizeInBits(in_sqrt), 1)); 343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < FRAMESAMPLES/8; k++) 345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com in_sqrt = summQ16[k] + WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal); 347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com i = 10; 348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* make in_sqrt positive to prohibit sqrt of negative values */ 350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(in_sqrt<0) 351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com in_sqrt=-in_sqrt; 352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(in_sqrt, res) + res, 1); 354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com do 355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com res = newRes; 357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(in_sqrt, res) + res, 1); 358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } while (newRes != res && i-- > 0); 359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CurveQ8[k] = (WebRtc_Word16)newRes; 361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = FRAMESAMPLES/8; k < FRAMESAMPLES/4; k++) { 363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com in_sqrt = summQ16[FRAMESAMPLES/4-1 - k] - WEBRTC_SPL_LSHIFT_W32(diffQ16[FRAMESAMPLES/4-1 - k], shftVal); 365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com i = 10; 366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* make in_sqrt positive to prohibit sqrt of negative values */ 368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(in_sqrt<0) 369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com in_sqrt=-in_sqrt; 370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(in_sqrt, res) + res, 1); 372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com do 373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com res = newRes; 375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(in_sqrt, res) + res, 1); 376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } while (newRes != res && i-- > 0); 377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CurveQ8[k] = (WebRtc_Word16)newRes; 379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* generate array of dither samples in Q7 */ 386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comstatic void GenerateDitherQ7(WebRtc_Word16 *bufQ7, 387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 seed, 388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 length, 389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 AvgPitchGain_Q12) 390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k; 392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 dither1_Q7, dither2_Q7, dither_gain_Q14, shft; 393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (AvgPitchGain_Q12 < 614) /* this threshold should be equal to that in decode_spec() */ 395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < length-2; k += 3) 397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* new random unsigned WebRtc_Word32 */ 399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515; 400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* fixed-point dither sample between -64 and 64 (Q7) */ 402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com dither1_Q7 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)seed + 16777216, 25); // * 128/4294967295 403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* new random unsigned WebRtc_Word32 */ 405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515; 406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* fixed-point dither sample between -64 and 64 */ 408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com dither2_Q7 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(seed + 16777216, 25); 409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shft = (WebRtc_Word16)(WEBRTC_SPL_RSHIFT_U32(seed, 25) & 15); 411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (shft < 5) 412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k] = dither1_Q7; 414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k+1] = dither2_Q7; 415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k+2] = 0; 416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (shft < 10) 418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k] = dither1_Q7; 420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k+1] = 0; 421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k+2] = dither2_Q7; 422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k] = 0; 426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k+1] = dither1_Q7; 427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k+2] = dither2_Q7; 428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com dither_gain_Q14 = (WebRtc_Word16)(22528 - WEBRTC_SPL_MUL(10, AvgPitchGain_Q12)); 434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* dither on half of the coefficients */ 436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < length-1; k += 2) 437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* new random unsigned WebRtc_Word32 */ 439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515; 440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* fixed-point dither sample between -64 and 64 */ 442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com dither1_Q7 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)seed + 16777216, 25); 443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* dither sample is placed in either even or odd index */ 445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shft = (WebRtc_Word16)(WEBRTC_SPL_RSHIFT_U32(seed, 25) & 1); /* either 0 or 1 */ 446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k + shft] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(dither_gain_Q14, dither1_Q7) + 8192, 14); 448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufQ7[k + 1 - shft] = 0; 449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * function to decode the complex spectrum from the bitstream 458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * returns the total number of bytes in the stream 459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word16 WebRtcIsacfix_DecodeSpec(Bitstr_dec *streamdata, 461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 *frQ7, 462470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 *fiQ7, 463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 AvgPitchGain_Q12) 464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 data[FRAMESAMPLES]; 466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 invARSpec2_Q16[FRAMESAMPLES/4]; 467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 ARCoefQ12[AR_ORDER+1]; 468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 RCQ15[AR_ORDER]; 469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 gainQ10; 470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 gain2_Q10; 471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 len; 472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k; 473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* create dither signal */ 475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com GenerateDitherQ7(data, streamdata->W_upper, FRAMESAMPLES, AvgPitchGain_Q12); /* Dither is output in vector 'Data' */ 476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* decode model parameters */ 478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (WebRtcIsacfix_DecodeRcCoef(streamdata, RCQ15) < 0) 479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; 480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); 483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (WebRtcIsacfix_DecodeGain2(streamdata, &gain2_Q10) < 0) 485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; 486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* compute inverse AR power spectrum */ 488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CalcInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); 489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* arithmetic decoding of spectrum */ 491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* 'data' input and output. Input = Dither */ 492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com len = WebRtcIsacfix_DecLogisticMulti2(data, streamdata, invARSpec2_Q16, (WebRtc_Word16)FRAMESAMPLES); 493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (len<1) 495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; 496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* subtract dither and scale down spectral samples with low SNR */ 498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (AvgPitchGain_Q12 <= 614) 499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < FRAMESAMPLES; k += 4) 501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gainQ10 = WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)30, 10), 503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(invARSpec2_Q16[k>>2] + (WebRtc_UWord32)2195456, 16)); 504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *frQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[ k ], gainQ10) + 512, 10); 505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *fiQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+1], gainQ10) + 512, 10); 506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *frQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+2], gainQ10) + 512, 10); 507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *fiQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+3], gainQ10) + 512, 10); 508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < FRAMESAMPLES; k += 4) 513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gainQ10 = WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)36, 10), 515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(invARSpec2_Q16[k>>2] + (WebRtc_UWord32)2654208, 16)); 516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *frQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[ k ], gainQ10) + 512, 10); 517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *fiQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+1], gainQ10) + 512, 10); 518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *frQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+2], gainQ10) + 512, 10); 519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *fiQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+3], gainQ10) + 512, 10); 520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return len; 524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_EncodeSpec(const WebRtc_Word16 *fr, 528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_Word16 *fi, 529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Bitstr_enc *streamdata, 530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 AvgPitchGain_Q12) 531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 dataQ7[FRAMESAMPLES]; 533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 PSpec[FRAMESAMPLES/4]; 534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 invARSpecQ8[FRAMESAMPLES/4]; 535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 CorrQ7[AR_ORDER+1]; 536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 CorrQ7_norm[AR_ORDER+1]; 537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 RCQ15[AR_ORDER]; 538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 ARCoefQ12[AR_ORDER+1]; 539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 gain2_Q10; 540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 val; 541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 nrg; 542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 sum; 543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 lft_shft; 544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 status; 545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k, n, j; 546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* create dither_float signal */ 549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com GenerateDitherQ7(dataQ7, streamdata->W_upper, FRAMESAMPLES, AvgPitchGain_Q12); 550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* add dither and quantize, and compute power spectrum */ 552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Vector dataQ7 contains Dither in Q7 */ 553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < FRAMESAMPLES; k += 4) 554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com val = ((*fr++ + dataQ7[k] + 64) & 0xFF80) - dataQ7[k]; /* Data = Dither */ 556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com dataQ7[k] = val; /* New value in Data */ 557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum = WEBRTC_SPL_UMUL(val, val); 558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com val = ((*fi++ + dataQ7[k+1] + 64) & 0xFF80) - dataQ7[k+1]; /* Data = Dither */ 560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com dataQ7[k+1] = val; /* New value in Data */ 561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum += WEBRTC_SPL_UMUL(val, val); 562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com val = ((*fr++ + dataQ7[k+2] + 64) & 0xFF80) - dataQ7[k+2]; /* Data = Dither */ 564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com dataQ7[k+2] = val; /* New value in Data */ 565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum += WEBRTC_SPL_UMUL(val, val); 566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com val = ((*fi++ + dataQ7[k+3] + 64) & 0xFF80) - dataQ7[k+3]; /* Data = Dither */ 568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com dataQ7[k+3] = val; /* New value in Data */ 569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sum += WEBRTC_SPL_UMUL(val, val); 570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PSpec[k>>2] = WEBRTC_SPL_RSHIFT_U32(sum, 2); 572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* compute correlation from power spectrum */ 575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CalcCorrelation(PSpec, CorrQ7); 576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find AR coefficients */ 579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* number of bit shifts to 14-bit normalize CorrQ7[0] (leaving room for sign) */ 580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lft_shft = WebRtcSpl_NormW32(CorrQ7[0]) - 18; 581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (lft_shft > 0) { 583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<AR_ORDER+1; k++) 584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CorrQ7_norm[k] = WEBRTC_SPL_LSHIFT_W32(CorrQ7[k], lft_shft); 585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<AR_ORDER+1; k++) 587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CorrQ7_norm[k] = WEBRTC_SPL_RSHIFT_W32(CorrQ7[k], -lft_shft); 588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find RC coefficients */ 591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcSpl_AutoCorrToReflCoef(CorrQ7_norm, AR_ORDER, RCQ15); 592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* quantize & code RC Coef */ 594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncodeRcCoef(RCQ15, streamdata); 595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (status < 0) { 596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* RC -> AR coefficients */ 600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); 601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* compute ARCoef' * Corr * ARCoef in Q19 */ 603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nrg = 0; 604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (j = 0; j <= AR_ORDER; j++) { 605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n <= j; n++) 606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nrg += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(ARCoefQ12[j], WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CorrQ7_norm[j-n], ARCoefQ12[n]) + 256, 9)) + 4, 3); 607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = j+1; n <= AR_ORDER; n++) 608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nrg += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(ARCoefQ12[j], WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CorrQ7_norm[n-j], ARCoefQ12[n]) + 256, 9)) + 4, 3); 609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (lft_shft > 0) 612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nrg = WEBRTC_SPL_RSHIFT_W32(nrg, lft_shft); 613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nrg = WEBRTC_SPL_LSHIFT_W32(nrg, -lft_shft); 615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(nrg>131072) 617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES >> 2, nrg); /* also shifts 31 bits to the left! */ 618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gain2_Q10 = WEBRTC_SPL_RSHIFT_W32(FRAMESAMPLES, 2); 620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* quantize & code gain2_Q10 */ 622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (WebRtcIsacfix_EncodeGain2(&gain2_Q10, streamdata)) 623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* compute inverse AR magnitude spectrum */ 626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CalcRootInvArSpec(ARCoefQ12, gain2_Q10, invARSpecQ8); 627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* arithmetic coding of spectrum */ 630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncLogisticMulti2(streamdata, dataQ7, invARSpecQ8, (WebRtc_Word16)FRAMESAMPLES); 631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ( status ) 632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return( status ); 633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* Matlab's LAR definition */ 639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comstatic void Rc2LarFix(const WebRtc_Word16 *rcQ15, WebRtc_Word32 *larQ17, WebRtc_Word16 order) { 640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* 642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com This is a piece-wise implemenetation of a rc2lar-function (all values in the comment 644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com are Q15 values and are based on [0 24956/32768 30000/32768 32500/32768], i.e. 645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com [0.76159667968750 0.91552734375000 0.99182128906250] 646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com x0 x1 a k x0(again) b 648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ================================================================================== 649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 0.00 0.76: 0 2.625997508581 0 0 650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 0.76 0.91: 2.000012018559 7.284502668663 0.761596679688 -3.547841027073 651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 0.91 0.99: 3.121320351712 31.115835041229 0.915527343750 -25.366077452148 652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 0.99 1.00: 5.495270168700 686.663805654056 0.991821289063 -675.552510708011 653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com The implementation is y(x)= a + (x-x0)*k, but this can be simplified to 655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com y(x) = a-x0*k + x*k = b + x*k, where b = a-x0*k 657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com akx=[0 2.625997508581 0 659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2.000012018559 7.284502668663 0.761596679688 660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3.121320351712 31.115835041229 0.915527343750 661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5.495270168700 686.663805654056 0.991821289063]; 662470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com b = akx(:,1) - akx(:,3).*akx(:,2) 664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com [ 0.0 666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com -3.547841027073 667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com -25.366077452148 668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com -675.552510708011] 669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k; 673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 rc; 674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 larAbsQ17; 675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < order; k++) { 677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rc = WEBRTC_SPL_ABS_W16(rcQ15[k]); //Q15 679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Calculate larAbsQ17 in Q17 from rc in Q15 */ 681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (rc<24956) { //0.7615966 in Q15 683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (Q15*Q13)>>11 = Q17 684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com larAbsQ17 = WEBRTC_SPL_MUL_16_16_RSFT(rc, 21512, 11); 685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else if (rc<30000) { //0.91552734375 in Q15 686470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Q17 + (Q15*Q12)>>10 = Q17 687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com larAbsQ17 = -465024 + WEBRTC_SPL_MUL_16_16_RSFT(rc, 29837, 10); 688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else if (rc<32500) { //0.99182128906250 in Q15 689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Q17 + (Q15*Q10)>>8 = Q17 690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com larAbsQ17 = -3324784 + WEBRTC_SPL_MUL_16_16_RSFT(rc, 31863, 8); 691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Q17 + (Q15*Q5)>>3 = Q17 693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com larAbsQ17 = -88546020 + WEBRTC_SPL_MUL_16_16_RSFT(rc, 21973, 3); 694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (rcQ15[k]>0) { 697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com larQ17[k] = larAbsQ17; 698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com larQ17[k] = -larAbsQ17; 700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comstatic void Lar2RcFix(const WebRtc_Word32 *larQ17, WebRtc_Word16 *rcQ15, WebRtc_Word16 order) { 706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* 708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com This is a piece-wise implemenetation of a lar2rc-function 709470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com See comment in Rc2LarFix() about details. 710470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k; 713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 larAbsQ11; 714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 rc; 715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < order; k++) { 717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com larAbsQ11 = (WebRtc_Word16) WEBRTC_SPL_ABS_W32(WEBRTC_SPL_RSHIFT_W32(larQ17[k]+32,6)); //Q11 719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (larAbsQ11<4097) { //2.000012018559 in Q11 721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Q11*Q16>>12 = Q15 722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rc = WEBRTC_SPL_MUL_16_16_RSFT(larAbsQ11, 24957, 12); 723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else if (larAbsQ11<6393) { //3.121320351712 in Q11 724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (Q11*Q17 + Q13)>>13 = Q15 725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rc = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(larAbsQ11, 17993) + 130738688), 13); 726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else if (larAbsQ11<11255) { //5.495270168700 in Q11 727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (Q11*Q19 + Q30)>>15 = Q15 728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rc = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(larAbsQ11, 16850) + 875329820), 15); 729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (Q11*Q24>>16 + Q19)>>4 = Q15 731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rc = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16_RSFT(larAbsQ11, 24433, 16)) + 515804), 4); 732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (larQ17[k]<=0) { 735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rc = -rc; 736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rcQ15[k] = (WebRtc_Word16) rc; // Q15 739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comstatic void Poly2LarFix(WebRtc_Word16 *lowbandQ15, 743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 orderLo, 744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 *hibandQ15, 745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 orderHi, 746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 Nsub, 747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 *larsQ17) { 748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k, n; 750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 *outpQ17; 751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 orderTot; 752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 larQ17[MAX_ORDER]; // Size 7+6 is enough 753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com orderTot = (orderLo + orderHi); 755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com outpQ17 = larsQ17; 756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < Nsub; k++) { 757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Rc2LarFix(lowbandQ15, larQ17, orderLo); 759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < orderLo; n++) 761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com outpQ17[n] = larQ17[n]; //Q17 762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Rc2LarFix(hibandQ15, larQ17, orderHi); 764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < orderHi; n++) 766470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com outpQ17[n + orderLo] = larQ17[n]; //Q17; 767470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com outpQ17 += orderTot; 769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lowbandQ15 += orderLo; 770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com hibandQ15 += orderHi; 771470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 772470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 773470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comstatic void Lar2polyFix(WebRtc_Word32 *larsQ17, 776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 *lowbandQ15, 777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 orderLo, 778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 *hibandQ15, 779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 orderHi, 780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 Nsub) { 781470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 782470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k, n; 783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 orderTot; 784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 *outplQ15, *outphQ15; 785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 *inpQ17; 786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 rcQ15[7+6]; 787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com orderTot = (orderLo + orderHi); 789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com outplQ15 = lowbandQ15; 790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com outphQ15 = hibandQ15; 791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com inpQ17 = larsQ17; 792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < Nsub; k++) { 793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* gains not handled here as in the FLP version */ 795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Low band */ 797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Lar2RcFix(&inpQ17[0], rcQ15, orderLo); 798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < orderLo; n++) 799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com outplQ15[n] = rcQ15[n]; // Refl. coeffs 800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* High band */ 802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Lar2RcFix(&inpQ17[orderLo], rcQ15, orderHi); 803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n = 0; n < orderHi; n++) 804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com outphQ15[n] = rcQ15[n]; // Refl. coeffs 805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com inpQ17 += orderTot; 807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com outplQ15 += orderLo; 808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com outphQ15 += orderHi; 809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 81223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org/* 81323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgFunction WebRtcIsacfix_MatrixProduct1C() does one form of matrix multiplication. 81423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgIt first shifts input data of one matrix, determines the right indexes for the 81523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgtwo matrixes, multiply them, and write the results into an output buffer. 81623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 81723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgNote that two factors (or, multipliers) determine the initialization values of 81823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgthe variable |matrix1_index| in the code. The relationship is 81923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org|matrix1_index| = |matrix1_index_factor1| * |matrix1_index_factor2|, where 82023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org|matrix1_index_factor1| is given by the argument while |matrix1_index_factor2| 82123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgis determined by the value of argument |matrix1_index_init_case|; 82223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org|matrix1_index_factor2| is the value of the outmost loop counter j (when 82323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org|matrix1_index_init_case| is 0), or the value of the middle loop counter k (when 82423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org|matrix1_index_init_case| is non-zero). 82523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 82623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org|matrix0_index| is determined the same way. 82723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 82823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgArguments: 82923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0[]: matrix0 data in Q15 domain. 83023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1[]: matrix1 data. 83123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix_product[]: output data (matrix product). 83223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1_index_factor1: The first of two factors determining the 83323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org initialization value of matrix1_index. 83423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0_index_factor1: The first of two factors determining the 83523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org initialization value of matrix0_index. 83623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1_index_init_case: Case number for selecting the second of two 83723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org factors determining the initialization value 83823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org of matrix1_index and matrix0_index. 83923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1_index_step: Incremental step for matrix1_index. 84023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0_index_step: Incremental step for matrix0_index. 84123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org inner_loop_count: Maximum count of the inner loop. 84223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org mid_loop_count: Maximum count of the intermediate loop. 84323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org shift: Left shift value for matrix1. 84423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org*/ 84523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgvoid WebRtcIsacfix_MatrixProduct1C(const int16_t matrix0[], 84623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int32_t matrix1[], 84723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int32_t matrix_product[], 84823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int matrix1_index_factor1, 84923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int matrix0_index_factor1, 85023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int matrix1_index_init_case, 85123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int matrix1_index_step, 85223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int matrix0_index_step, 85323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int inner_loop_count, 85423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int mid_loop_count, 85523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int shift) { 85623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int j = 0, k = 0, n = 0; 85723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int matrix0_index = 0, matrix1_index = 0, matrix_prod_index = 0; 85823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int* matrix0_index_factor2 = &k; 85923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int* matrix1_index_factor2 = &j; 86023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org if (matrix1_index_init_case != 0) { 86123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0_index_factor2 = &j; 86223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1_index_factor2 = &k; 86323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org } 86423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 86523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org for (j = 0; j < SUBFRAMES; j++) { 86623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix_prod_index = mid_loop_count * j; 86723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org for (k = 0; k < mid_loop_count; k++) { 86823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int32_t sum32 = 0; 86923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0_index = matrix0_index_factor1 * (*matrix0_index_factor2); 87023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1_index = matrix1_index_factor1 * (*matrix1_index_factor2); 87123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org for (n = 0; n < inner_loop_count; n++) { 87223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sum32 += (WEBRTC_SPL_MUL_16_32_RSFT16(matrix0[matrix0_index], 87323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1[matrix1_index] << shift)); 87423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0_index += matrix0_index_step; 87523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1_index += matrix1_index_step; 87623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org } 87723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix_product[matrix_prod_index] = sum32; 87823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix_prod_index++; 87923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org } 88023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org } 88123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org} 88223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 88323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org/* 88423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgFunction WebRtcIsacfix_MatrixProduct2C() returns the product of two matrixes, 88523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgone of which has two columns. It first has to determine the correct index of 88623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgthe first matrix before doing the actual element multiplication. 88723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 88823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgArguments: 88923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0[]: A matrix in Q15 domain. 89023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1[]: A matrix in Q21 domain. 89123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix_product[]: Output data in Q17 domain. 89223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0_index_factor: A factor determining the initialization value 89323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org of matrix0_index. 89423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0_index_step: Incremental step for matrix0_index. 89523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org*/ 89623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgvoid WebRtcIsacfix_MatrixProduct2C(const int16_t matrix0[], 89723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int32_t matrix1[], 89823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int32_t matrix_product[], 89923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int matrix0_index_factor, 90023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org const int matrix0_index_step) { 90123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int j = 0, n = 0; 90223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int matrix1_index = 0, matrix0_index = 0, matrix_prod_index = 0; 90323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org for (j = 0; j < SUBFRAMES; j++) { 90423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int32_t sum32 = 0, sum32_2 = 0; 90523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1_index = 0; 90623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0_index = matrix0_index_factor * j; 90723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org for (n = SUBFRAMES; n > 0; n--) { 90823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sum32 += (WEBRTC_SPL_MUL_16_32_RSFT16(matrix0[matrix0_index], 90923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1[matrix1_index])); 91023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sum32_2 += (WEBRTC_SPL_MUL_16_32_RSFT16(matrix0[matrix0_index], 91123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1[matrix1_index + 1])); 91223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix1_index += 2; 91323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix0_index += matrix0_index_step; 91423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org } 91523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix_product[matrix_prod_index] = sum32 >> 3; 91623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix_product[matrix_prod_index + 1] = sum32_2 >> 3; 91723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org matrix_prod_index += 2; 91823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org } 91923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org} 92023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 921470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_DecodeLpc(WebRtc_Word32 *gain_lo_hiQ17, 922470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 *LPCCoef_loQ15, 923470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 *LPCCoef_hiQ15, 924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Bitstr_dec *streamdata, 925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 *outmodel) { 926470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 927470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 larsQ17[KLT_ORDER_SHAPE]; // KLT_ORDER_GAIN+KLT_ORDER_SHAPE == (ORDERLO+ORDERHI)*SUBFRAMES 928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int err; 929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 930470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecodeLpcCoef(streamdata, larsQ17, gain_lo_hiQ17, outmodel); 931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (err<0) // error check 932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -ISAC_RANGE_ERROR_DECODE_LPC; 933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Lar2polyFix(larsQ17, LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES); 935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 937470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* decode & dequantize LPC Coef */ 940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_DecodeLpcCoef(Bitstr_dec *streamdata, 941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 *LPCCoefQ17, 942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 *gain_lo_hiQ17, 943470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 *outmodel) 944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int j, k, n; 946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int err; 94723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtc_Word16 pos, pos2, posg, poss; 948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 gainpos; 949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 model; 950470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 index_QQ[KLT_ORDER_SHAPE]; 951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 tmpcoeffs_gQ17[KLT_ORDER_GAIN]; 952470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 tmpcoeffs2_gQ21[KLT_ORDER_GAIN]; 953470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 tmpcoeffs_sQ10[KLT_ORDER_SHAPE]; 954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 tmpcoeffs_sQ17[KLT_ORDER_SHAPE]; 955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 tmpcoeffs2_sQ18[KLT_ORDER_SHAPE]; 956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 sumQQ; 957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 sumQQ16; 958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 tmp32; 959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy decoding of model number */ 963470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecHistOneStepMulti(&model, streamdata, WebRtcIsacfix_kModelCdfPtr, WebRtcIsacfix_kModelInitIndex, 1); 964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (err<0) // error check 965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return err; 966470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 967470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy decoding of quantization indices */ 968470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecHistOneStepMulti(index_QQ, streamdata, WebRtcIsacfix_kCdfShapePtr[model], WebRtcIsacfix_kInitIndexShape[model], KLT_ORDER_SHAPE); 969470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (err<0) // error check 970470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return err; 971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find quantization levels for coefficients */ 972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_SHAPE; k++) { 973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_sQ10[WebRtcIsacfix_kSelIndShape[k]] = WebRtcIsacfix_kLevelsShapeQ10[WebRtcIsacfix_kOfLevelsShape[model]+WebRtcIsacfix_kOffsetShape[model][k] + index_QQ[k]]; 974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecHistOneStepMulti(index_QQ, streamdata, WebRtcIsacfix_kCdfGainPtr[model], WebRtcIsacfix_kInitIndexGain[model], KLT_ORDER_GAIN); 977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (err<0) // error check 978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return err; 979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find quantization levels for coefficients */ 980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_GAIN; k++) { 981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ17[WebRtcIsacfix_kSelIndGain[k]] = WebRtcIsacfix_kLevelsGainQ17[WebRtcIsacfix_kOfLevelsGain[model]+ WebRtcIsacfix_kOffsetGain[model][k] + index_QQ[k]]; 982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* inverse KLT */ 986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* left transform */ // Transpose matrix! 98823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT1GainQ15[model], tmpcoeffs_gQ17, 98923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs2_gQ21, kTIndexFactor2, kTIndexFactor2, 99023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTInitCase0, kTIndexStep1, kTIndexStep1, 99123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTLoopCount2, kTLoopCount2, kTMatrix1_shift5); 99223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com poss = 0; 994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (j=0; j<SUBFRAMES; j++) { 995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<LPC_SHAPE_ORDER; k++) { 996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ = 0; 99723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org pos = LPC_SHAPE_ORDER * j; 99823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org pos2 = LPC_SHAPE_ORDER * k; 999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n=0; n<LPC_SHAPE_ORDER; n++) { 1000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ += WEBRTC_SPL_MUL_16_16_RSFT(tmpcoeffs_sQ10[pos], WebRtcIsacfix_kT1ShapeQ15[model][pos2], 7); // (Q10*Q15)>>7 = Q18 1001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos++; 1002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos2++; 1003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs2_sQ18[poss] = sumQQ; //Q18 1005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com poss++; 1006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* right transform */ // Transpose matrix 101023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21, 101123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_gQ17, kTIndexFactor1, kTIndexStep2); 101223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT2ShapeQ15[model], 101323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs2_sQ18, tmpcoeffs_sQ17, kTIndexFactor1, kTIndexFactor1, 101423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTInitCase1, kTIndexStep3, kTIndexStep2, kTLoopCount1, kTLoopCount3, 101523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTMatrix1_shift0); 1016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* scaling, mean addition, and gain restoration */ 1018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gainpos = 0; 1019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg = 0;poss = 0;pos=0; 1020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<SUBFRAMES; k++) { 1021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* log gains */ 1023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9 1024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ16 += WebRtcIsacfix_kMeansGainQ8[model][posg]; 1025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out 1026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gain_lo_hiQ17[gainpos] = sumQQ; //Q17 1027470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gainpos++; 1028470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; 1029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9 1031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ16 += WebRtcIsacfix_kMeansGainQ8[model][posg]; 1032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out 1033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gain_lo_hiQ17[gainpos] = sumQQ; //Q17 1034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gainpos++; 1035470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; 1036470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1037470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* lo band LAR coeffs */ 1038470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n=0; n<ORDERLO; n++, pos++, poss++) { 1039470e71d3649f6cac4688e83819640b012b5d38bbniklase@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 1040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[model][poss]; // Q17+Q17 = Q17 1041470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com LPCCoefQ17[pos] = tmp32; 1042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1043470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1044470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* hi band LAR coeffs */ 1045470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n=0; n<ORDERHI; n++, pos++, poss++) { 1046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32 = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(18204, tmpcoeffs_sQ17[poss]), 3); // ((Q13*Q17)>>16)<<3 = Q17, with 1/0.45 = 2.222222222222 ~= 18204 in Q13 1047470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[model][poss]; // Q17+Q17 = Q17 1048470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com LPCCoefQ17[pos] = tmp32; 1049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1052470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *outmodel=model; 1054470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1055470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1058470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* estimate codel length of LPC Coef */ 1059470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comstatic int EstCodeLpcCoef(WebRtc_Word32 *LPCCoefQ17, 1060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 *gain_lo_hiQ17, 1061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 *model, 1062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 *sizeQ11, 1063470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Bitstr_enc *streamdata, 1064470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ISAC_SaveEncData_t* encData, 1065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com transcode_obj *transcodingParam) { 1066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int j, k, n; 1067470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 posQQ, pos2QQ, gainpos; 106823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtc_Word16 pos, poss, posg, offsg; 1069470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 index_gQQ[KLT_ORDER_GAIN], index_sQQ[KLT_ORDER_SHAPE]; 1070470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 index_ovr_gQQ[KLT_ORDER_GAIN], index_ovr_sQQ[KLT_ORDER_SHAPE]; 1071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 BitsQQ; 1072470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1073470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 tmpcoeffs_gQ6[KLT_ORDER_GAIN]; 1074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 tmpcoeffs_gQ17[KLT_ORDER_GAIN]; 1075470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 tmpcoeffs_sQ17[KLT_ORDER_SHAPE]; 1076470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 tmpcoeffs2_gQ21[KLT_ORDER_GAIN]; 1077470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 tmpcoeffs2_sQ17[KLT_ORDER_SHAPE]; 1078470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 sumQQ; 1079470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 tmp32; 1080470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 sumQQ16; 1081470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int status = 0; 1082470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1083470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* write LAR coefficients to statistics file */ 1084470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Save data for creation of multiple bitstreams (and transcoding) */ 1085470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (encData != NULL) { 1086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_GAIN; k++) { 1087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com encData->LPCcoeffs_g[KLT_ORDER_GAIN*encData->startIdx + k] = gain_lo_hiQ17[k]; 1088470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1089470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* log gains, mean removal and scaling */ 1092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg = 0;poss = 0;pos=0; gainpos=0; 1093470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1094470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<SUBFRAMES; k++) { 1095470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* log gains */ 1096470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* The input argument X to logN(X) is 2^17 times higher than the 1098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com input floating point argument Y to log(Y), since the X value 1099470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com is a Q17 value. This can be compensated for after the call, by 1100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subraction a value Z for each Q-step. One Q-step means that 1101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com X gets 2 times higher, i.e. Z = logN(2)*256 = 0.693147180559*256 = 1102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 177.445678 should be subtracted (since logN() returns a Q8 value). 1103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com For a X value in Q17, the value 177.445678*17 = 3017 should be 1104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subtracted */ 1105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 1106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 1107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; gainpos++; 1108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 1110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 1111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; gainpos++; 1112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1113470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* lo band LAR coeffs */ 1114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n=0; n<ORDERLO; n++, poss++, pos++) { 1115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32 = LPCCoefQ17[pos] - WebRtcIsacfix_kMeansShapeQ17[0][poss]; //Q17 1116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(17203, tmp32<<3); // tmp32 = 2.1*tmp32 1117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_sQ17[poss] = tmp32; //Q17 1118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* hi band LAR coeffs */ 1121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n=0; n<ORDERHI; n++, poss++, pos++) { 1122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32 = LPCCoefQ17[pos] - WebRtcIsacfix_kMeansShapeQ17[0][poss]; //Q17 1123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(14746, tmp32<<1); // tmp32 = 0.45*tmp32 1124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_sQ17[poss] = tmp32; //Q17 1125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* KLT */ 1131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* left transform */ 1133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com offsg = 0; 113423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org posg = 0; 1135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (j=0; j<SUBFRAMES; j++) { 113623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org // Q21 = Q6 * Q15 113723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sumQQ = WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg], 113823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][0]); 113923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg + 1], 114023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][2]); 114123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs2_gQ21[posg] = sumQQ; 114223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org posg++; 114323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 114423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org // Q21 = Q6 * Q15 114523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sumQQ = WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg], 114623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][1]); 114723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg + 1], 114823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][3]); 114923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs2_gQ21[posg] = sumQQ; 115023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org posg++; 115123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 1152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com offsg += 2; 1153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 115523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT1ShapeQ15[0], tmpcoeffs_sQ17, 115623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs2_sQ17, kTIndexFactor4, kTIndexFactor1, kTInitCase0, 115723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTIndexStep1, kTIndexStep3, kTLoopCount3, kTLoopCount3, kTMatrix1_shift1); 115823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 1159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* right transform */ 116023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21, 116123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_gQ17, kTIndexFactor3, kTIndexStep1); 116223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 116323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT2ShapeQ15[0], tmpcoeffs2_sQ17, 116423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_sQ17, kTIndexFactor1, kTIndexFactor3, kTInitCase1, kTIndexStep3, 116523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTIndexStep1, kTLoopCount1, kTLoopCount3, kTMatrix1_shift1); 1166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* quantize coefficients */ 1168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com BitsQQ = 0; 1170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok? 1171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posQQ = WebRtcIsacfix_kSelIndGain[k]; 1173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos2QQ= (WebRtc_Word16)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17); 1174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok? 1176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (index_gQQ[k] < 0) { 1177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_gQQ[k] = 0; 1178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) { 1180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k]; 1181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_ovr_gQQ[k] = WebRtcIsacfix_kOffsetGain[0][k]+index_gQQ[k]; 1183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posQQ = WebRtcIsacfix_kOfLevelsGain[0] + index_ovr_gQQ[k]; 1184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Save data for creation of multiple bitstreams */ 1186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (encData != NULL) { 1187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com encData->LPCindex_g[KLT_ORDER_GAIN*encData->startIdx + k] = index_gQQ[k]; 1188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* determine number of bits */ 1191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ = WebRtcIsacfix_kCodeLenGainQ11[posQQ]; //Q11 1192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com BitsQQ += sumQQ; 1193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_SHAPE; k++) //ATTN: ok? 1196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_sQQ[k] = (WebRtc_Word16)(CalcLrIntQ(tmpcoeffs_sQ17[WebRtcIsacfix_kSelIndShape[k]], 17) + WebRtcIsacfix_kQuantMinShape[k]); //ATTN: ok? 1198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (index_sQQ[k] < 0) 1200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_sQQ[k] = 0; 1201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (index_sQQ[k] > WebRtcIsacfix_kMaxIndShape[k]) 1202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_sQQ[k] = WebRtcIsacfix_kMaxIndShape[k]; 1203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_ovr_sQQ[k] = WebRtcIsacfix_kOffsetShape[0][k]+index_sQQ[k]; 1204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posQQ = WebRtcIsacfix_kOfLevelsShape[0] + index_ovr_sQQ[k]; 1206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ = WebRtcIsacfix_kCodeLenShapeQ11[posQQ]; //Q11 1207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com BitsQQ += sumQQ; 1208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *model = 0; 1213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *sizeQ11=BitsQQ; 1214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy coding of model number */ 1216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncHistMulti(streamdata, model, WebRtcIsacfix_kModelCdfPtr, 1); 1217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (status < 0) { 1218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy coding of quantization indices - shape only */ 1222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncHistMulti(streamdata, index_sQQ, WebRtcIsacfix_kCdfShapePtr[0], KLT_ORDER_SHAPE); 1223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (status < 0) { 1224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Save data for creation of multiple bitstreams */ 1228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (encData != NULL) { 1229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_SHAPE; k++) 1230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com encData->LPCindex_s[KLT_ORDER_SHAPE*encData->startIdx + k] = index_sQQ[k]; 1232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* save the state of the bitstream object 'streamdata' for the possible bit-rate reduction */ 1235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com transcodingParam->full = streamdata->full; 1236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com transcodingParam->stream_index = streamdata->stream_index; 1237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com transcodingParam->streamval = streamdata->streamval; 1238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com transcodingParam->W_upper = streamdata->W_upper; 1239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com transcodingParam->beforeLastWord = streamdata->stream[streamdata->stream_index-1]; 1240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com transcodingParam->lastWord = streamdata->stream[streamdata->stream_index]; 1241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy coding of index */ 1243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncHistMulti(streamdata, index_gQQ, WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN); 1244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (status < 0) { 1245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find quantization levels for shape coefficients */ 1249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_SHAPE; k++) { 1250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_sQ17[WebRtcIsacfix_kSelIndShape[k]] = WEBRTC_SPL_MUL(128, WebRtcIsacfix_kLevelsShapeQ10[WebRtcIsacfix_kOfLevelsShape[0]+index_ovr_sQQ[k]]); 1251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* inverse KLT */ 1254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* left transform */ // Transpose matrix! 125623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT1ShapeQ15[0], tmpcoeffs_sQ17, 125723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs2_sQ17, kTIndexFactor4, kTIndexFactor4, kTInitCase0, 125823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTIndexStep1, kTIndexStep1, kTLoopCount3, kTLoopCount3, kTMatrix1_shift1); 1259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* right transform */ // Transpose matrix 126123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT2ShapeQ15[0], tmpcoeffs2_sQ17, 126223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_sQ17, kTIndexFactor1, kTIndexFactor1, kTInitCase1, kTIndexStep3, 126323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org kTIndexStep2, kTLoopCount1, kTLoopCount3, kTMatrix1_shift1); 1264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* scaling, mean addition, and gain restoration */ 1266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com poss = 0;pos=0; 1267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<SUBFRAMES; k++) { 1268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* lo band LAR coeffs */ 1270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n=0; n<ORDERLO; n++, pos++, poss++) { 1271470e71d3649f6cac4688e83819640b012b5d38bbniklase@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 1272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[0][poss]; // Q17+Q17 = Q17 1273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com LPCCoefQ17[pos] = tmp32; 1274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* hi band LAR coeffs */ 1277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (n=0; n<ORDERHI; n++, pos++, poss++) { 1278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32 = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(18204, tmpcoeffs_sQ17[poss]), 3); // ((Q13*Q17)>>16)<<3 = Q17, with 1/0.45 = 2.222222222222 ~= 18204 in Q13 1279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[0][poss]; // Q17+Q17 = Q17 1280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com LPCCoefQ17[pos] = tmp32; 1281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com //to update tmpcoeffs_gQ17 to the proper state 1286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_GAIN; k++) { 1287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ17[WebRtcIsacfix_kSelIndGain[k]] = WebRtcIsacfix_kLevelsGainQ17[WebRtcIsacfix_kOfLevelsGain[0]+index_ovr_gQQ[k]]; 1288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find quantization levels for coefficients */ 1293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* left transform */ 1295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com offsg = 0; 1296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg = 0; 1297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (j=0; j<SUBFRAMES; j++) { 129823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org // (Q15 * Q17) >> (16 - 1) = Q17; Q17 << 4 = Q21. 129923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sumQQ = (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[0][0], 130023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_gQ17[offsg]) << 1); 130123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[0][1], 130223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_gQ17[offsg + 1]) << 1); 130323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs2_gQ21[posg] = WEBRTC_SPL_LSHIFT_W32(sumQQ, 4); 130423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org posg++; 130523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 130623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sumQQ = (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[0][2], 130723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_gQ17[offsg]) << 1); 130823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[0][3], 130923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_gQ17[offsg + 1]) << 1); 131023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs2_gQ21[posg] = WEBRTC_SPL_LSHIFT_W32(sumQQ, 4); 131123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org posg++; 1312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com offsg += 2; 1313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* right transform */ // Transpose matrix 131623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21, 131723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_gQ17, kTIndexFactor1, kTIndexStep2); 1318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* scaling, mean addition, and gain restoration */ 1320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg = 0; 1321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gainpos = 0; 1322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<2*SUBFRAMES; k++) { 1323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9 1325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ16 += WebRtcIsacfix_kMeansGainQ8[0][posg]; 1326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out 1327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gain_lo_hiQ17[gainpos] = sumQQ; //Q17 1328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gainpos++; 1330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos++;posg++; 1331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_EstCodeLpcGain(WebRtc_Word32 *gain_lo_hiQ17, 1337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Bitstr_enc *streamdata, 1338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ISAC_SaveEncData_t* encData) { 133923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int j, k; 1340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 posQQ, pos2QQ, gainpos; 134123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtc_Word16 posg; 1342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 index_gQQ[KLT_ORDER_GAIN]; 1343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 tmpcoeffs_gQ6[KLT_ORDER_GAIN]; 1345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 tmpcoeffs_gQ17[KLT_ORDER_GAIN]; 1346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 tmpcoeffs2_gQ21[KLT_ORDER_GAIN]; 1347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 sumQQ; 1348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int status = 0; 1349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* write LAR coefficients to statistics file */ 1351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Save data for creation of multiple bitstreams (and transcoding) */ 1352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (encData != NULL) { 1353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_GAIN; k++) { 1354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com encData->LPCcoeffs_g[KLT_ORDER_GAIN*encData->startIdx + k] = gain_lo_hiQ17[k]; 1355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* log gains, mean removal and scaling */ 135923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org posg = 0; gainpos = 0; 1360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<SUBFRAMES; k++) { 1362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* log gains */ 1363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* The input argument X to logN(X) is 2^17 times higher than the 1365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com input floating point argument Y to log(Y), since the X value 1366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com is a Q17 value. This can be compensated for after the call, by 1367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subraction a value Z for each Q-step. One Q-step means that 1368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com X gets 2 times higher, i.e. Z = logN(2)*256 = 0.693147180559*256 = 1369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 177.445678 should be subtracted (since logN() returns a Q8 value). 1370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com For a X value in Q17, the value 177.445678*17 = 3017 should be 1371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subtracted */ 1372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 1373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 1374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; gainpos++; 1375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 1377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 1378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; gainpos++; 1379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* KLT */ 1383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* left transform */ 138523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org posg = 0; 1386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (j=0; j<SUBFRAMES; j++) { 138723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org // Q21 = Q6 * Q15 138823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sumQQ = WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[j * 2], 138923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][0]); 139023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[j * 2 + 1], 139123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][2]); 1392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs2_gQ21[posg] = sumQQ; 1393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; 1394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 139523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sumQQ = WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[j * 2], 139623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][1]); 139723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[j * 2 + 1], 139823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][3]); 139923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs2_gQ21[posg] = sumQQ; 1400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; 1401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 140323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org /* right transform */ 140423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21, 140523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_gQ17, kTIndexFactor3, kTIndexStep1); 140623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org 1407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* quantize coefficients */ 1408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok? 1410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posQQ = WebRtcIsacfix_kSelIndGain[k]; 1412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos2QQ= (WebRtc_Word16)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17); 1413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok? 1415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (index_gQQ[k] < 0) { 1416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_gQQ[k] = 0; 1417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) { 1419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k]; 1420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Save data for creation of multiple bitstreams */ 1423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (encData != NULL) { 1424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com encData->LPCindex_g[KLT_ORDER_GAIN*encData->startIdx + k] = index_gQQ[k]; 1425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy coding of index */ 1429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncHistMulti(streamdata, index_gQQ, WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN); 1430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (status < 0) { 1431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_EncodeLpc(WebRtc_Word32 *gain_lo_hiQ17, 1439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 *LPCCoef_loQ15, 1440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 *LPCCoef_hiQ15, 1441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 *model, 1442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 *sizeQ11, 1443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Bitstr_enc *streamdata, 1444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ISAC_SaveEncData_t* encData, 1445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com transcode_obj *transcodeParam) 1446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int status = 0; 1448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 larsQ17[KLT_ORDER_SHAPE]; // KLT_ORDER_SHAPE == (ORDERLO+ORDERHI)*SUBFRAMES 1449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // = (6+12)*6 == 108 1450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Poly2LarFix(LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES, larsQ17); 1452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 145323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org status = EstCodeLpcCoef(larsQ17, gain_lo_hiQ17, model, sizeQ11, 145423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org streamdata, encData, transcodeParam); 1455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (status < 0) { 1456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return (status); 1457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Lar2polyFix(larsQ17, LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES); 1460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1462470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* decode & dequantize RC */ 1466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_DecodeRcCoef(Bitstr_dec *streamdata, WebRtc_Word16 *RCQ15) 1467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k, err; 1469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 index[AR_ORDER]; 1470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy decoding of quantization indices */ 1472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecHistOneStepMulti(index, streamdata, WebRtcIsacfix_kRcCdfPtr, WebRtcIsacfix_kRcInitInd, AR_ORDER); 1473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (err<0) // error check 1474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return err; 1475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find quantization levels for reflection coefficients */ 1477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<AR_ORDER; k++) 1478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RCQ15[k] = *(WebRtcIsacfix_kRcLevPtr[k] + index[k]); 1480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* quantize & code RC */ 1488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_EncodeRcCoef(WebRtc_Word16 *RCQ15, Bitstr_enc *streamdata) 1489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k; 1491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 index[AR_ORDER]; 1492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int status; 1493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* quantize reflection coefficients (add noise feedback?) */ 1495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<AR_ORDER; k++) 1496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index[k] = WebRtcIsacfix_kRcInitInd[k]; 1498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (RCQ15[k] > WebRtcIsacfix_kRcBound[index[k]]) 1500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com while (RCQ15[k] > WebRtcIsacfix_kRcBound[index[k] + 1]) 1502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index[k]++; 1503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 1505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com while (RCQ15[k] < WebRtcIsacfix_kRcBound[--index[k]]) ; 1507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RCQ15[k] = *(WebRtcIsacfix_kRcLevPtr[k] + index[k]); 1510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy coding of quantization indices */ 1514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncHistMulti(streamdata, index, WebRtcIsacfix_kRcCdfPtr, AR_ORDER); 1515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */ 1517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* decode & dequantize squared Gain */ 1522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_DecodeGain2(Bitstr_dec *streamdata, WebRtc_Word32 *gainQ10) 1523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int err; 1525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 index; 1526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy decoding of quantization index */ 1528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecHistOneStepMulti( 1529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &index, 1530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com streamdata, 1531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcIsacfix_kGainPtr, 1532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcIsacfix_kGainInitInd, 1533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1); 1534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* error check */ 1535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (err<0) { 1536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return err; 1537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find quantization level */ 1540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *gainQ10 = WebRtcIsacfix_kGain2Lev[index]; 1541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* quantize & code squared Gain */ 1548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_EncodeGain2(WebRtc_Word32 *gainQ10, Bitstr_enc *streamdata) 1549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 index; 1551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int status = 0; 1552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find quantization index */ 1554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index = WebRtcIsacfix_kGainInitInd[0]; 1555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (*gainQ10 > WebRtcIsacfix_kGain2Bound[index]) 1556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com while (*gainQ10 > WebRtcIsacfix_kGain2Bound[index + 1]) 1558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index++; 1559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 1561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com while (*gainQ10 < WebRtcIsacfix_kGain2Bound[--index]) ; 1563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* dequantize */ 1566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *gainQ10 = WebRtcIsacfix_kGain2Lev[index]; 1567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy coding of quantization index */ 1569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncHistMulti(streamdata, &index, WebRtcIsacfix_kGainPtr, 1); 1570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */ 1572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* code and decode Pitch Gains and Lags functions */ 1577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* decode & dequantize Pitch Gains */ 1579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_DecodePitchGain(Bitstr_dec *streamdata, WebRtc_Word16 *PitchGains_Q12) 1580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int err; 1582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 index_comb; 1583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord16 *pitch_gain_cdf_ptr[1]; 1584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy decoding of quantization indices */ 1586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *pitch_gain_cdf_ptr = WebRtcIsacfix_kPitchGainCdf; 1587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecHistBisectMulti(&index_comb, streamdata, pitch_gain_cdf_ptr, WebRtcIsacfix_kCdfTableSizeGain, 1); 1588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* error check, Q_mean_Gain.. tables are of size 144 */ 15891617f65eecbd894b17870929a9ffec4d62078d89tina.legrand@webrtc.org if ((err < 0) || (index_comb < 0) || (index_comb >= 144)) 1590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -ISAC_RANGE_ERROR_DECODE_PITCH_GAIN; 1591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* unquantize back to pitch gains by table look-up */ 1593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchGains_Q12[0] = WebRtcIsacfix_kPitchGain1[index_comb]; 1594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchGains_Q12[1] = WebRtcIsacfix_kPitchGain2[index_comb]; 1595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchGains_Q12[2] = WebRtcIsacfix_kPitchGain3[index_comb]; 1596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchGains_Q12[3] = WebRtcIsacfix_kPitchGain4[index_comb]; 1597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* quantize & code Pitch Gains */ 1603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_EncodePitchGain(WebRtc_Word16 *PitchGains_Q12, Bitstr_enc *streamdata, ISAC_SaveEncData_t* encData) 1604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k,j; 1606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 SQ15[PITCH_SUBFRAMES]; 1607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 index[3]; 1608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 index_comb; 1609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord16 *pitch_gain_cdf_ptr[1]; 1610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 CQ17; 1611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int status = 0; 1612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* get the approximate arcsine (almost linear)*/ 1615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<PITCH_SUBFRAMES; k++) 1616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com SQ15[k] = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT(PitchGains_Q12[k],33,2); //Q15 1617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find quantization index; only for the first three transform coefficients */ 1620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<3; k++) 1621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* transform */ 1623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ17=0; 1624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (j=0; j<PITCH_SUBFRAMES; j++) { 1625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ17 += WEBRTC_SPL_MUL_16_16_RSFT(WebRtcIsacfix_kTransform[k][j], SQ15[j],10); // Q17 1626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index[k] = (WebRtc_Word16)((CQ17 + 8192)>>14); // Rounding and scaling with stepsize (=1/0.125=8) 1629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* check that the index is not outside the boundaries of the table */ 1631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (index[k] < WebRtcIsacfix_kLowerlimiGain[k]) index[k] = WebRtcIsacfix_kLowerlimiGain[k]; 1632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (index[k] > WebRtcIsacfix_kUpperlimitGain[k]) index[k] = WebRtcIsacfix_kUpperlimitGain[k]; 1633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index[k] -= WebRtcIsacfix_kLowerlimiGain[k]; 1634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* calculate unique overall index */ 1637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_comb = (WebRtc_Word16)(WEBRTC_SPL_MUL(WebRtcIsacfix_kMultsGain[0], index[0]) + 1638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_SPL_MUL(WebRtcIsacfix_kMultsGain[1], index[1]) + index[2]); 1639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* unquantize back to pitch gains by table look-up */ 1641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (Y) 1642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchGains_Q12[0] = WebRtcIsacfix_kPitchGain1[index_comb]; 1643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchGains_Q12[1] = WebRtcIsacfix_kPitchGain2[index_comb]; 1644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchGains_Q12[2] = WebRtcIsacfix_kPitchGain3[index_comb]; 1645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchGains_Q12[3] = WebRtcIsacfix_kPitchGain4[index_comb]; 1646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy coding of quantization pitch gains */ 1649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *pitch_gain_cdf_ptr = WebRtcIsacfix_kPitchGainCdf; 1650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncHistMulti(streamdata, &index_comb, pitch_gain_cdf_ptr, 1); 1651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (status < 0) { 1652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Save data for creation of multiple bitstreams */ 1656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (encData != NULL) { 1657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com encData->pitchGain_index[encData->startIdx] = index_comb; 1658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1662470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* Pitch LAG */ 1666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* decode & dequantize Pitch Lags */ 1669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_DecodePitchLag(Bitstr_dec *streamdata, 1670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 *PitchGain_Q12, 1671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 *PitchLags_Q7) 1672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k, err; 1674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 index[PITCH_SUBFRAMES]; 1675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_Word16 *mean_val2Q10, *mean_val4Q10; 1676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_Word16 *lower_limit; 1678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord16 *init_index; 1679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord16 *cdf_size; 1680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord16 **cdf; 1681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 meangainQ12; 1683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 CQ11, CQ10,tmp32a,tmp32b; 1684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 shft,tmp16a,tmp16c; 1685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1686470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com meangainQ12=0; 1687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < 4; k++) 1688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com meangainQ12 += PitchGain_Q12[k]; 1689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com meangainQ12 = WEBRTC_SPL_RSHIFT_W32(meangainQ12, 2); // Get average 1691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* voicing classificiation */ 1693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (meangainQ12 <= 819) { // mean_gain < 0.2 1694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shft = -1; // StepSize=2.0; 1695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdf = WebRtcIsacfix_kPitchLagPtrLo; 1696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdf_size = WebRtcIsacfix_kPitchLagSizeLo; 1697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val2Q10 = WebRtcIsacfix_kMeanLag2Lo; 1698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val4Q10 = WebRtcIsacfix_kMeanLag4Lo; 1699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lower_limit = WebRtcIsacfix_kLowerLimitLo; 1700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com init_index = WebRtcIsacfix_kInitIndLo; 1701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else if (meangainQ12 <= 1638) { // mean_gain < 0.4 1702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shft = 0; // StepSize=1.0; 1703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdf = WebRtcIsacfix_kPitchLagPtrMid; 1704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdf_size = WebRtcIsacfix_kPitchLagSizeMid; 1705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val2Q10 = WebRtcIsacfix_kMeanLag2Mid; 1706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val4Q10 = WebRtcIsacfix_kMeanLag4Mid; 1707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lower_limit = WebRtcIsacfix_kLowerLimitMid; 1708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com init_index = WebRtcIsacfix_kInitIndMid; 1709470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 1710470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shft = 1; // StepSize=0.5; 1711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdf = WebRtcIsacfix_kPitchLagPtrHi; 1712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdf_size = WebRtcIsacfix_kPitchLagSizeHi; 1713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val2Q10 = WebRtcIsacfix_kMeanLag2Hi; 1714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val4Q10 = WebRtcIsacfix_kMeanLag4Hi; 1715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lower_limit = WebRtcIsacfix_kLowerLimitHi; 1716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com init_index = WebRtcIsacfix_kInitIndHi; 1717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy decoding of quantization indices */ 1720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecHistBisectMulti(index, streamdata, cdf, cdf_size, 1); 1721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((err<0) || (index[0]<0)) // error check 1722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG; 1723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecHistOneStepMulti(index+1, streamdata, cdf+1, init_index, 3); 1725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (err<0) // error check 1726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG; 1727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* unquantize back to transform coefficients and do the inverse transform: S = T'*C */ 1730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ11 = ((WebRtc_Word32)index[0] + lower_limit[0]); // Q0 1731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ11 = WEBRTC_SPL_SHIFT_W32(CQ11,11-shft); // Scale with StepSize, Q11 1732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<PITCH_SUBFRAMES; k++) { 1733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32a = WEBRTC_SPL_MUL_16_32_RSFT11(WebRtcIsacfix_kTransform[0][k], CQ11); 1734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp16a = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32a, 5); 1735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchLags_Q7[k] = tmp16a; 1736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ10 = mean_val2Q10[index[1]]; 1739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<PITCH_SUBFRAMES; k++) { 1740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32b = (WebRtc_Word32) WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) WebRtcIsacfix_kTransform[1][k], (WebRtc_Word16) CQ10,10); 1741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp16c = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); 1742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchLags_Q7[k] += tmp16c; 1743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ10 = mean_val4Q10[index[3]]; 1746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<PITCH_SUBFRAMES; k++) { 1747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32b = (WebRtc_Word32) WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) WebRtcIsacfix_kTransform[3][k], (WebRtc_Word16) CQ10,10); 1748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp16c = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); 1749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchLags_Q7[k] += tmp16c; 1750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* quantize & code Pitch Lags */ 1758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_EncodePitchLag(WebRtc_Word16 *PitchLagsQ7,WebRtc_Word16 *PitchGain_Q12, 1759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Bitstr_enc *streamdata, ISAC_SaveEncData_t* encData) 1760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int k, j; 1762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 index[PITCH_SUBFRAMES]; 1763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 meangainQ12, CQ17; 1764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 CQ11, CQ10,tmp32a; 1765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1766470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_Word16 *mean_val2Q10,*mean_val4Q10; 1767470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_Word16 *lower_limit, *upper_limit; 1768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord16 **cdf; 1769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 shft, tmp16a, tmp16b, tmp16c; 1770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 tmp32b; 1771470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int status = 0; 1772470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1773470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* compute mean pitch gain */ 1774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com meangainQ12=0; 1775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < 4; k++) 1776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com meangainQ12 += PitchGain_Q12[k]; 1777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com meangainQ12 = WEBRTC_SPL_RSHIFT_W32(meangainQ12, 2); 1779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Save data for creation of multiple bitstreams */ 1781470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (encData != NULL) { 1782470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com encData->meanGain[encData->startIdx] = meangainQ12; 1783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* voicing classificiation */ 1786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (meangainQ12 <= 819) { // mean_gain < 0.2 1787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shft = -1; // StepSize=2.0; 1788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdf = WebRtcIsacfix_kPitchLagPtrLo; 1789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val2Q10 = WebRtcIsacfix_kMeanLag2Lo; 1790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val4Q10 = WebRtcIsacfix_kMeanLag4Lo; 1791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lower_limit = WebRtcIsacfix_kLowerLimitLo; 1792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com upper_limit = WebRtcIsacfix_kUpperLimitLo; 1793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else if (meangainQ12 <= 1638) { // mean_gain < 0.4 1794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shft = 0; // StepSize=1.0; 1795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdf = WebRtcIsacfix_kPitchLagPtrMid; 1796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val2Q10 = WebRtcIsacfix_kMeanLag2Mid; 1797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val4Q10 = WebRtcIsacfix_kMeanLag4Mid; 1798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lower_limit = WebRtcIsacfix_kLowerLimitMid; 1799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com upper_limit = WebRtcIsacfix_kUpperLimitMid; 1800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 1801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shft = 1; // StepSize=0.5; 1802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cdf = WebRtcIsacfix_kPitchLagPtrHi; 1803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val2Q10 = WebRtcIsacfix_kMeanLag2Hi; 1804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mean_val4Q10 = WebRtcIsacfix_kMeanLag4Hi; 1805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lower_limit = WebRtcIsacfix_kLowerLimitHi; 1806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com upper_limit = WebRtcIsacfix_kUpperLimitHi; 1807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* find quantization index */ 1810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<4; k++) 1811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* transform */ 1813470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ17=0; 1814470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (j=0; j<PITCH_SUBFRAMES; j++) 1815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ17 += WEBRTC_SPL_MUL_16_16_RSFT(WebRtcIsacfix_kTransform[k][j], PitchLagsQ7[j],2); // Q17 1816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1817470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ17 = WEBRTC_SPL_SHIFT_W32(CQ17,shft); // Scale with StepSize 1818470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* quantize */ 1820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp16b = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(CQ17 + 65536, 17 ); 1821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index[k] = tmp16b; 1822470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* check that the index is not outside the boundaries of the table */ 1824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (index[k] < lower_limit[k]) index[k] = lower_limit[k]; 1825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (index[k] > upper_limit[k]) index[k] = upper_limit[k]; 1826470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index[k] -= lower_limit[k]; 1827470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1828470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Save data for creation of multiple bitstreams */ 1829470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(encData != NULL) { 1830470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com encData->pitchIndex[PITCH_SUBFRAMES*encData->startIdx + k] = index[k]; 1831470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1832470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1833470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1834470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* unquantize back to transform coefficients and do the inverse transform: S = T'*C */ 1835470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ11 = (index[0] + lower_limit[0]); // Q0 1836470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ11 = WEBRTC_SPL_SHIFT_W32(CQ11,11-shft); // Scale with StepSize, Q11 1837470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1838470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<PITCH_SUBFRAMES; k++) { 1839470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32a = WEBRTC_SPL_MUL_16_32_RSFT11(WebRtcIsacfix_kTransform[0][k], CQ11); // Q12 1840470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp16a = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32a, 5);// Q7 1841470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchLagsQ7[k] = tmp16a; 1842470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1843470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1844470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ10 = mean_val2Q10[index[1]]; 1845470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<PITCH_SUBFRAMES; k++) { 1846470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32b = (WebRtc_Word32) WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) WebRtcIsacfix_kTransform[1][k], (WebRtc_Word16) CQ10,10); 1847470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp16c = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q7 1848470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchLagsQ7[k] += tmp16c; 1849470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1850470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1851470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CQ10 = mean_val4Q10[index[3]]; 1852470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<PITCH_SUBFRAMES; k++) { 1853470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32b = (WebRtc_Word32) WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) WebRtcIsacfix_kTransform[3][k], (WebRtc_Word16) CQ10,10); 1854470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp16c = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q7 1855470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PitchLagsQ7[k] += tmp16c; 1856470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1857470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1858470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy coding of quantization pitch lags */ 1859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncHistMulti(streamdata, index, cdf, PITCH_SUBFRAMES); 1860470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1861470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */ 1862470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1864470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1865470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1866470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1867470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* Routines for inband signaling of bandwitdh estimation */ 1868470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* Histograms based on uniform distribution of indices */ 1869470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* Move global variables later! */ 1870470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1872470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* cdf array for frame length indicator */ 1873470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comconst WebRtc_UWord16 kFrameLenCdf[4] = { 1874470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 0, 21845, 43690, 65535}; 1875470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* pointer to cdf array for frame length indicator */ 1877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comconst WebRtc_UWord16 *kFrameLenCdfPtr[1] = {kFrameLenCdf}; 1878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* initial cdf index for decoder of frame length indicator */ 1880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comconst WebRtc_UWord16 kFrameLenInitIndex[1] = {1}; 1881470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1882470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1883470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_DecodeFrameLen(Bitstr_dec *streamdata, 1884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 *framesamples) 1885470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1887470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int err; 1888470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 frame_mode; 1889470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1890470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = 0; 1891470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy decoding of frame length [1:30ms,2:60ms] */ 1892470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecHistOneStepMulti(&frame_mode, streamdata, kFrameLenCdfPtr, kFrameLenInitIndex, 1); 1893470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (err<0) // error check 1894470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH; 1895470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1896470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch(frame_mode) { 1897470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case 1: 1898470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *framesamples = 480; /* 30ms */ 1899470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1900470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case 2: 1901470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *framesamples = 960; /* 60ms */ 1902470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1903470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com default: 1904470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = -ISAC_DISALLOWED_FRAME_MODE_DECODER; 1905470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1906470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1907470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return err; 1908470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1909470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1910470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1911470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_EncodeFrameLen(WebRtc_Word16 framesamples, Bitstr_enc *streamdata) { 1912470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1913470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int status; 1914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 frame_mode; 1915470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1916470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = 0; 1917470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com frame_mode = 0; 1918470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy coding of frame length [1:480 samples,2:960 samples] */ 1919470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch(framesamples) { 1920470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case 480: 1921470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com frame_mode = 1; 1922470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1923470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case 960: 1924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com frame_mode = 2; 1925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1926470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com default: 1927470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = - ISAC_DISALLOWED_FRAME_MODE_ENCODER; 1928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1930470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (status < 0) 1931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncHistMulti(streamdata, &frame_mode, kFrameLenCdfPtr, 1); 1934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1937470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* cdf array for estimated bandwidth */ 1939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comconst WebRtc_UWord16 kBwCdf[25] = { 1940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 0, 2731, 5461, 8192, 10923, 13653, 16384, 19114, 21845, 24576, 27306, 30037, 1941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 32768, 35498, 38229, 40959, 43690, 46421, 49151, 51882, 54613, 57343, 60074, 1942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 62804, 65535}; 1943470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* pointer to cdf array for estimated bandwidth */ 1945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comconst WebRtc_UWord16 *kBwCdfPtr[1] = {kBwCdf}; 1946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* initial cdf index for decoder of estimated bandwidth*/ 1948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comconst WebRtc_UWord16 kBwInitIndex[1] = {7}; 1949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1950470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_DecodeSendBandwidth(Bitstr_dec *streamdata, WebRtc_Word16 *BWno) { 1952470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1953470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int err; 1954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 BWno32; 1955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy decoding of sender's BW estimation [0..23] */ 1957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com err = WebRtcIsacfix_DecHistOneStepMulti(&BWno32, streamdata, kBwCdfPtr, kBwInitIndex, 1); 1958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (err<0) // error check 1959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -ISAC_RANGE_ERROR_DECODE_BANDWIDTH; 1960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *BWno = (WebRtc_Word16)BWno32; 1961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return err; 1962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1963470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1966470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint WebRtcIsacfix_EncodeReceiveBandwidth(WebRtc_Word16 *BWno, Bitstr_enc *streamdata) 1967470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1968470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int status = 0; 1969470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* entropy encoding of receiver's BW estimation [0..23] */ 1970470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com status = WebRtcIsacfix_EncHistMulti(streamdata, BWno, kBwCdfPtr, 1); 1971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return status; 1973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* estimate codel length of LPC Coef */ 1976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid WebRtcIsacfix_TranscodeLpcCoef(WebRtc_Word32 *gain_lo_hiQ17, 1977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 *index_gQQ) { 197823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org int j, k; 1979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 posQQ, pos2QQ; 198023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtc_Word16 posg, offsg, gainpos; 1981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 tmpcoeffs_gQ6[KLT_ORDER_GAIN]; 1982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 tmpcoeffs_gQ17[KLT_ORDER_GAIN]; 1983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 tmpcoeffs2_gQ21[KLT_ORDER_GAIN]; 1984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 sumQQ; 1985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* log gains, mean removal and scaling */ 198823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org posg = 0; gainpos=0; 1989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1990470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<SUBFRAMES; k++) { 1991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* log gains */ 1992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* The input argument X to logN(X) is 2^17 times higher than the 1994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com input floating point argument Y to log(Y), since the X value 1995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com is a Q17 value. This can be compensated for after the call, by 1996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subraction a value Z for each Q-step. One Q-step means that 1997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com X gets 2 times higher, i.e. Z = logN(2)*256 = 0.693147180559*256 = 1998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 177.445678 should be subtracted (since logN() returns a Q8 value). 1999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com For a X value in Q17, the value 177.445678*17 = 3017 should be 2000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subtracted */ 2001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 2002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 2003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; gainpos++; 2004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 2006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 2007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; gainpos++; 2008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* KLT */ 2013470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* left transform */ 2015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com offsg = 0; 2016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (j=0; j<SUBFRAMES; j++) { 201723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org // Q21 = Q6 * Q15 201823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sumQQ = WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg], 201923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][0]); 202023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg + 1], 202123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][2]); 2022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmpcoeffs2_gQ21[posg] = sumQQ; 2023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posg++; 2024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 202523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org // Q21 = Q6 * Q15 202623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sumQQ = WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg], 202723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][1]); 202823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg + 1], 202923da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_kT1GainQ15[0][3]); 203023da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs2_gQ21[posg] = sumQQ; 203123da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org posg++; 2032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* right transform */ 203523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21, 203623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org tmpcoeffs_gQ17, kTIndexFactor3, kTIndexStep1); 2037470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2038470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* quantize coefficients */ 2039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok? 2040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2041470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com posQQ = WebRtcIsacfix_kSelIndGain[k]; 2042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pos2QQ= (WebRtc_Word16)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17); 2043470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2044470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok? 2045470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (index_gQQ[k] < 0) { 2046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_gQQ[k] = 0; 2047470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2048470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) { 2049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k]; 2050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2052470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2053