1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * entropy_coding.c 13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This header file defines all of the functions used to arithmetically 15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * encode the iSAC bistream 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "entropy_coding.h" 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "settings.h" 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "arith_routines.h" 23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "signal_processing_library.h" 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "spectrum_ar_model_tables.h" 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "lpc_tables.h" 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "pitch_gain_tables.h" 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "pitch_lag_tables.h" 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "encode_lpc_swb.h" 29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "lpc_shape_swb12_tables.h" 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "lpc_shape_swb16_tables.h" 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "lpc_gain_swb_tables.h" 32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "os_specific_inline.h" 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <math.h> 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <string.h> 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 37fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic const uint16_t kLpcVecPerSegmentUb12 = 5; 38fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic const uint16_t kLpcVecPerSegmentUb16 = 4; 39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* CDF array for encoder bandwidth (12 vs 16 kHz) indicator. */ 41fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic const uint16_t kOneBitEqualProbCdf[3] = { 42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 0, 32768, 65535 }; 43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Pointer to cdf array for encoder bandwidth (12 vs 16 kHz) indicator. */ 45fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic const uint16_t* kOneBitEqualProbCdf_ptr[1] = { 46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kOneBitEqualProbCdf }; 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Initial cdf index for decoder of encoded bandwidth 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * (12 vs 16 kHz) indicator. 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 52fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic const uint16_t kOneBitEqualProbInitIndex[1] = { 1 }; 53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic const int kIsSWB12 = 1; 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* compute correlation from power spectrum */ 58fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic void FindCorrelation(int32_t* PSpecQ12, int32_t* CorrQ7) { 59fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t summ[FRAMESAMPLES / 8]; 60fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t diff[FRAMESAMPLES / 8]; 61fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int16_t* CS_ptrQ9; 62fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t sum; 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k, n; 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < FRAMESAMPLES / 8; k++) { 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org summ[k] = (PSpecQ12[k] + PSpecQ12[FRAMESAMPLES_QUARTER - 1 - k] + 16) >> 5; 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org diff[k] = (PSpecQ12[k] - PSpecQ12[FRAMESAMPLES_QUARTER - 1 - k] + 16) >> 5; 68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 2; 71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < FRAMESAMPLES / 8; n++) { 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += summ[n]; 73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CorrQ7[0] = sum; 75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < AR_ORDER; k += 2) { 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CS_ptrQ9 = WebRtcIsac_kCos[k]; 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < FRAMESAMPLES / 8; n++) 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += (CS_ptrQ9[n] * diff[n] + 256) >> 9; 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CorrQ7[k + 1] = sum; 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 1; k < AR_ORDER; k += 2) { 85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CS_ptrQ9 = WebRtcIsac_kCos[k]; 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < FRAMESAMPLES / 8; n++) 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += (CS_ptrQ9[n] * summ[n] + 256) >> 9; 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CorrQ7[k + 1] = sum; 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* compute inverse AR power spectrum */ 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Changed to the function used in iSAC FIX for compatibility reasons */ 95fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic void FindInvArSpec(const int16_t* ARCoefQ12, 96fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int32_t gainQ10, 97fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t* CurveQ16) { 98fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t CorrQ11[AR_ORDER + 1]; 99fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t sum, tmpGain; 100fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t diffQ16[FRAMESAMPLES / 8]; 101fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int16_t* CS_ptrQ9; 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k, n; 103fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t round, shftVal = 0, sh; 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < AR_ORDER + 1; n++) { 107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]); /* Q24 */ 108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(sum, 6), 110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 65) + 32768, 16); /* Q8 */ 111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CorrQ11[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, gainQ10) + 256, 9); 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* To avoid overflow, we shift down gainQ10 if it is large. 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * We will not lose any precision */ 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (gainQ10 > 400000) { 116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3); 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org round = 32; 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shftVal = 6; 119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpGain = gainQ10; 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org round = 256; 122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shftVal = 9; 123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 1; k < AR_ORDER + 1; k++) { 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 16384; 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = k; n < AR_ORDER + 1; n++) 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += WEBRTC_SPL_MUL(ARCoefQ12[n - k], ARCoefQ12[n]); /* Q24 */ 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = WEBRTC_SPL_RSHIFT_W32(sum, 15); 130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CorrQ11[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, tmpGain) + round, 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shftVal); 132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7); 134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < FRAMESAMPLES / 8; n++) { 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CurveQ16[n] = sum; 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 1; k < AR_ORDER; k += 2) { 138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < FRAMESAMPLES / 8; n++) { 139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CurveQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL( 140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kCos[k][n], CorrQ11[k + 1]) + 2, 2); 141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CS_ptrQ9 = WebRtcIsac_kCos[0]; 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* If CorrQ11[1] too large we avoid getting overflow in the 147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * calculation by shifting */ 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sh = WebRtcSpl_NormW32(CorrQ11[1]); 149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (CorrQ11[1] == 0) { /* Use next correlation */ 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sh = WebRtcSpl_NormW32(CorrQ11[2]); 151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (sh < 9) { 153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shftVal = 9 - sh; 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shftVal = 0; 156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < FRAMESAMPLES / 8; n++) { 158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org diffQ16[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL( 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[1], shftVal)) + 2, 2); 160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 2; k < AR_ORDER; k += 2) { 162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CS_ptrQ9 = WebRtcIsac_kCos[k]; 163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < FRAMESAMPLES / 8; n++) { 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org diffQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL( 165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[k + 1], shftVal)) + 2, 2); 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < FRAMESAMPLES / 8; k++) { 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CurveQ16[FRAMESAMPLES_QUARTER - 1 - k] = CurveQ16[k] - 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal); 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CurveQ16[k] += WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal); 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Generate array of dither samples in Q7. */ 177fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic void GenerateDitherQ7Lb(int16_t* bufQ7, uint32_t seed, 178fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int length, int16_t AvgPitchGain_Q12) { 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k, shft; 180fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t dither1_Q7, dither2_Q7, dither_gain_Q14; 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* This threshold should be equal to that in decode_spec(). */ 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (AvgPitchGain_Q12 < 614) { 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < length - 2; k += 3) { 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* New random unsigned int. */ 186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org seed = (seed * 196314165) + 907633515; 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Fixed-point dither sample between -64 and 64 (Q7). */ 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* dither = seed * 128 / 4294967295 */ 190fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org dither1_Q7 = (int16_t)(((int)seed + 16777216) >> 25); 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* New random unsigned int. */ 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org seed = (seed * 196314165) + 907633515; 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Fixed-point dither sample between -64 and 64. */ 196fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org dither2_Q7 = (int16_t)(((int)seed + 16777216) >> 25); 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shft = (seed >> 25) & 15; 199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (shft < 5) { 200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k] = dither1_Q7; 201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k + 1] = dither2_Q7; 202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k + 2] = 0; 203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (shft < 10) { 204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k] = dither1_Q7; 205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k + 1] = 0; 206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k + 2] = dither2_Q7; 207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k] = 0; 209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k + 1] = dither1_Q7; 210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k + 2] = dither2_Q7; 211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 214fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org dither_gain_Q14 = (int16_t)(22528 - 10 * AvgPitchGain_Q12); 215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Dither on half of the coefficients. */ 217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < length - 1; k += 2) { 218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* New random unsigned int */ 219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org seed = (seed * 196314165) + 907633515; 220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Fixed-point dither sample between -64 and 64. */ 222fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org dither1_Q7 = (int16_t)(((int)seed + 16777216) >> 25); 223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Dither sample is placed in either even or odd index. */ 225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shft = (seed >> 25) & 1; /* Either 0 or 1 */ 226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k + shft] = (((dither_gain_Q14 * dither1_Q7) + 8192) >> 14); 228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufQ7[k + 1 - shft] = 0; 229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/****************************************************************************** 236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * GenerateDitherQ7LbUB() 237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * generate array of dither samples in Q7 There are less zeros in dither 239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * vector compared to GenerateDitherQ7Lb. 240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * A uniform random number generator with the range of [-64 64] is employed 242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * but the generated dithers are scaled by 0.35, a heuristic scaling. 243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -seed : the initial seed for the random number generator. 246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -length : the number of dither values to be generated. 247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Output: 249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -bufQ7 : pointer to a buffer where dithers are written to. 250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic void GenerateDitherQ7LbUB( 252fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t* bufQ7, 253fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint32_t seed, 254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int length) { 255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < length; k++) { 257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* new random unsigned int */ 258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org seed = (seed * 196314165) + 907633515; 259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Fixed-point dither sample between -64 and 64 (Q7). */ 261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* bufQ7 = seed * 128 / 4294967295 */ 262fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org bufQ7[k] = (int16_t)(((int)seed + 16777216) >> 25); 263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Scale by 0.35. */ 265fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org bufQ7[k] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(bufQ7[k], 2048, 13); 266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Function to decode the complex spectrum from the bit stream 271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * returns the total number of bytes in the stream. 272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 273fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsac_DecodeSpec(Bitstr* streamdata, int16_t AvgPitchGain_Q12, 274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enum ISACBand band, double* fr, double* fi) { 275fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t DitherQ7[FRAMESAMPLES]; 276fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t data[FRAMESAMPLES]; 277fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t invARSpec2_Q16[FRAMESAMPLES_QUARTER]; 278fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint16_t invARSpecQ8[FRAMESAMPLES_QUARTER]; 279fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t ARCoefQ12[AR_ORDER + 1]; 280fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t RCQ15[AR_ORDER]; 281fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t gainQ10; 282fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t gain2_Q10, res; 283fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t in_sqrt; 284fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t newRes; 285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k, len, i; 286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int is_12khz = !kIsSWB12; 287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int num_dft_coeff = FRAMESAMPLES; 288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Create dither signal. */ 289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (band == kIsacLowerBand) { 290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GenerateDitherQ7Lb(DitherQ7, streamdata->W_upper, FRAMESAMPLES, 291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org AvgPitchGain_Q12); 292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GenerateDitherQ7LbUB(DitherQ7, streamdata->W_upper, FRAMESAMPLES); 294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (band == kIsacUpperBand12) { 295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org is_12khz = kIsSWB12; 296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_dft_coeff = FRAMESAMPLES_HALF; 297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Decode model parameters. */ 301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (WebRtcIsac_DecodeRc(streamdata, RCQ15) < 0) 302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; 303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); 305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (WebRtcIsac_DecodeGain2(streamdata, &gain2_Q10) < 0) 307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; 308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Compute inverse AR power spectrum. */ 310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); 311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Convert to magnitude spectrum, 313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * by doing square-roots (modified from SPLIB). */ 314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org res = 1 << (WebRtcSpl_GetSizeInBits(invARSpec2_Q16[0]) >> 1); 315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < FRAMESAMPLES_QUARTER; k++) { 316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org in_sqrt = invARSpec2_Q16[k]; 317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org i = 10; 318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Negative values make no sense for a real sqrt-function. */ 320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (in_sqrt < 0) 321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org in_sqrt = -in_sqrt; 322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org newRes = (in_sqrt / res + res) >> 1; 324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org do { 325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org res = newRes; 326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org newRes = (in_sqrt / res + res) >> 1; 327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } while (newRes != res && i-- > 0); 328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 329fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org invARSpecQ8[k] = (int16_t)newRes; 330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org len = WebRtcIsac_DecLogisticMulti2(data, streamdata, invARSpecQ8, DitherQ7, 333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_dft_coeff, is_12khz); 334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Arithmetic decoding of spectrum. */ 335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (len < 1) { 336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; 337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch (band) { 340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kIsacLowerBand: { 341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Scale down spectral samples with low SNR. */ 342fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t p1; 343fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t p2; 344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (AvgPitchGain_Q12 <= 614) { 345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org p1 = 30 << 10; 346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org p2 = 32768 + (33 << 16); 347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org p1 = 36 << 10; 349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org p2 = 32768 + (40 << 16); 350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < FRAMESAMPLES; k += 4) { 352fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org gainQ10 = WebRtcSpl_DivW32W16ResW16(p1, (int16_t)( 353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (invARSpec2_Q16[k >> 2] + p2) >> 16)); 354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *fr++ = (double)((data[ k ] * gainQ10 + 512) >> 10) / 128.0; 355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *fi++ = (double)((data[k + 1] * gainQ10 + 512) >> 10) / 128.0; 356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *fr++ = (double)((data[k + 2] * gainQ10 + 512) >> 10) / 128.0; 357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *fi++ = (double)((data[k + 3] * gainQ10 + 512) >> 10) / 128.0; 358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kIsacUpperBand12: { 362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0, i = 0; k < FRAMESAMPLES_HALF; k += 4) { 363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fr[i] = (double)data[ k ] / 128.0; 364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fi[i] = (double)data[k + 1] / 128.0; 365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org i++; 366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fr[i] = (double)data[k + 2] / 128.0; 367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fi[i] = (double)data[k + 3] / 128.0; 368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org i++; 369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* The second half of real and imaginary coefficients is zero. This is 371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * due to using the old FFT module which requires two signals as input 372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * while in 0-12 kHz mode we only have 8-12 kHz band, and the second 373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * signal is set to zero. */ 374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(&fr[FRAMESAMPLES_QUARTER], 0, FRAMESAMPLES_QUARTER * 375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sizeof(double)); 376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(&fi[FRAMESAMPLES_QUARTER], 0, FRAMESAMPLES_QUARTER * 377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sizeof(double)); 378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kIsacUpperBand16: { 381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (i = 0, k = 0; k < FRAMESAMPLES; k += 4, i++) { 382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fr[i] = (double)data[ k ] / 128.0; 383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fi[i] = (double)data[k + 1] / 128.0; 384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fr[(FRAMESAMPLES_HALF) - 1 - i] = (double)data[k + 2] / 128.0; 385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fi[(FRAMESAMPLES_HALF) - 1 - i] = (double)data[k + 3] / 128.0; 386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return len; 391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 394fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsac_EncodeSpec(const int16_t* fr, const int16_t* fi, 395fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t AvgPitchGain_Q12, enum ISACBand band, 396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Bitstr* streamdata) { 397fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t ditherQ7[FRAMESAMPLES]; 398fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t dataQ7[FRAMESAMPLES]; 399fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t PSpec[FRAMESAMPLES_QUARTER]; 400fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t invARSpec2_Q16[FRAMESAMPLES_QUARTER]; 401fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint16_t invARSpecQ8[FRAMESAMPLES_QUARTER]; 402fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t CorrQ7[AR_ORDER + 1]; 403fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t CorrQ7_norm[AR_ORDER + 1]; 404fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t RCQ15[AR_ORDER]; 405fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t ARCoefQ12[AR_ORDER + 1]; 406fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t gain2_Q10; 407fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t val; 408fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t nrg, res; 409fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint32_t sum; 410fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t in_sqrt; 411fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t newRes; 412fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t err; 413fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint32_t nrg_u32; 414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int shift_var; 415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k, n, j, i; 416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int is_12khz = !kIsSWB12; 417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int num_dft_coeff = FRAMESAMPLES; 418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Create dither signal. */ 420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (band == kIsacLowerBand) { 421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GenerateDitherQ7Lb(ditherQ7, streamdata->W_upper, FRAMESAMPLES, 422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org AvgPitchGain_Q12); 423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GenerateDitherQ7LbUB(ditherQ7, streamdata->W_upper, FRAMESAMPLES); 425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (band == kIsacUpperBand12) { 426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org is_12khz = kIsSWB12; 427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_dft_coeff = FRAMESAMPLES_HALF; 428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* add dither and quantize, and compute power spectrum */ 432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch (band) { 433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kIsacLowerBand: { 434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < FRAMESAMPLES; k += 4) { 435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org val = ((*fr++ + ditherQ7[k] + 64) & 0xFF80) - ditherQ7[k]; 436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dataQ7[k] = val; 437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = val * val; 438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org val = ((*fi++ + ditherQ7[k + 1] + 64) & 0xFF80) - ditherQ7[k + 1]; 440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dataQ7[k + 1] = val; 441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += val * val; 442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org val = ((*fr++ + ditherQ7[k + 2] + 64) & 0xFF80) - ditherQ7[k + 2]; 444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dataQ7[k + 2] = val; 445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += val * val; 446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org val = ((*fi++ + ditherQ7[k + 3] + 64) & 0xFF80) - ditherQ7[k + 3]; 448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dataQ7[k + 3] = val; 449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += val * val; 450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PSpec[k >> 2] = sum >> 2; 452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kIsacUpperBand12: { 456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0, j = 0; k < FRAMESAMPLES_HALF; k += 4) { 457b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org val = ((*fr++ + ditherQ7[k] + 64) & 0xFF80) - ditherQ7[k]; 458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dataQ7[k] = val; 459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = val * val; 460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org val = ((*fi++ + ditherQ7[k + 1] + 64) & 0xFF80) - ditherQ7[k + 1]; 462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dataQ7[k + 1] = val; 463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += val * val; 464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PSpec[j++] = sum >> 1; 466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org val = ((*fr++ + ditherQ7[k + 2] + 64) & 0xFF80) - ditherQ7[k + 2]; 468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dataQ7[k + 2] = val; 469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = val * val; 470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org val = ((*fi++ + ditherQ7[k + 3] + 64) & 0xFF80) - ditherQ7[k + 3]; 472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dataQ7[k + 3] = val; 473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += val * val; 474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PSpec[j++] = sum >> 1; 476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kIsacUpperBand16: { 480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j = 0, k = 0; k < FRAMESAMPLES; k += 4, j++) { 481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org val = ((fr[j] + ditherQ7[k] + 64) & 0xFF80) - ditherQ7[k]; 482b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dataQ7[k] = val; 483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = val * val; 484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org val = ((fi[j] + ditherQ7[k + 1] + 64) & 0xFF80) - ditherQ7[k + 1]; 486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dataQ7[k + 1] = val; 487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += val * val; 488b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org val = ((fr[(FRAMESAMPLES_HALF) - 1 - j] + ditherQ7[k + 2] + 64) & 490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 0xFF80) - ditherQ7[k + 2]; 491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dataQ7[k + 2] = val; 492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += val * val; 493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org val = ((fi[(FRAMESAMPLES_HALF) - 1 - j] + ditherQ7[k + 3] + 64) & 495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 0xFF80) - ditherQ7[k + 3]; 496b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dataQ7[k + 3] = val; 497b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += val * val; 498b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 499b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PSpec[k >> 2] = sum >> 2; 500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 502b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 503b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 504b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* compute correlation from power spectrum */ 506b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org FindCorrelation(PSpec, CorrQ7); 507b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 508b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Find AR coefficients */ 509b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Aumber of bit shifts to 14-bit normalize CorrQ7[0] 510b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * (leaving room for sign) */ 511b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shift_var = WebRtcSpl_NormW32(CorrQ7[0]) - 18; 512b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 513b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (shift_var > 0) { 514b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < AR_ORDER + 1; k++) { 515b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CorrQ7_norm[k] = CorrQ7[k] << shift_var; 516b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 518b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < AR_ORDER + 1; k++) { 519b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CorrQ7_norm[k] = CorrQ7[k] >> (-shift_var); 520b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 521b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 522b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 523b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Find RC coefficients. */ 524b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcSpl_AutoCorrToReflCoef(CorrQ7_norm, AR_ORDER, RCQ15); 525b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 526b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Quantize & code RC Coefficient. */ 527b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncodeRc(RCQ15, streamdata); 528b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 529b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* RC -> AR coefficients */ 530b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); 531b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 532b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Compute ARCoef' * Corr * ARCoef in Q19. */ 533b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nrg = 0; 534b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j = 0; j <= AR_ORDER; j++) { 535b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n <= j; n++) { 536b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nrg += (ARCoefQ12[j] * ((CorrQ7_norm[j - n] * ARCoefQ12[n] + 256) >> 9) + 537b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 4) >> 3; 538b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 539b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = j + 1; n <= AR_ORDER; n++) { 540b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nrg += (ARCoefQ12[j] * ((CorrQ7_norm[n - j] * ARCoefQ12[n] + 256) >> 9) + 541b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 4) >> 3; 542b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 543b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 544b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 545fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org nrg_u32 = (uint32_t)nrg; 546b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (shift_var > 0) { 547b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nrg_u32 = nrg_u32 >> shift_var; 548b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 549b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nrg_u32 = nrg_u32 << (-shift_var); 550b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 551b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (nrg_u32 > 0x7FFFFFFF) { 552b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nrg = 0x7FFFFFFF; 553b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 554fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org nrg = (int32_t)nrg_u32; 555b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 556b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Also shifts 31 bits to the left! */ 557b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES_QUARTER, nrg); 558b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 559b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Quantize & code gain2_Q10. */ 560b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (WebRtcIsac_EncodeGain2(&gain2_Q10, streamdata)) { 561b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 562b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 563b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 564b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Compute inverse AR power spectrum. */ 565b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); 566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Convert to magnitude spectrum, by doing square-roots 567b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * (modified from SPLIB). */ 568b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org res = 1 << (WebRtcSpl_GetSizeInBits(invARSpec2_Q16[0]) >> 1); 569b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < FRAMESAMPLES_QUARTER; k++) { 570b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org in_sqrt = invARSpec2_Q16[k]; 571b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org i = 10; 572b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Negative values make no sense for a real sqrt-function. */ 573b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (in_sqrt < 0) { 574b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org in_sqrt = -in_sqrt; 575b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 576b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org newRes = (in_sqrt / res + res) >> 1; 577b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org do { 578b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org res = newRes; 579b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org newRes = (in_sqrt / res + res) >> 1; 580b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } while (newRes != res && i-- > 0); 581b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 582fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org invARSpecQ8[k] = (int16_t)newRes; 583b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 584b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* arithmetic coding of spectrum */ 585b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_EncLogisticMulti2(streamdata, dataQ7, invARSpecQ8, 586b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_dft_coeff, is_12khz); 587b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return (err); 589b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 590b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 591b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 592b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 593b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 594b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* step-up */ 595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid WebRtcIsac_Rc2Poly(double* RC, int N, double* a) { 596b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int m, k; 597b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double tmp[MAX_AR_MODEL_ORDER]; 598b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 599b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org a[0] = 1.0; 600b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp[0] = 1.0; 601b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (m = 1; m <= N; m++) { 602b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* copy */ 603b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&tmp[1], &a[1], (m - 1) * sizeof(double)); 604b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org a[m] = RC[m - 1]; 605b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 1; k < m; k++) { 606b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org a[k] += RC[m - 1] * tmp[m - k]; 607b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 608b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 609b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return; 610b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 611b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 612b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* step-down */ 613b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid WebRtcIsac_Poly2Rc(double* a, int N, double* RC) { 614b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int m, k; 615b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double tmp[MAX_AR_MODEL_ORDER]; 616b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double tmp_inv; 617b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 618b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RC[N - 1] = a[N]; 619b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (m = N - 1; m > 0; m--) { 620b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp_inv = 1.0 / (1.0 - RC[m] * RC[m]); 621b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 1; k <= m; k++) { 622b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp[k] = (a[k] - RC[m] * a[m - k + 1]) * tmp_inv; 623b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 624b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 625b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&a[1], &tmp[1], (m - 1) * sizeof(double)); 626b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RC[m - 1] = tmp[m]; 627b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 628b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return; 629b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 630b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 631b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 632b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define MAX_ORDER 100 633b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 634b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Matlab's LAR definition */ 635b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid WebRtcIsac_Rc2Lar(const double* refc, double* lar, int order) { 636b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 637b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < order; k++) { 638b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lar[k] = log((1 + refc[k]) / (1 - refc[k])); 639b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 640b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 641b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 642b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 643b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid WebRtcIsac_Lar2Rc(const double* lar, double* refc, int order) { 644b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 645b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double tmp; 646b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 647b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < order; k++) { 648b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp = exp(lar[k]); 649b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org refc[k] = (tmp - 1) / (tmp + 1); 650b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 651b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 652b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 653b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid WebRtcIsac_Poly2Lar(double* lowband, int orderLo, double* hiband, 654b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int orderHi, int Nsub, double* lars) { 655b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 656b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double rc[MAX_ORDER], *inpl, *inph, *outp; 657b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 658b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inpl = lowband; 659b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inph = hiband; 660b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outp = lars; 661b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < Nsub; k++) { 662b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* gains */ 663b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outp[0] = inpl[0]; 664b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outp[1] = inph[0]; 665b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outp += 2; 666b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 667b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Low band */ 668b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inpl[0] = 1.0; 669b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Poly2Rc(inpl, orderLo, rc); 670b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Rc2Lar(rc, outp, orderLo); 671b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outp += orderLo; 672b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 673b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* High band */ 674b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inph[0] = 1.0; 675b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Poly2Rc(inph, orderHi, rc); 676b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Rc2Lar(rc, outp, orderHi); 677b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outp += orderHi; 678b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 679b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inpl += orderLo + 1; 680b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inph += orderHi + 1; 681b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 682b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 683b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 684b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 685fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_Poly2LarUB(double* lpcVecs, int16_t bandwidth) { 686b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double poly[MAX_ORDER]; 687b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double rc[MAX_ORDER]; 688b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double* ptrIO; 689fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t vecCntr; 690fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t vecSize; 691fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t numVec; 692b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 693b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org vecSize = UB_LPC_ORDER; 694b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch (bandwidth) { 695b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case isac12kHz: { 696b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numVec = UB_LPC_VEC_PER_FRAME; 697b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 698b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 699b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case isac16kHz: { 700b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numVec = UB16_LPC_VEC_PER_FRAME; 701b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 702b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 703b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org default: 704b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 705b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 706b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 707b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ptrIO = lpcVecs; 708b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org poly[0] = 1.0; 709b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (vecCntr = 0; vecCntr < numVec; vecCntr++) { 710b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&poly[1], ptrIO, sizeof(double) * vecSize); 711b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Poly2Rc(poly, vecSize, rc); 712b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Rc2Lar(rc, ptrIO, vecSize); 713b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ptrIO += vecSize; 714b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 715b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 716b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 717b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 718b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 719b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid WebRtcIsac_Lar2Poly(double* lars, double* lowband, int orderLo, 720b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double* hiband, int orderHi, int Nsub) { 721b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k, orderTot; 722b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double rc[MAX_ORDER], *outpl, *outph, *inp; 723b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 724b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org orderTot = (orderLo + orderHi + 2); 725b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outpl = lowband; 726b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outph = hiband; 727b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* First two elements of 'inp' store gains*/ 728b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inp = lars; 729b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < Nsub; k++) { 730b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Low band */ 731b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Lar2Rc(&inp[2], rc, orderLo); 732b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Rc2Poly(rc, orderLo, outpl); 733b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 734b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* High band */ 735b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Lar2Rc(&inp[orderLo + 2], rc, orderHi); 736b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Rc2Poly(rc, orderHi, outph); 737b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 738b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* gains */ 739b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outpl[0] = inp[0]; 740b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outph[0] = inp[1]; 741b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 742b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outpl += orderLo + 1; 743b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outph += orderHi + 1; 744b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inp += orderTot; 745b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 746b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 747b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 748b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 749b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * assumes 2 LAR vectors interpolates to 'numPolyVec' A-polynomials 750b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Note: 'numPolyVecs' includes the first and the last point of the interval 751b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 752b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid WebRtcIsac_Lar2PolyInterpolUB(double* larVecs, double* percepFilterParams, 753b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int numPolyVecs) { 754b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int polyCntr, coeffCntr; 755b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double larInterpol[UB_LPC_ORDER]; 756b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double rc[UB_LPC_ORDER]; 757b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double delta[UB_LPC_ORDER]; 758b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 759b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* calculate the step-size for linear interpolation coefficients */ 760b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (coeffCntr = 0; coeffCntr < UB_LPC_ORDER; coeffCntr++) { 761b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delta[coeffCntr] = (larVecs[UB_LPC_ORDER + coeffCntr] - 762b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org larVecs[coeffCntr]) / (numPolyVecs - 1); 763b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 764b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 765b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (polyCntr = 0; polyCntr < numPolyVecs; polyCntr++) { 766b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (coeffCntr = 0; coeffCntr < UB_LPC_ORDER; coeffCntr++) { 767b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org larInterpol[coeffCntr] = larVecs[coeffCntr] + 768b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delta[coeffCntr] * polyCntr; 769b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 770b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Lar2Rc(larInterpol, rc, UB_LPC_ORDER); 771b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 772b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* convert to A-polynomial, the following function returns A[0] = 1; 773b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * which is written where gains had to be written. Then we write the 774b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * gain (outside this function). This way we say a memcpy. */ 775b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Rc2Poly(rc, UB_LPC_ORDER, percepFilterParams); 776b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org percepFilterParams += (UB_LPC_ORDER + 1); 777b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 778b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 779b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 780b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint WebRtcIsac_DecodeLpc(Bitstr* streamdata, double* LPCCoef_lo, 781b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double* LPCCoef_hi) { 782b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double lars[KLT_ORDER_GAIN + KLT_ORDER_SHAPE]; 783b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int err; 784b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 785b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_DecodeLpcCoef(streamdata, lars); 786b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 787b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_LPC; 788b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 789b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Lar2Poly(lars, LPCCoef_lo, ORDERLO, LPCCoef_hi, ORDERHI, 790b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SUBFRAMES); 791b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 792b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 793b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 794fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_DecodeInterpolLpcUb(Bitstr* streamdata, 795fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org double* percepFilterParams, 796fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t bandwidth) { 797b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double lpcCoeff[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME]; 798b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int err; 799b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int interpolCntr; 800b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int subframeCntr; 801fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t numSegments; 802fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t numVecPerSegment; 803fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t numGains; 804b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 805b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double percepFilterGains[SUBFRAMES << 1]; 806b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double* ptrOutParam = percepFilterParams; 807b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 808b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_DecodeLpcCoefUB(streamdata, lpcCoeff, percepFilterGains, 809b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bandwidth); 810b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 811b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_LPC; 812b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 813b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 814b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch (bandwidth) { 815b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case isac12kHz: { 816b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numGains = SUBFRAMES; 817b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numSegments = UB_LPC_VEC_PER_FRAME - 1; 818b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numVecPerSegment = kLpcVecPerSegmentUb12; 819b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 820b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 821b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case isac16kHz: { 822b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numGains = SUBFRAMES << 1; 823b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numSegments = UB16_LPC_VEC_PER_FRAME - 1; 824b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numVecPerSegment = kLpcVecPerSegmentUb16; 825b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 826b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 827b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org default: 828b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 829b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 830b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 831b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (interpolCntr = 0; interpolCntr < numSegments; interpolCntr++) { 832b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Lar2PolyInterpolUB(&lpcCoeff[interpolCntr * UB_LPC_ORDER], 833b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ptrOutParam, numVecPerSegment + 1); 834b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ptrOutParam += (numVecPerSegment * (UB_LPC_ORDER + 1)); 835b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 836b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 837b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ptrOutParam = percepFilterParams; 838b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 839b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (bandwidth == isac16kHz) { 840b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ptrOutParam += (1 + UB_LPC_ORDER); 841b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 842b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 843b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (subframeCntr = 0; subframeCntr < numGains; subframeCntr++) { 844b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *ptrOutParam = percepFilterGains[subframeCntr]; 845b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ptrOutParam += (1 + UB_LPC_ORDER); 846b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 847b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 848b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 849b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 850b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 851b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* decode & dequantize LPC Coef */ 852b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint WebRtcIsac_DecodeLpcCoef(Bitstr* streamdata, double* LPCCoef) { 853b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int j, k, n, pos, pos2, posg, poss, offsg, offss, offs2; 854b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int index_g[KLT_ORDER_GAIN], index_s[KLT_ORDER_SHAPE]; 855b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double tmpcoeffs_g[KLT_ORDER_GAIN], tmpcoeffs_s[KLT_ORDER_SHAPE]; 856b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double tmpcoeffs2_g[KLT_ORDER_GAIN], tmpcoeffs2_s[KLT_ORDER_SHAPE]; 857b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double sum; 858b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int err; 859b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int model = 1; 860b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 861b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy decoding of model number */ 862b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* We are keeping this for backward compatibility of bit-streams. */ 863b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_DecHistOneStepMulti(&model, streamdata, 864b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kQKltModelCdfPtr, 865b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kQKltModelInitIndex, 1); 866b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 867b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 868b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 869b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Only accepted value of model is 0. It is kept in bit-stream for backward 870b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * compatibility. */ 871b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (model != 0) { 872b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_DISALLOWED_LPC_MODEL; 873b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 874b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 875b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy decoding of quantization indices */ 876b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_DecHistOneStepMulti( 877b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_s, streamdata, WebRtcIsac_kQKltCdfPtrShape, 878b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kQKltInitIndexShape, KLT_ORDER_SHAPE); 879b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 880b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 881b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 882b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_DecHistOneStepMulti( 883b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_g, streamdata, WebRtcIsac_kQKltCdfPtrGain, 884b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kQKltInitIndexGain, KLT_ORDER_GAIN); 885b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 886b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 887b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 888b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 889b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* find quantization levels for coefficients */ 890b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < KLT_ORDER_SHAPE; k++) { 891b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_s[k] = 892b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kQKltLevelsShape[WebRtcIsac_kQKltOffsetShape[k] + 893b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_s[k]]; 894b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 895b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < KLT_ORDER_GAIN; k++) { 896b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_g[k] = WebRtcIsac_kQKltLevelsGain[WebRtcIsac_kQKltOffsetGain[k] + 897b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_g[k]]; 898b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 899b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 900b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Inverse KLT */ 901b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 902b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Left transform, transpose matrix! */ 903b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offsg = 0; 904b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offss = 0; 905b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg = 0; 906b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org poss = 0; 907b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j = 0; j < SUBFRAMES; j++) { 908b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offs2 = 0; 909b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < LPC_GAIN_ORDER; k++) { 910b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 911b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos = offsg; 912b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 = offs2; 913b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < LPC_GAIN_ORDER; n++) { 914b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += tmpcoeffs_g[pos++] * WebRtcIsac_kKltT1Gain[pos2++]; 915b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 916b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs2_g[posg++] = sum; 917b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offs2 += LPC_GAIN_ORDER; 918b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 919b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offs2 = 0; 920b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < LPC_SHAPE_ORDER; k++) { 921b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 922b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos = offss; 923b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 = offs2; 924b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < LPC_SHAPE_ORDER; n++) { 925b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += tmpcoeffs_s[pos++] * WebRtcIsac_kKltT1Shape[pos2++]; 926b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 927b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs2_s[poss++] = sum; 928b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offs2 += LPC_SHAPE_ORDER; 929b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 930b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offsg += LPC_GAIN_ORDER; 931b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offss += LPC_SHAPE_ORDER; 932b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 933b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 934b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Right transform, transpose matrix */ 935b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offsg = 0; 936b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offss = 0; 937b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg = 0; 938b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org poss = 0; 939b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j = 0; j < SUBFRAMES; j++) { 940b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg = offsg; 941b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < LPC_GAIN_ORDER; k++) { 942b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 943b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos = k; 944b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 = j; 945b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < SUBFRAMES; n++) { 946b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += tmpcoeffs2_g[pos] * WebRtcIsac_kKltT2Gain[pos2]; 947b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += LPC_GAIN_ORDER; 948b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 += SUBFRAMES; 949b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 950b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 951b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_g[posg++] = sum; 952b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 953b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org poss = offss; 954b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < LPC_SHAPE_ORDER; k++) { 955b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 956b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos = k; 957b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 = j; 958b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < SUBFRAMES; n++) { 959b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += tmpcoeffs2_s[pos] * WebRtcIsac_kKltT2Shape[pos2]; 960b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += LPC_SHAPE_ORDER; 961b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 += SUBFRAMES; 962b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 963b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_s[poss++] = sum; 964b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 965b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offsg += LPC_GAIN_ORDER; 966b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offss += LPC_SHAPE_ORDER; 967b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 968b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 969b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* scaling, mean addition, and gain restoration */ 970b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg = 0; 971b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org poss = 0; 972b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos = 0; 973b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < SUBFRAMES; k++) { 974b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* log gains */ 975b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoef[pos] = tmpcoeffs_g[posg] / LPC_GAIN_SCALE; 976b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoef[pos] += WebRtcIsac_kLpcMeansGain[posg]; 977b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoef[pos] = exp(LPCCoef[pos]); 978b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++; 979b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg++; 980b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoef[pos] = tmpcoeffs_g[posg] / LPC_GAIN_SCALE; 981b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoef[pos] += WebRtcIsac_kLpcMeansGain[posg]; 982b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoef[pos] = exp(LPCCoef[pos]); 983b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++; 984b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg++; 985b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 986b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Low-band LAR coefficients. */ 987b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < LPC_LOBAND_ORDER; n++, pos++, poss++) { 988b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoef[pos] = tmpcoeffs_s[poss] / LPC_LOBAND_SCALE; 989b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoef[pos] += WebRtcIsac_kLpcMeansShape[poss]; 990b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 991b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 992b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* High-band LAR coefficients. */ 993b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < LPC_HIBAND_ORDER; n++, pos++, poss++) { 994b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoef[pos] = tmpcoeffs_s[poss] / LPC_HIBAND_SCALE; 995b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoef[pos] += WebRtcIsac_kLpcMeansShape[poss]; 996b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 997b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 998b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 999b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1000b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1001b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Encode LPC in LAR domain. */ 1002b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid WebRtcIsac_EncodeLar(double* LPCCoef, Bitstr* streamdata, 1003b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISAC_SaveEncData_t* encData) { 1004b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int j, k, n, pos, pos2, poss, offss, offs2; 1005b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int index_s[KLT_ORDER_SHAPE]; 1006b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int index_ovr_s[KLT_ORDER_SHAPE]; 1007b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double tmpcoeffs_s[KLT_ORDER_SHAPE]; 1008b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double tmpcoeffs2_s[KLT_ORDER_SHAPE]; 1009b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double sum; 1010b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const int kModel = 0; 1011b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1012b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Mean removal and scaling. */ 1013b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org poss = 0; 1014b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos = 0; 1015b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < SUBFRAMES; k++) { 1016b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* First two element are gains, move over them. */ 1017b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 2; 1018b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1019b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Low-band LAR coefficients. */ 1020b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < LPC_LOBAND_ORDER; n++, poss++, pos++) { 1021b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_s[poss] = LPCCoef[pos] - WebRtcIsac_kLpcMeansShape[poss]; 1022b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_s[poss] *= LPC_LOBAND_SCALE; 1023b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1024b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1025b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* High-band LAR coefficients. */ 1026b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < LPC_HIBAND_ORDER; n++, poss++, pos++) { 1027b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_s[poss] = LPCCoef[pos] - WebRtcIsac_kLpcMeansShape[poss]; 1028b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_s[poss] *= LPC_HIBAND_SCALE; 1029b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1030b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1031b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1032b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* KLT */ 1033b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1034b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Left transform. */ 1035b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offss = 0; 1036b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j = 0; j < SUBFRAMES; j++) { 1037b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org poss = offss; 1038b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < LPC_SHAPE_ORDER; k++) { 1039b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 1040b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos = offss; 1041b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 = k; 1042b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < LPC_SHAPE_ORDER; n++) { 1043b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += tmpcoeffs_s[pos++] * WebRtcIsac_kKltT1Shape[pos2]; 1044b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 += LPC_SHAPE_ORDER; 1045b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1046b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs2_s[poss++] = sum; 1047b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1048b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offss += LPC_SHAPE_ORDER; 1049b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1050b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1051b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Right transform. */ 1052b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offss = 0; 1053b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offs2 = 0; 1054b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j = 0; j < SUBFRAMES; j++) { 1055b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org poss = offss; 1056b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < LPC_SHAPE_ORDER; k++) { 1057b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 1058b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos = k; 1059b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 = offs2; 1060b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < SUBFRAMES; n++) { 1061b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += tmpcoeffs2_s[pos] * WebRtcIsac_kKltT2Shape[pos2++]; 1062b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += LPC_SHAPE_ORDER; 1063b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1064b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_s[poss++] = sum; 1065b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1066b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offs2 += SUBFRAMES; 1067b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offss += LPC_SHAPE_ORDER; 1068b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1069b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1070b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Quantize coefficients. */ 1071b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < KLT_ORDER_SHAPE; k++) { 1072b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_s[k] = (WebRtcIsac_lrint(tmpcoeffs_s[k] / KLT_STEPSIZE)) + 1073b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kQKltQuantMinShape[k]; 1074b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (index_s[k] < 0) { 1075b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_s[k] = 0; 1076b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (index_s[k] > WebRtcIsac_kQKltMaxIndShape[k]) { 1077b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_s[k] = WebRtcIsac_kQKltMaxIndShape[k]; 1078b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1079b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_ovr_s[k] = WebRtcIsac_kQKltOffsetShape[k] + index_s[k]; 1080b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1081b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1082b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1083b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Only one model remains in this version of the code, kModel = 0. We 1084b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * are keeping for bit-streams to be backward compatible. */ 1085b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy coding of model number */ 1086b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(streamdata, &kModel, WebRtcIsac_kQKltModelCdfPtr, 1); 1087b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1088b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save data for creation of multiple bit streams */ 1089b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Entropy coding of quantization indices - shape only. */ 1090b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(streamdata, index_s, WebRtcIsac_kQKltCdfPtrShape, 1091b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org KLT_ORDER_SHAPE); 1092b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1093b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save data for creation of multiple bit streams. */ 1094b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < KLT_ORDER_SHAPE; k++) { 1095b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org encData->LPCindex_s[KLT_ORDER_SHAPE * encData->startIdx + k] = index_s[k]; 1096b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1097b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1098b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Find quantization levels for shape coefficients. */ 1099b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < KLT_ORDER_SHAPE; k++) { 1100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_s[k] = WebRtcIsac_kQKltLevelsShape[index_ovr_s[k]]; 1101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Inverse KLT. */ 1103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Left transform, transpose matrix.! */ 1104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offss = 0; 1105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org poss = 0; 1106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j = 0; j < SUBFRAMES; j++) { 1107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offs2 = 0; 1108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < LPC_SHAPE_ORDER; k++) { 1109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 1110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos = offss; 1111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 = offs2; 1112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < LPC_SHAPE_ORDER; n++) { 1113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += tmpcoeffs_s[pos++] * WebRtcIsac_kKltT1Shape[pos2++]; 1114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs2_s[poss++] = sum; 1116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offs2 += LPC_SHAPE_ORDER; 1117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offss += LPC_SHAPE_ORDER; 1119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Right transform, Transpose matrix */ 1122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offss = 0; 1123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org poss = 0; 1124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j = 0; j < SUBFRAMES; j++) { 1125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org poss = offss; 1126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < LPC_SHAPE_ORDER; k++) { 1127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 1128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos = k; 1129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 = j; 1130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < SUBFRAMES; n++) { 1131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += tmpcoeffs2_s[pos] * WebRtcIsac_kKltT2Shape[pos2]; 1132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += LPC_SHAPE_ORDER; 1133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 += SUBFRAMES; 1134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_s[poss++] = sum; 1136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offss += LPC_SHAPE_ORDER; 1138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Scaling, mean addition, and gain restoration. */ 1141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org poss = 0; 1142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos = 0; 1143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < SUBFRAMES; k++) { 1144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Ignore gains. */ 1145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += 2; 1146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Low band LAR coefficients. */ 1148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < LPC_LOBAND_ORDER; n++, pos++, poss++) { 1149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoef[pos] = tmpcoeffs_s[poss] / LPC_LOBAND_SCALE; 1150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoef[pos] += WebRtcIsac_kLpcMeansShape[poss]; 1151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* High band LAR coefficients. */ 1154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < LPC_HIBAND_ORDER; n++, pos++, poss++) { 1155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoef[pos] = tmpcoeffs_s[poss] / LPC_HIBAND_SCALE; 1156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoef[pos] += WebRtcIsac_kLpcMeansShape[poss]; 1157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid WebRtcIsac_EncodeLpcLb(double* LPCCoef_lo, double* LPCCoef_hi, 1163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Bitstr* streamdata, ISAC_SaveEncData_t* encData) { 1164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double lars[KLT_ORDER_GAIN + KLT_ORDER_SHAPE]; 1165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 1166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Poly2Lar(LPCCoef_lo, ORDERLO, LPCCoef_hi, ORDERHI, SUBFRAMES, 1168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lars); 1169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncodeLar(lars, streamdata, encData); 1170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Lar2Poly(lars, LPCCoef_lo, ORDERLO, LPCCoef_hi, ORDERHI, 1171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SUBFRAMES); 1172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save data for creation of multiple bit streams (and transcoding). */ 1173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < (ORDERLO + 1)*SUBFRAMES; k++) { 1174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org encData->LPCcoeffs_lo[(ORDERLO + 1)*SUBFRAMES * encData->startIdx + k] = 1175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoef_lo[k]; 1176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < (ORDERHI + 1)*SUBFRAMES; k++) { 1178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org encData->LPCcoeffs_hi[(ORDERHI + 1)*SUBFRAMES * encData->startIdx + k] = 1179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoef_hi[k]; 1180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1184fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_EncodeLpcUB(double* lpcVecs, Bitstr* streamdata, 1185fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org double* interpolLPCCoeff, 1186fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t bandwidth, 1187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACUBSaveEncDataStruct* encData) { 1188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double U[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME]; 1189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int idx[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME]; 1190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int interpolCntr; 1191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Poly2LarUB(lpcVecs, bandwidth); 1193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_RemoveLarMean(lpcVecs, bandwidth); 1194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_DecorrelateIntraVec(lpcVecs, U, bandwidth); 1195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_DecorrelateInterVec(U, lpcVecs, bandwidth); 1196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_QuantizeUncorrLar(lpcVecs, idx, bandwidth); 1197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_CorrelateInterVec(lpcVecs, U, bandwidth); 1199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_CorrelateIntraVec(U, lpcVecs, bandwidth); 1200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_AddLarMean(lpcVecs, bandwidth); 1201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch (bandwidth) { 1203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case isac12kHz: { 1204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store the indices to be used for multiple encoding. */ 1205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(encData->indexLPCShape, idx, UB_LPC_ORDER * 1206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UB_LPC_VEC_PER_FRAME * sizeof(int)); 1207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(streamdata, idx, WebRtcIsac_kLpcShapeCdfMatUb12, 1208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME); 1209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (interpolCntr = 0; interpolCntr < UB_INTERPOL_SEGMENTS; 1210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org interpolCntr++) { 1211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Lar2PolyInterpolUB(lpcVecs, interpolLPCCoeff, 1212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kLpcVecPerSegmentUb12 + 1); 1213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lpcVecs += UB_LPC_ORDER; 1214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org interpolLPCCoeff += (kLpcVecPerSegmentUb12 * (UB_LPC_ORDER + 1)); 1215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 1217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case isac16kHz: { 1219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store the indices to be used for multiple encoding. */ 1220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(encData->indexLPCShape, idx, UB_LPC_ORDER * 1221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UB16_LPC_VEC_PER_FRAME * sizeof(int)); 1222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(streamdata, idx, WebRtcIsac_kLpcShapeCdfMatUb16, 1223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME); 1224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (interpolCntr = 0; interpolCntr < UB16_INTERPOL_SEGMENTS; 1225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org interpolCntr++) { 1226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Lar2PolyInterpolUB(lpcVecs, interpolLPCCoeff, 1227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kLpcVecPerSegmentUb16 + 1); 1228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lpcVecs += UB_LPC_ORDER; 1229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org interpolLPCCoeff += (kLpcVecPerSegmentUb16 * (UB_LPC_ORDER + 1)); 1230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 1232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org default: 1234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid WebRtcIsac_EncodeLpcGainLb(double* LPCCoef_lo, double* LPCCoef_hi, 1240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Bitstr* streamdata, 1241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISAC_SaveEncData_t* encData) { 1242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int j, k, n, pos, pos2, posg, offsg, offs2; 1243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int index_g[KLT_ORDER_GAIN]; 1244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int index_ovr_g[KLT_ORDER_GAIN]; 1245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double tmpcoeffs_g[KLT_ORDER_GAIN]; 1246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double tmpcoeffs2_g[KLT_ORDER_GAIN]; 1247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double sum; 1248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* log gains, mean removal and scaling */ 1249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg = 0; 1250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < SUBFRAMES; k++) { 1251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_g[posg] = log(LPCCoef_lo[(LPC_LOBAND_ORDER + 1) * k]); 1252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_g[posg] -= WebRtcIsac_kLpcMeansGain[posg]; 1253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_g[posg] *= LPC_GAIN_SCALE; 1254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg++; 1255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_g[posg] = log(LPCCoef_hi[(LPC_HIBAND_ORDER + 1) * k]); 1256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_g[posg] -= WebRtcIsac_kLpcMeansGain[posg]; 1257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_g[posg] *= LPC_GAIN_SCALE; 1258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg++; 1259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* KLT */ 1262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Left transform. */ 1264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offsg = 0; 1265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j = 0; j < SUBFRAMES; j++) { 1266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg = offsg; 1267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < LPC_GAIN_ORDER; k++) { 1268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 1269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos = offsg; 1270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 = k; 1271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < LPC_GAIN_ORDER; n++) { 1272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += tmpcoeffs_g[pos++] * WebRtcIsac_kKltT1Gain[pos2]; 1273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 += LPC_GAIN_ORDER; 1274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs2_g[posg++] = sum; 1276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offsg += LPC_GAIN_ORDER; 1278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Right transform. */ 1281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offsg = 0; 1282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offs2 = 0; 1283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j = 0; j < SUBFRAMES; j++) { 1284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg = offsg; 1285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < LPC_GAIN_ORDER; k++) { 1286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 1287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos = k; 1288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 = offs2; 1289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < SUBFRAMES; n++) { 1290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += tmpcoeffs2_g[pos] * WebRtcIsac_kKltT2Gain[pos2++]; 1291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += LPC_GAIN_ORDER; 1292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_g[posg++] = sum; 1294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offs2 += SUBFRAMES; 1296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offsg += LPC_GAIN_ORDER; 1297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Quantize coefficients. */ 1300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < KLT_ORDER_GAIN; k++) { 1301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Get index. */ 1302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 = WebRtcIsac_lrint(tmpcoeffs_g[k] / KLT_STEPSIZE); 1303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_g[k] = (pos2) + WebRtcIsac_kQKltQuantMinGain[k]; 1304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (index_g[k] < 0) { 1305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_g[k] = 0; 1306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (index_g[k] > WebRtcIsac_kQKltMaxIndGain[k]) { 1307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_g[k] = WebRtcIsac_kQKltMaxIndGain[k]; 1308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_ovr_g[k] = WebRtcIsac_kQKltOffsetGain[k] + index_g[k]; 1310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Find quantization levels for coefficients. */ 1312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_g[k] = WebRtcIsac_kQKltLevelsGain[index_ovr_g[k]]; 1313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save data for creation of multiple bit streams. */ 1315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org encData->LPCindex_g[KLT_ORDER_GAIN * encData->startIdx + k] = index_g[k]; 1316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Entropy coding of quantization indices - gain. */ 1319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(streamdata, index_g, WebRtcIsac_kQKltCdfPtrGain, 1320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org KLT_ORDER_GAIN); 1321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Find quantization levels for coefficients. */ 1323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Left transform. */ 1324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offsg = 0; 1325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg = 0; 1326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j = 0; j < SUBFRAMES; j++) { 1327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offs2 = 0; 1328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < LPC_GAIN_ORDER; k++) { 1329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 1330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos = offsg; 1331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 = offs2; 1332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < LPC_GAIN_ORDER; n++) 1333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += tmpcoeffs_g[pos++] * WebRtcIsac_kKltT1Gain[pos2++]; 1334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs2_g[posg++] = sum; 1335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offs2 += LPC_GAIN_ORDER; 1336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offsg += LPC_GAIN_ORDER; 1338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Right transform, transpose matrix. */ 1341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offsg = 0; 1342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg = 0; 1343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j = 0; j < SUBFRAMES; j++) { 1344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg = offsg; 1345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < LPC_GAIN_ORDER; k++) { 1346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 1347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos = k; 1348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 = j; 1349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < SUBFRAMES; n++) { 1350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += tmpcoeffs2_g[pos] * WebRtcIsac_kKltT2Gain[pos2]; 1351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += LPC_GAIN_ORDER; 1352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 += SUBFRAMES; 1353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_g[posg++] = sum; 1355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offsg += LPC_GAIN_ORDER; 1357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Scaling, mean addition, and gain restoration. */ 1361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg = 0; 1362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < SUBFRAMES; k++) { 1363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = tmpcoeffs_g[posg] / LPC_GAIN_SCALE; 1364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += WebRtcIsac_kLpcMeansGain[posg]; 1365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoef_lo[k * (LPC_LOBAND_ORDER + 1)] = exp(sum); 1366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++; 1367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg++; 1368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = tmpcoeffs_g[posg] / LPC_GAIN_SCALE; 1369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += WebRtcIsac_kLpcMeansGain[posg]; 1370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LPCCoef_hi[k * (LPC_HIBAND_ORDER + 1)] = exp(sum); 1371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos++; 1372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg++; 1373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid WebRtcIsac_EncodeLpcGainUb(double* lpGains, Bitstr* streamdata, 1378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int* lpcGainIndex) { 1379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double U[UB_LPC_GAIN_DIM]; 1380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int idx[UB_LPC_GAIN_DIM]; 1381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_ToLogDomainRemoveMean(lpGains); 1382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_DecorrelateLPGain(lpGains, U); 1383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_QuantizeLpcGain(U, idx); 1384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store the index for re-encoding for FEC. */ 1385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(lpcGainIndex, idx, UB_LPC_GAIN_DIM * sizeof(int)); 1386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_CorrelateLpcGain(U, lpGains); 1387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_AddMeanToLinearDomain(lpGains); 1388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(streamdata, idx, WebRtcIsac_kLpcGainCdfMat, 1389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UB_LPC_GAIN_DIM); 1390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid WebRtcIsac_StoreLpcGainUb(double* lpGains, Bitstr* streamdata) { 1394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double U[UB_LPC_GAIN_DIM]; 1395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int idx[UB_LPC_GAIN_DIM]; 1396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_ToLogDomainRemoveMean(lpGains); 1397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_DecorrelateLPGain(lpGains, U); 1398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_QuantizeLpcGain(U, idx); 1399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(streamdata, idx, WebRtcIsac_kLpcGainCdfMat, 1400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UB_LPC_GAIN_DIM); 1401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1405fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_DecodeLpcGainUb(double* lpGains, Bitstr* streamdata) { 1406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double U[UB_LPC_GAIN_DIM]; 1407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int idx[UB_LPC_GAIN_DIM]; 1408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int err; 1409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_DecHistOneStepMulti(idx, streamdata, 1410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kLpcGainCdfMat, 1411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kLpcGainEntropySearch, 1412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UB_LPC_GAIN_DIM); 1413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 1414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_DequantizeLpcGain(idx, U); 1417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_CorrelateLpcGain(U, lpGains); 1418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_AddMeanToLinearDomain(lpGains); 1419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* decode & dequantize RC */ 1425fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsac_DecodeRc(Bitstr* streamdata, int16_t* RCQ15) { 1426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k, err; 1427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int index[AR_ORDER]; 1428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy decoding of quantization indices */ 1430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_DecHistOneStepMulti(index, streamdata, 1431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kQArRcCdfPtr, 1432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kQArRcInitIndex, AR_ORDER); 1433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) 1434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 1435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* find quantization levels for reflection coefficients */ 1437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < AR_ORDER; k++) { 1438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RCQ15[k] = *(WebRtcIsac_kQArRcLevelsPtr[k] + index[k]); 1439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* quantize & code RC */ 1445fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgvoid WebRtcIsac_EncodeRc(int16_t* RCQ15, Bitstr* streamdata) { 1446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 1447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int index[AR_ORDER]; 1448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* quantize reflection coefficients (add noise feedback?) */ 1450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < AR_ORDER; k++) { 1451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index[k] = WebRtcIsac_kQArRcInitIndex[k]; 1452febbabbdb781402c24d22b29980396445b10d725turaj@webrtc.org // The safe-guards in following while conditions are to suppress gcc 4.8.3 1453febbabbdb781402c24d22b29980396445b10d725turaj@webrtc.org // warnings, Issue 2888. Otherwise, first and last elements of 1454febbabbdb781402c24d22b29980396445b10d725turaj@webrtc.org // |WebRtcIsac_kQArBoundaryLevels| are such that the following search 1455febbabbdb781402c24d22b29980396445b10d725turaj@webrtc.org // *never* cause an out-of-boundary read. 1456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (RCQ15[k] > WebRtcIsac_kQArBoundaryLevels[index[k]]) { 1457febbabbdb781402c24d22b29980396445b10d725turaj@webrtc.org while (index[k] + 1 < NUM_AR_RC_QUANT_BAUNDARY && 1458febbabbdb781402c24d22b29980396445b10d725turaj@webrtc.org RCQ15[k] > WebRtcIsac_kQArBoundaryLevels[index[k] + 1]) { 1459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index[k]++; 1460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1462febbabbdb781402c24d22b29980396445b10d725turaj@webrtc.org while (index[k] > 0 && 1463febbabbdb781402c24d22b29980396445b10d725turaj@webrtc.org RCQ15[k] < WebRtcIsac_kQArBoundaryLevels[--index[k]]) ; 1464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RCQ15[k] = *(WebRtcIsac_kQArRcLevelsPtr[k] + index[k]); 1466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy coding of quantization indices */ 1469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(streamdata, index, WebRtcIsac_kQArRcCdfPtr, AR_ORDER); 1470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* decode & dequantize squared Gain */ 1474fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsac_DecodeGain2(Bitstr* streamdata, int32_t* gainQ10) { 1475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int index, err; 1476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy decoding of quantization index */ 1478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_DecHistOneStepMulti(&index, streamdata, 1479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kQGainCdf_ptr, 1480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kQGainInitIndex, 1); 1481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 1482b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 1483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* find quantization level */ 1485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *gainQ10 = WebRtcIsac_kQGain2Levels[index]; 1486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1488b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* quantize & code squared Gain */ 1491fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsac_EncodeGain2(int32_t* gainQ10, Bitstr* streamdata) { 1492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int index; 1493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* find quantization index */ 1495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index = WebRtcIsac_kQGainInitIndex[0]; 1496b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (*gainQ10 > WebRtcIsac_kQGain2BoundaryLevels[index]) { 1497b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while (*gainQ10 > WebRtcIsac_kQGain2BoundaryLevels[index + 1]) { 1498b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index++; 1499b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while (*gainQ10 < WebRtcIsac_kQGain2BoundaryLevels[--index]) ; 1502b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1503b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* De-quantize */ 1504b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *gainQ10 = WebRtcIsac_kQGain2Levels[index]; 1505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1506b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy coding of quantization index */ 1507b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(streamdata, &index, WebRtcIsac_kQGainCdf_ptr, 1); 1508b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1509b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1510b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1511b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1512b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* code and decode Pitch Gains and Lags functions */ 1513b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1514b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* decode & dequantize Pitch Gains */ 1515b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint WebRtcIsac_DecodePitchGain(Bitstr* streamdata, 1516fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t* PitchGains_Q12) { 1517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int index_comb, err; 1518fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const uint16_t* WebRtcIsac_kQPitchGainCdf_ptr[1]; 1519b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1520b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Entropy decoding of quantization indices */ 1521b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *WebRtcIsac_kQPitchGainCdf_ptr = WebRtcIsac_kQPitchGainCdf; 1522b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_DecHistBisectMulti(&index_comb, streamdata, 1523b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kQPitchGainCdf_ptr, 1524b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kQCdfTableSizeGain, 1); 1525b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Error check, Q_mean_Gain.. tables are of size 144 */ 1526b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((err < 0) || (index_comb < 0) || (index_comb >= 144)) { 1527b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_PITCH_GAIN; 1528b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1529b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* De-quantize back to pitch gains by table look-up. */ 1530b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains_Q12[0] = WebRtcIsac_kQMeanGain1Q12[index_comb]; 1531b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains_Q12[1] = WebRtcIsac_kQMeanGain2Q12[index_comb]; 1532b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains_Q12[2] = WebRtcIsac_kQMeanGain3Q12[index_comb]; 1533b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains_Q12[3] = WebRtcIsac_kQMeanGain4Q12[index_comb]; 1534b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1535b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1536b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1537b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1538b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Quantize & code Pitch Gains. */ 1539fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgvoid WebRtcIsac_EncodePitchGain(int16_t* PitchGains_Q12, 1540b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Bitstr* streamdata, 1541b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISAC_SaveEncData_t* encData) { 1542b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k, j; 1543b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double C; 1544b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double S[PITCH_SUBFRAMES]; 1545b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int index[3]; 1546b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int index_comb; 1547fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const uint16_t* WebRtcIsac_kQPitchGainCdf_ptr[1]; 1548b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double PitchGains[PITCH_SUBFRAMES] = {0, 0, 0, 0}; 1549b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1550b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Take the asin. */ 1551b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < PITCH_SUBFRAMES; k++) { 1552b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains[k] = ((float)PitchGains_Q12[k]) / 4096; 1553b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org S[k] = asin(PitchGains[k]); 1554b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1555b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1556b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Find quantization index; only for the first three 1557b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * transform coefficients. */ 1558b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < 3; k++) { 1559b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* transform */ 1560b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org C = 0.0; 1561b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j = 0; j < PITCH_SUBFRAMES; j++) { 1562b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org C += WebRtcIsac_kTransform[k][j] * S[j]; 1563b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1564b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Quantize */ 1565b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index[k] = WebRtcIsac_lrint(C / PITCH_GAIN_STEPSIZE); 1566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1567b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Check that the index is not outside the boundaries of the table. */ 1568b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (index[k] < WebRtcIsac_kIndexLowerLimitGain[k]) { 1569b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index[k] = WebRtcIsac_kIndexLowerLimitGain[k]; 1570b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (index[k] > WebRtcIsac_kIndexUpperLimitGain[k]) { 1571b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index[k] = WebRtcIsac_kIndexUpperLimitGain[k]; 1572b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1573b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index[k] -= WebRtcIsac_kIndexLowerLimitGain[k]; 1574b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1575b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1576b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Calculate unique overall index. */ 1577b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_comb = WebRtcIsac_kIndexMultsGain[0] * index[0] + 1578b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kIndexMultsGain[1] * index[1] + index[2]; 1579b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1580b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* unquantize back to pitch gains by table look-up */ 1581b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains_Q12[0] = WebRtcIsac_kQMeanGain1Q12[index_comb]; 1582b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains_Q12[1] = WebRtcIsac_kQMeanGain2Q12[index_comb]; 1583b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains_Q12[2] = WebRtcIsac_kQMeanGain3Q12[index_comb]; 1584b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains_Q12[3] = WebRtcIsac_kQMeanGain4Q12[index_comb]; 1585b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1586b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy coding of quantization pitch gains */ 1587b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *WebRtcIsac_kQPitchGainCdf_ptr = WebRtcIsac_kQPitchGainCdf; 1588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(streamdata, &index_comb, 1589b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kQPitchGainCdf_ptr, 1); 1590b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org encData->pitchGain_index[encData->startIdx] = index_comb; 1591b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1592b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1593b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1594b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Pitch LAG */ 1596b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Decode & de-quantize Pitch Lags. */ 1597fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsac_DecodePitchLag(Bitstr* streamdata, int16_t* PitchGain_Q12, 1598b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double* PitchLags) { 1599b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k, err; 1600b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double StepSize; 1601b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double C; 1602b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int index[PITCH_SUBFRAMES]; 1603b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double mean_gain; 1604b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const double* mean_val2, *mean_val3, *mean_val4; 1605fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int16_t* lower_limit; 1606fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const uint16_t* init_index; 1607fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const uint16_t* cdf_size; 1608fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const uint16_t** cdf; 1609b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double PitchGain[4] = {0, 0, 0, 0}; 1610b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1611b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* compute mean pitch gain */ 1612b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_gain = 0.0; 1613b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < 4; k++) { 1614b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGain[k] = ((float)PitchGain_Q12[k]) / 4096; 1615b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_gain += PitchGain[k]; 1616b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1617b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_gain /= 4.0; 1618b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1619b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* voicing classification. */ 1620b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (mean_gain < 0.2) { 1621b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org StepSize = WebRtcIsac_kQPitchLagStepsizeLo; 1622b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf = WebRtcIsac_kQPitchLagCdfPtrLo; 1623b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf_size = WebRtcIsac_kQPitchLagCdfSizeLo; 1624b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val2 = WebRtcIsac_kQMeanLag2Lo; 1625b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val3 = WebRtcIsac_kQMeanLag3Lo; 1626b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val4 = WebRtcIsac_kQMeanLag4Lo; 1627b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lower_limit = WebRtcIsac_kQIndexLowerLimitLagLo; 1628b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org init_index = WebRtcIsac_kQInitIndexLagLo; 1629b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (mean_gain < 0.4) { 1630b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org StepSize = WebRtcIsac_kQPitchLagStepsizeMid; 1631b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf = WebRtcIsac_kQPitchLagCdfPtrMid; 1632b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf_size = WebRtcIsac_kQPitchLagCdfSizeMid; 1633b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val2 = WebRtcIsac_kQMeanLag2Mid; 1634b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val3 = WebRtcIsac_kQMeanLag3Mid; 1635b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val4 = WebRtcIsac_kQMeanLag4Mid; 1636b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lower_limit = WebRtcIsac_kQIndexLowerLimitLagMid; 1637b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org init_index = WebRtcIsac_kQInitIndexLagMid; 1638b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1639b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org StepSize = WebRtcIsac_kQPitchLagStepsizeHi; 1640b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf = WebRtcIsac_kQPitchLagCdfPtrHi; 1641b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf_size = WebRtcIsac_kQPitchLagCdfSizeHi; 1642b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val2 = WebRtcIsac_kQMeanLag2Hi; 1643b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val3 = WebRtcIsac_kQMeanLag3Hi; 1644b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val4 = WebRtcIsac_kQMeanLag4Hi; 1645b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lower_limit = WebRtcIsac_kQindexLowerLimitLagHi; 1646b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org init_index = WebRtcIsac_kQInitIndexLagHi; 1647b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1648b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1649b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Entropy decoding of quantization indices. */ 1650b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_DecHistBisectMulti(index, streamdata, cdf, cdf_size, 1); 1651b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((err < 0) || (index[0] < 0)) { 1652b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG; 1653b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1654b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_DecHistOneStepMulti(index + 1, streamdata, cdf + 1, 1655b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org init_index, 3); 1656b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 1657b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG; 1658b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1659b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1660b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Unquantize back to transform coefficients and do the inverse transform: 1661b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * S = T'*C. */ 1662b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org C = (index[0] + lower_limit[0]) * StepSize; 1663b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < PITCH_SUBFRAMES; k++) { 1664b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchLags[k] = WebRtcIsac_kTransformTranspose[k][0] * C; 1665b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1666b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org C = mean_val2[index[1]]; 1667b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < PITCH_SUBFRAMES; k++) { 1668b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchLags[k] += WebRtcIsac_kTransformTranspose[k][1] * C; 1669b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1670b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org C = mean_val3[index[2]]; 1671b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < PITCH_SUBFRAMES; k++) { 1672b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchLags[k] += WebRtcIsac_kTransformTranspose[k][2] * C; 1673b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1674b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org C = mean_val4[index[3]]; 1675b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < PITCH_SUBFRAMES; k++) { 1676b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchLags[k] += WebRtcIsac_kTransformTranspose[k][3] * C; 1677b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1678b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1679b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1680b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1681b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1682b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1683b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Quantize & code pitch lags. */ 1684fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgvoid WebRtcIsac_EncodePitchLag(double* PitchLags, int16_t* PitchGain_Q12, 1685b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Bitstr* streamdata, 1686b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISAC_SaveEncData_t* encData) { 1687b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k, j; 1688b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double StepSize; 1689b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double C; 1690b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int index[PITCH_SUBFRAMES]; 1691b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double mean_gain; 1692b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const double* mean_val2, *mean_val3, *mean_val4; 1693fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int16_t* lower_limit, *upper_limit; 1694fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const uint16_t** cdf; 1695b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double PitchGain[4] = {0, 0, 0, 0}; 1696b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1697b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* compute mean pitch gain */ 1698b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_gain = 0.0; 1699b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < 4; k++) { 1700b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGain[k] = ((float)PitchGain_Q12[k]) / 4096; 1701b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_gain += PitchGain[k]; 1702b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1703b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_gain /= 4.0; 1704b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1705b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save data for creation of multiple bit streams */ 1706b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org encData->meanGain[encData->startIdx] = mean_gain; 1707b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1708b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Voicing classification. */ 1709b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (mean_gain < 0.2) { 1710b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org StepSize = WebRtcIsac_kQPitchLagStepsizeLo; 1711b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf = WebRtcIsac_kQPitchLagCdfPtrLo; 1712b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val2 = WebRtcIsac_kQMeanLag2Lo; 1713b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val3 = WebRtcIsac_kQMeanLag3Lo; 1714b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val4 = WebRtcIsac_kQMeanLag4Lo; 1715b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lower_limit = WebRtcIsac_kQIndexLowerLimitLagLo; 1716b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org upper_limit = WebRtcIsac_kQIndexUpperLimitLagLo; 1717b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (mean_gain < 0.4) { 1718b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org StepSize = WebRtcIsac_kQPitchLagStepsizeMid; 1719b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf = WebRtcIsac_kQPitchLagCdfPtrMid; 1720b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val2 = WebRtcIsac_kQMeanLag2Mid; 1721b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val3 = WebRtcIsac_kQMeanLag3Mid; 1722b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val4 = WebRtcIsac_kQMeanLag4Mid; 1723b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lower_limit = WebRtcIsac_kQIndexLowerLimitLagMid; 1724b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org upper_limit = WebRtcIsac_kQIndexUpperLimitLagMid; 1725b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1726b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org StepSize = WebRtcIsac_kQPitchLagStepsizeHi; 1727b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf = WebRtcIsac_kQPitchLagCdfPtrHi; 1728b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val2 = WebRtcIsac_kQMeanLag2Hi; 1729b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val3 = WebRtcIsac_kQMeanLag3Hi; 1730b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mean_val4 = WebRtcIsac_kQMeanLag4Hi; 1731b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lower_limit = WebRtcIsac_kQindexLowerLimitLagHi; 1732b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org upper_limit = WebRtcIsac_kQindexUpperLimitLagHi; 1733b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1734b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1735b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* find quantization index */ 1736b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < 4; k++) { 1737b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* transform */ 1738b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org C = 0.0; 1739b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j = 0; j < PITCH_SUBFRAMES; j++) { 1740b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org C += WebRtcIsac_kTransform[k][j] * PitchLags[j]; 1741b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1742b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* quantize */ 1743b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index[k] = WebRtcIsac_lrint(C / StepSize); 1744b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1745b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* check that the index is not outside the boundaries of the table */ 1746b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (index[k] < lower_limit[k]) { 1747b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index[k] = lower_limit[k]; 1748b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (index[k] > upper_limit[k]) index[k] = upper_limit[k]; { 1749b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index[k] -= lower_limit[k]; 1750b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1751b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save data for creation of multiple bit streams */ 1752b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org encData->pitchIndex[PITCH_SUBFRAMES * encData->startIdx + k] = index[k]; 1753b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1754b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1755b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Un-quantize back to transform coefficients and do the inverse transform: 1756b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * S = T'*C */ 1757b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org C = (index[0] + lower_limit[0]) * StepSize; 1758b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < PITCH_SUBFRAMES; k++) { 1759b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchLags[k] = WebRtcIsac_kTransformTranspose[k][0] * C; 1760b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1761b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org C = mean_val2[index[1]]; 1762b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < PITCH_SUBFRAMES; k++) { 1763b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchLags[k] += WebRtcIsac_kTransformTranspose[k][1] * C; 1764b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1765b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org C = mean_val3[index[2]]; 1766b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < PITCH_SUBFRAMES; k++) { 1767b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchLags[k] += WebRtcIsac_kTransformTranspose[k][2] * C; 1768b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1769b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org C = mean_val4[index[3]]; 1770b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < PITCH_SUBFRAMES; k++) { 1771b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchLags[k] += WebRtcIsac_kTransformTranspose[k][3] * C; 1772b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1773b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy coding of quantization pitch lags */ 1774b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(streamdata, index, cdf, PITCH_SUBFRAMES); 1775b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1776b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1777b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1778b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1779b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Routines for in-band signaling of bandwidth estimation */ 1780b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Histograms based on uniform distribution of indices */ 1781b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Move global variables later! */ 1782b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1783b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1784b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* cdf array for frame length indicator */ 1785fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgconst uint16_t WebRtcIsac_kFrameLengthCdf[4] = { 1786b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 0, 21845, 43690, 65535 }; 1787b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1788b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* pointer to cdf array for frame length indicator */ 1789fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgconst uint16_t* WebRtcIsac_kFrameLengthCdf_ptr[1] = { 1790b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kFrameLengthCdf }; 1791b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1792b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* initial cdf index for decoder of frame length indicator */ 1793fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgconst uint16_t WebRtcIsac_kFrameLengthInitIndex[1] = { 1 }; 1794b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1795b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1796fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsac_DecodeFrameLen(Bitstr* streamdata, int16_t* framesamples) { 1797b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int frame_mode, err; 1798b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = 0; 1799b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy decoding of frame length [1:30ms,2:60ms] */ 1800b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_DecHistOneStepMulti(&frame_mode, streamdata, 1801b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kFrameLengthCdf_ptr, 1802b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kFrameLengthInitIndex, 1); 1803b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) 1804b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH; 1805b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1806b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch (frame_mode) { 1807b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case 1: 1808b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *framesamples = 480; /* 30ms */ 1809b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 1810b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case 2: 1811b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *framesamples = 960; /* 60ms */ 1812b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 1813b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org default: 1814b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = -ISAC_DISALLOWED_FRAME_MODE_DECODER; 1815b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1816b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 1817b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1818b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1819fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsac_EncodeFrameLen(int16_t framesamples, Bitstr* streamdata) { 1820b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int frame_mode, status; 1821b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1822b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = 0; 1823b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame_mode = 0; 1824b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy coding of frame length [1:480 samples,2:960 samples] */ 1825b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch (framesamples) { 1826b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case 480: 1827b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame_mode = 1; 1828b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 1829b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case 960: 1830b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame_mode = 2; 1831b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 1832b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org default: 1833b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = - ISAC_DISALLOWED_FRAME_MODE_ENCODER; 1834b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1835b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1836b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (status < 0) 1837b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 1838b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1839b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(streamdata, &frame_mode, 1840b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kFrameLengthCdf_ptr, 1); 1841b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 1842b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1843b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1844b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* cdf array for estimated bandwidth */ 1845fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic const uint16_t kBwCdf[25] = { 1846b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 0, 2731, 5461, 8192, 10923, 13653, 16384, 19114, 21845, 24576, 27306, 30037, 1847b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 32768, 35498, 38229, 40959, 43690, 46421, 49151, 51882, 54613, 57343, 60074, 1848b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 62804, 65535 }; 1849b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1850b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* pointer to cdf array for estimated bandwidth */ 1851fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic const uint16_t* kBwCdfPtr[1] = { kBwCdf }; 1852b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1853b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* initial cdf index for decoder of estimated bandwidth*/ 1854fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic const uint16_t kBwInitIndex[1] = { 7 }; 1855b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1856b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1857fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint WebRtcIsac_DecodeSendBW(Bitstr* streamdata, int16_t* BWno) { 1858b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int BWno32, err; 1859b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1860b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy decoding of sender's BW estimation [0..23] */ 1861b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_DecHistOneStepMulti(&BWno32, streamdata, kBwCdfPtr, 1862b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kBwInitIndex, 1); 1863b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 1864b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_BANDWIDTH; 1865b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1866fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org *BWno = (int16_t)BWno32; 1867b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 1868b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1869b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1870b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid WebRtcIsac_EncodeReceiveBw(int* BWno, Bitstr* streamdata) { 1871b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* entropy encoding of receiver's BW estimation [0..23] */ 1872b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(streamdata, BWno, kBwCdfPtr, 1); 1873b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1874b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1875b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1876b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* estimate code length of LPC Coef */ 1877b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid WebRtcIsac_TranscodeLPCCoef(double* LPCCoef_lo, double* LPCCoef_hi, 1878b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int* index_g) { 1879b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int j, k, n, pos, pos2, posg, offsg, offs2; 1880b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int index_ovr_g[KLT_ORDER_GAIN]; 1881b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double tmpcoeffs_g[KLT_ORDER_GAIN]; 1882b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double tmpcoeffs2_g[KLT_ORDER_GAIN]; 1883b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double sum; 1884b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1885b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* log gains, mean removal and scaling */ 1886b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg = 0; 1887b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < SUBFRAMES; k++) { 1888b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_g[posg] = log(LPCCoef_lo[(LPC_LOBAND_ORDER + 1) * k]); 1889b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_g[posg] -= WebRtcIsac_kLpcMeansGain[posg]; 1890b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_g[posg] *= LPC_GAIN_SCALE; 1891b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg++; 1892b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_g[posg] = log(LPCCoef_hi[(LPC_HIBAND_ORDER + 1) * k]); 1893b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_g[posg] -= WebRtcIsac_kLpcMeansGain[posg]; 1894b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_g[posg] *= LPC_GAIN_SCALE; 1895b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg++; 1896b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1897b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1898b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* KLT */ 1899b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1900b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Left transform. */ 1901b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offsg = 0; 1902b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j = 0; j < SUBFRAMES; j++) { 1903b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg = offsg; 1904b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < LPC_GAIN_ORDER; k++) { 1905b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 1906b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos = offsg; 1907b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 = k; 1908b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < LPC_GAIN_ORDER; n++) { 1909b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += tmpcoeffs_g[pos++] * WebRtcIsac_kKltT1Gain[pos2]; 1910b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 += LPC_GAIN_ORDER; 1911b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1912b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs2_g[posg++] = sum; 1913b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1914b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offsg += LPC_GAIN_ORDER; 1915b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1916b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1917b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Right transform. */ 1918b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offsg = 0; 1919b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offs2 = 0; 1920b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (j = 0; j < SUBFRAMES; j++) { 1921b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org posg = offsg; 1922b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < LPC_GAIN_ORDER; k++) { 1923b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum = 0; 1924b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos = k; 1925b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 = offs2; 1926b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < SUBFRAMES; n++) { 1927b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sum += tmpcoeffs2_g[pos] * WebRtcIsac_kKltT2Gain[pos2++]; 1928b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos += LPC_GAIN_ORDER; 1929b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1930b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_g[posg++] = sum; 1931b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1932b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offs2 += SUBFRAMES; 1933b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org offsg += LPC_GAIN_ORDER; 1934b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1935b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1936b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1937b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* quantize coefficients */ 1938b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < KLT_ORDER_GAIN; k++) { 1939b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Get index. */ 1940b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos2 = WebRtcIsac_lrint(tmpcoeffs_g[k] / KLT_STEPSIZE); 1941b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_g[k] = (pos2) + WebRtcIsac_kQKltQuantMinGain[k]; 1942b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (index_g[k] < 0) { 1943b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_g[k] = 0; 1944b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (index_g[k] > WebRtcIsac_kQKltMaxIndGain[k]) { 1945b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_g[k] = WebRtcIsac_kQKltMaxIndGain[k]; 1946b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1947b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_ovr_g[k] = WebRtcIsac_kQKltOffsetGain[k] + index_g[k]; 1948b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1949b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* find quantization levels for coefficients */ 1950b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpcoeffs_g[k] = WebRtcIsac_kQKltLevelsGain[index_ovr_g[k]]; 1951b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1952b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1953b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1954b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1955b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Decode & de-quantize LPC Coefficients. */ 1956b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint WebRtcIsac_DecodeLpcCoefUB(Bitstr* streamdata, double* lpcVecs, 1957b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double* percepFilterGains, 1958fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t bandwidth) { 1959b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int index_s[KLT_ORDER_SHAPE]; 1960b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1961b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double U[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME]; 1962b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int err; 1963b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1964b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Entropy decoding of quantization indices. */ 1965b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch (bandwidth) { 1966b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case isac12kHz: { 1967b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_DecHistOneStepMulti( 1968b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_s, streamdata, WebRtcIsac_kLpcShapeCdfMatUb12, 1969b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kLpcShapeEntropySearchUb12, UB_LPC_ORDER * 1970b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UB_LPC_VEC_PER_FRAME); 1971b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 1972b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1973b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case isac16kHz: { 1974b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_DecHistOneStepMulti( 1975b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index_s, streamdata, WebRtcIsac_kLpcShapeCdfMatUb16, 1976b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kLpcShapeEntropySearchUb16, UB_LPC_ORDER * 1977b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UB16_LPC_VEC_PER_FRAME); 1978b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 1979b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1980b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org default: 1981b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1982b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1983b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1984b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 1985b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 1986b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1987b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1988b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_DequantizeLpcParam(index_s, lpcVecs, bandwidth); 1989b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_CorrelateInterVec(lpcVecs, U, bandwidth); 1990b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_CorrelateIntraVec(U, lpcVecs, bandwidth); 1991b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_AddLarMean(lpcVecs, bandwidth); 1992b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_DecodeLpcGainUb(percepFilterGains, streamdata); 1993b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1994b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (bandwidth == isac16kHz) { 1995b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Decode another set of Gains. */ 1996b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_DecodeLpcGainUb(&percepFilterGains[SUBFRAMES], streamdata); 1997b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1998b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1999b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 2000b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2001fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_EncodeBandwidth(enum ISACBandwidth bandwidth, 2002fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org Bitstr* streamData) { 2003b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int bandwidthMode; 2004b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch (bandwidth) { 2005b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case isac12kHz: { 2006b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bandwidthMode = 0; 2007b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 2008b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2009b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case isac16kHz: { 2010b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bandwidthMode = 1; 2011b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 2012b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2013b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org default: 2014b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_DISALLOWED_ENCODER_BANDWIDTH; 2015b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2016b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(streamData, &bandwidthMode, kOneBitEqualProbCdf_ptr, 2017b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1); 2018b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 2019b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 2020b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2021fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_DecodeBandwidth(Bitstr* streamData, 2022fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org enum ISACBandwidth* bandwidth) { 2023b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int bandwidthMode; 2024b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (WebRtcIsac_DecHistOneStepMulti(&bandwidthMode, streamData, 2025b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kOneBitEqualProbCdf_ptr, 2026b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kOneBitEqualProbInitIndex, 1) < 0) { 2027b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_BANDWITH; 2028b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2029b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch (bandwidthMode) { 2030b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case 0: { 2031b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *bandwidth = isac12kHz; 2032b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 2033b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2034b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case 1: { 2035b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *bandwidth = isac16kHz; 2036b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 2037b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2038b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org default: 2039b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_DISALLOWED_BANDWIDTH_MODE_DECODER; 2040b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2041b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 2042b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 2043b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2044fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_EncodeJitterInfo(int32_t jitterIndex, 2045fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org Bitstr* streamData) { 2046b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* This is to avoid LINUX warning until we change 'int' to 'Word32'. */ 2047b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int intVar; 2048b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2049b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((jitterIndex < 0) || (jitterIndex > 1)) { 2050b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 2051b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2052b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org intVar = (int)(jitterIndex); 2053b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Use the same CDF table as for bandwidth 2054b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * both take two values with equal probability.*/ 2055b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(streamData, &intVar, kOneBitEqualProbCdf_ptr, 1); 2056b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 2057b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 2058b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2059fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_DecodeJitterInfo(Bitstr* streamData, 2060fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t* jitterInfo) { 2061b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int intVar; 2062b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Use the same CDF table as for bandwidth 2063b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * both take two values with equal probability. */ 2064b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (WebRtcIsac_DecHistOneStepMulti(&intVar, streamData, 2065b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kOneBitEqualProbCdf_ptr, 2066b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kOneBitEqualProbInitIndex, 1) < 0) { 2067b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_DECODE_BANDWITH; 2068b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2069fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org *jitterInfo = (int16_t)(intVar); 2070b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 2071b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 2072