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 * encode.c 13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This file contains definition of funtions for encoding. 15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Decoding of upper-band, including 8-12 kHz, when the bandwidth is 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 0-12 kHz, and 8-16 kHz, when the bandwidth is 0-16 kHz. 17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <stdlib.h> 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <string.h> 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <stdio.h> 23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "structs.h" 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "codec.h" 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "pitch_estimator.h" 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "entropy_coding.h" 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "arith_routines.h" 29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "pitch_gain_tables.h" 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "pitch_lag_tables.h" 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "spectrum_ar_model_tables.h" 32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "lpc_tables.h" 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "lpc_analysis.h" 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "bandwidth_estimator.h" 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "lpc_shape_swb12_tables.h" 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "lpc_shape_swb16_tables.h" 37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "lpc_gain_swb_tables.h" 38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define UB_LOOKAHEAD 24 41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Rate allocation tables of lower and upper-band bottleneck for 45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 12kHz & 16kHz bandwidth. 46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 12 kHz bandwidth 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ----------------- 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org The overall bottleneck of the coder is between 38 kbps and 45 kbps. We have 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org considered 7 enteries, uniformly distributed in this interval, i.e. 38, 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 39.17, 40.33, 41.5, 42.67, 43.83 and 45. For every entery, the lower-band 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org and the upper-band bottlenecks are specified in 53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 'kLowerBandBitRate12' and 'kUpperBandBitRate12' 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tables, respectively. E.g. the overall rate of 41.5 kbps corresponts to a 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bottleneck of 31 kbps for lower-band and 27 kbps for upper-band. Given an 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org overall bottleneck of the codec, we use linear interpolation to get 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lower-band and upper-band bottlenecks. 58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 16 kHz bandwidth 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ----------------- 61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org The overall bottleneck of the coder is between 50 kbps and 56 kbps. We have 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org considered 7 enteries, uniformly distributed in this interval, i.e. 50, 51.2, 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 52.4, 53.6, 54.8 and 56. For every entery, the lower-band and the upper-band 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bottlenecks are specified in 'kLowerBandBitRate16' and 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 'kUpperBandBitRate16' tables, respectively. E.g. the overall rate 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org of 53.6 kbps corresponts to a bottleneck of 32 kbps for lower-band and 30 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kbps for upper-band. Given an overall bottleneck of the codec, we use linear 68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org interpolation to get lower-band and upper-band bottlenecks. 69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 38 39.17 40.33 41.5 42.67 43.83 45 */ 73fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic const int16_t kLowerBandBitRate12[7] = { 74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 29000, 30000, 30000, 31000, 31000, 32000, 32000 }; 75fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic const int16_t kUpperBandBitRate12[7] = { 76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 25000, 25000, 27000, 27000, 29000, 29000, 32000 }; 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 50 51.2 52.4 53.6 54.8 56 */ 79fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic const int16_t kLowerBandBitRate16[6] = { 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 31000, 31000, 32000, 32000, 32000, 32000 }; 81fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic const int16_t kUpperBandBitRate16[6] = { 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 28000, 29000, 29000, 30000, 31000, 32000 }; 83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/****************************************************************************** 85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_RateAllocation() 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Internal function to perform a rate-allocation for upper and lower-band, 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * given a total rate. 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - inRateBitPerSec : a total bottleneck in bits/sec. 91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Output: 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - rateLBBitPerSec : a bottleneck allocated to the lower-band 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in bits/sec. 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - rateUBBitPerSec : a bottleneck allocated to the upper-band 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in bits/sec. 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : 0 if rate allocation has been successful. 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -1 if failed to allocate rates. 100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 102fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_RateAllocation(int32_t inRateBitPerSec, 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double* rateLBBitPerSec, 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double* rateUBBitPerSec, 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enum ISACBandwidth* bandwidthKHz) { 106fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t idx; 107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double idxD; 108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double idxErr; 109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (inRateBitPerSec < 38000) { 110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* If the given overall bottleneck is less than 38000 then 111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * then codec has to operate in wideband mode, i.e. 8 kHz 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * bandwidth. */ 113fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org *rateLBBitPerSec = (int16_t)((inRateBitPerSec > 32000) ? 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 32000 : inRateBitPerSec); 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *rateUBBitPerSec = 0; 116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *bandwidthKHz = isac8kHz; 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if ((inRateBitPerSec >= 38000) && (inRateBitPerSec < 50000)) { 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* At a bottleneck between 38 and 50 kbps the codec is operating 119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * at 12 kHz bandwidth. Using xxxBandBitRate12[] to calculates 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * upper/lower bottleneck */ 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Find the bottlenecks by linear interpolation, 123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * step is (45000 - 38000)/6.0 we use the inverse of it. */ 124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const double stepSizeInv = 8.5714286e-4; 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org idxD = (inRateBitPerSec - 38000) * stepSizeInv; 126fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org idx = (idxD >= 6) ? 6 : ((int16_t)idxD); 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org idxErr = idxD - idx; 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *rateLBBitPerSec = kLowerBandBitRate12[idx]; 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *rateUBBitPerSec = kUpperBandBitRate12[idx]; 130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (idx < 6) { 132fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org *rateLBBitPerSec += (int16_t)( 133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org idxErr * (kLowerBandBitRate12[idx + 1] - kLowerBandBitRate12[idx])); 134fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org *rateUBBitPerSec += (int16_t)( 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org idxErr * (kUpperBandBitRate12[idx + 1] - kUpperBandBitRate12[idx])); 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *bandwidthKHz = isac12kHz; 138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if ((inRateBitPerSec >= 50000) && (inRateBitPerSec <= 56000)) { 139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* A bottleneck between 50 and 56 kbps corresponds to bandwidth 140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * of 16 kHz. Using xxxBandBitRate16[] to calculates 141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * upper/lower bottleneck. */ 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Find the bottlenecks by linear interpolation 144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * step is (56000 - 50000)/5 we use the inverse of it. */ 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const double stepSizeInv = 8.3333333e-4; 146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org idxD = (inRateBitPerSec - 50000) * stepSizeInv; 147fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org idx = (idxD >= 5) ? 5 : ((int16_t)idxD); 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org idxErr = idxD - idx; 149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *rateLBBitPerSec = kLowerBandBitRate16[idx]; 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *rateUBBitPerSec = kUpperBandBitRate16[idx]; 151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (idx < 5) { 153fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org *rateLBBitPerSec += (int16_t)(idxErr * 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (kLowerBandBitRate16[idx + 1] - 155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kLowerBandBitRate16[idx])); 156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 157fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org *rateUBBitPerSec += (int16_t)(idxErr * 158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (kUpperBandBitRate16[idx + 1] - 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kUpperBandBitRate16[idx])); 160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *bandwidthKHz = isac16kHz; 162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Out-of-range botlteneck value. */ 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* limit the values. */ 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *rateLBBitPerSec = (*rateLBBitPerSec > 32000) ? 32000 : *rateLBBitPerSec; 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *rateUBBitPerSec = (*rateUBBitPerSec > 32000) ? 32000 : *rateUBBitPerSec; 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid WebRtcIsac_ResetBitstream(Bitstr* bit_stream) { 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bit_stream->W_upper = 0xFFFFFFFF; 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bit_stream->stream_index = 0; 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bit_stream->streamval = 0; 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint WebRtcIsac_EncodeLb(float* in, ISACLBEncStruct* ISACencLB_obj, 181fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t codingMode, 182fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t bottleneckIndex) { 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int stream_length = 0; 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int err; 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int iterCntr; 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double lofilt_coef[(ORDERLO + 1)*SUBFRAMES]; 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double hifilt_coef[(ORDERHI + 1)*SUBFRAMES]; 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float LP[FRAMESAMPLES_HALF]; 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float HP[FRAMESAMPLES_HALF]; 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double LP_lookahead[FRAMESAMPLES_HALF]; 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double HP_lookahead[FRAMESAMPLES_HALF]; 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double LP_lookahead_pf[FRAMESAMPLES_HALF + QLOOKAHEAD]; 196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double LPw[FRAMESAMPLES_HALF]; 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double HPw[FRAMESAMPLES_HALF]; 199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double LPw_pf[FRAMESAMPLES_HALF]; 200fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t fre[FRAMESAMPLES_HALF]; /* Q7 */ 201fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t fim[FRAMESAMPLES_HALF]; /* Q7 */ 202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double PitchLags[4]; 204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double PitchGains[4]; 205fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t PitchGains_Q12[4]; 206fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t AvgPitchGain_Q12; 207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int frame_mode; /* 0 for 30ms, 1 for 60ms */ 209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int status = 0; 210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int my_index; 211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcode_obj transcodingParam; 212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double bytesLeftSpecCoding; 213fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint16_t payloadLimitBytes; 214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Copy new frame-length and bottleneck rate only for the first 10 ms data */ 216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (ISACencLB_obj->buffer_index == 0) { 217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Set the framelength for the next packet. */ 218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->current_framesamples = ISACencLB_obj->new_framelength; 219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* 'frame_mode' is 0 (30 ms) or 1 (60 ms). */ 221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame_mode = ISACencLB_obj->current_framesamples / MAX_FRAMESAMPLES; 222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* buffer speech samples (by 10ms packet) until the frame-length */ 224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* is reached (30 or 60 ms). */ 225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /*****************************************************************/ 226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* fill the buffer with 10ms input data */ 228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < FRAMESAMPLES_10ms; k++) { 229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->data_buffer_float[k + ISACencLB_obj->buffer_index] = in[k]; 230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* If buffersize is not equal to current framesize then increase index 233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * and return. We do no encoding untill we have enough audio. */ 234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (ISACencLB_obj->buffer_index + FRAMESAMPLES_10ms != FRAMESAMPLES) { 235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->buffer_index += FRAMESAMPLES_10ms; 236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* If buffer reached the right size, reset index and continue with 239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * encoding the frame. */ 240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->buffer_index = 0; 241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* End of buffer function. */ 243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /**************************/ 244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Encoding */ 246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /************/ 247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (frame_mode == 0 || ISACencLB_obj->frame_nb == 0) { 249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* This is to avoid Linux warnings until we change 'int' to 'Word32' 250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * at all places. */ 251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int intVar; 252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* reset bitstream */ 253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_ResetBitstream(&(ISACencLB_obj->bitstr_obj)); 254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((codingMode == 0) && (frame_mode == 0) && 256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (ISACencLB_obj->enforceFrameSize == 0)) { 257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->new_framelength = WebRtcIsac_GetNewFrameLength( 258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->bottleneck, ISACencLB_obj->current_framesamples); 259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->s2nr = WebRtcIsac_GetSnr( 262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->bottleneck, ISACencLB_obj->current_framesamples); 263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Encode frame length. */ 265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = WebRtcIsac_EncodeFrameLen( 266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->current_framesamples, &ISACencLB_obj->bitstr_obj); 267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (status < 0) { 268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Wrong frame size. */ 269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save framelength for multiple packets memory. */ 272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->SaveEnc_obj.framelength = 273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->current_framesamples; 274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* To be used for Redundant Coding. */ 276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->lastBWIdx = bottleneckIndex; 277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org intVar = (int)bottleneckIndex; 278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncodeReceiveBw(&intVar, &ISACencLB_obj->bitstr_obj); 279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Split signal in two bands. */ 282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_SplitAndFilterFloat(ISACencLB_obj->data_buffer_float, LP, HP, 283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LP_lookahead, HP_lookahead, 284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencLB_obj->prefiltbankstr_obj); 285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* estimate pitch parameters and pitch-filter lookahead signal */ 287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_PitchAnalysis(LP_lookahead, LP_lookahead_pf, 288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencLB_obj->pitchanalysisstr_obj, PitchLags, 289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains); 290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Encode in FIX Q12. */ 292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Convert PitchGain to Fixed point. */ 294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < PITCH_SUBFRAMES; k++) { 295fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org PitchGains_Q12[k] = (int16_t)(PitchGains[k] * 4096.0); 296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Set where to store data in multiple packets memory. */ 299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (frame_mode == 0 || ISACencLB_obj->frame_nb == 0) { 300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->SaveEnc_obj.startIdx = 0; 301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->SaveEnc_obj.startIdx = 1; 303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Quantize & encode pitch parameters. */ 306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncodePitchGain(PitchGains_Q12, &ISACencLB_obj->bitstr_obj, 307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencLB_obj->SaveEnc_obj); 308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncodePitchLag(PitchLags, PitchGains_Q12, 309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencLB_obj->bitstr_obj, 310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencLB_obj->SaveEnc_obj); 311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org AvgPitchGain_Q12 = (PitchGains_Q12[0] + PitchGains_Q12[1] + 313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains_Q12[2] + PitchGains_Q12[3]) >> 2; 314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Find coefficients for perceptual pre-filters. */ 316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_GetLpcCoefLb(LP_lookahead_pf, HP_lookahead, 317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencLB_obj->maskfiltstr_obj, ISACencLB_obj->s2nr, 318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains_Q12, lofilt_coef, hifilt_coef); 319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Code LPC model and shape - gains not quantized yet. */ 321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncodeLpcLb(lofilt_coef, hifilt_coef, &ISACencLB_obj->bitstr_obj, 322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencLB_obj->SaveEnc_obj); 323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Convert PitchGains back to FLOAT for pitchfilter_pre. */ 325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < 4; k++) { 326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchGains[k] = ((float)PitchGains_Q12[k]) / 4096; 327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store the state of arithmetic coder before coding LPC gains. */ 330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.W_upper = ISACencLB_obj->bitstr_obj.W_upper; 331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.stream_index = ISACencLB_obj->bitstr_obj.stream_index; 332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.streamval = ISACencLB_obj->bitstr_obj.streamval; 333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.stream[0] = 334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->bitstr_obj.stream[ISACencLB_obj->bitstr_obj.stream_index - 335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2]; 336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.stream[1] = 337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->bitstr_obj.stream[ISACencLB_obj->bitstr_obj.stream_index - 338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1]; 339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.stream[2] = 340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->bitstr_obj.stream[ISACencLB_obj->bitstr_obj.stream_index]; 341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store LPC Gains before encoding them. */ 343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < SUBFRAMES; k++) { 344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.loFiltGain[k] = lofilt_coef[(LPC_LOBAND_ORDER + 1) * k]; 345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.hiFiltGain[k] = hifilt_coef[(LPC_HIBAND_ORDER + 1) * k]; 346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Code gains */ 349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncodeLpcGainLb(lofilt_coef, hifilt_coef, 350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencLB_obj->bitstr_obj, 351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencLB_obj->SaveEnc_obj); 352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Get the correct value for the payload limit and calculate the 354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * number of bytes left for coding the spectrum. */ 355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((frame_mode == 1) && (ISACencLB_obj->frame_nb == 0)) { 356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* It is a 60ms and we are in the first 30ms then the limit at 357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * this point should be half of the assigned value. */ 358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org payloadLimitBytes = ISACencLB_obj->payloadLimitBytes60 >> 1; 359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (frame_mode == 0) { 360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* It is a 30ms frame */ 361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Subract 3 because termination process may add 3 bytes. */ 362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org payloadLimitBytes = ISACencLB_obj->payloadLimitBytes30 - 3; 363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* This is the second half of a 60ms frame. */ 365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Subract 3 because termination process may add 3 bytes. */ 366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org payloadLimitBytes = ISACencLB_obj->payloadLimitBytes60 - 3; 367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bytesLeftSpecCoding = payloadLimitBytes - transcodingParam.stream_index; 369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Perceptual pre-filtering (using normalized lattice filter). */ 371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Low-band filtering. */ 372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_NormLatticeFilterMa(ORDERLO, 373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->maskfiltstr_obj.PreStateLoF, 374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->maskfiltstr_obj.PreStateLoG, 375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LP, lofilt_coef, LPw); 376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* High-band filtering. */ 377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_NormLatticeFilterMa(ORDERHI, 378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->maskfiltstr_obj.PreStateHiF, 379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->maskfiltstr_obj.PreStateHiG, 380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org HP, hifilt_coef, HPw); 381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Pitch filter. */ 382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_PitchfilterPre(LPw, LPw_pf, &ISACencLB_obj->pitchfiltstr_obj, 383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PitchLags, PitchGains); 384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Transform */ 385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Time2Spec(LPw_pf, HPw, fre, fim, &ISACencLB_obj->fftstr_obj); 386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save data for multiple packets memory. */ 388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org my_index = ISACencLB_obj->SaveEnc_obj.startIdx * FRAMESAMPLES_HALF; 389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&ISACencLB_obj->SaveEnc_obj.fre[my_index], fre, sizeof(fre)); 390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&ISACencLB_obj->SaveEnc_obj.fim[my_index], fim, sizeof(fim)); 391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->SaveEnc_obj.AvgPitchGain[ISACencLB_obj->SaveEnc_obj.startIdx] = 393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org AvgPitchGain_Q12; 394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Quantization and loss-less coding. */ 396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_EncodeSpec(fre, fim, AvgPitchGain_Q12, kIsacLowerBand, 397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencLB_obj->bitstr_obj); 398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { 399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* There has been an error but it was not too large payload 400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (we can cure too large payload). */ 401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (frame_mode == 1 && ISACencLB_obj->frame_nb == 1) { 402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* If this is the second 30ms of a 60ms frame reset 403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org this such that in the next call encoder starts fresh. */ 404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->frame_nb = 0; 405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org iterCntr = 0; 409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while ((ISACencLB_obj->bitstr_obj.stream_index > payloadLimitBytes) || 410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { 411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double bytesSpecCoderUsed; 412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double transcodeScale; 413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) { 415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* We were not able to limit the payload size */ 416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((frame_mode == 1) && (ISACencLB_obj->frame_nb == 0)) { 417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* This was the first 30ms of a 60ms frame. Although 418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org the payload is larger than it should be but we let 419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org the second 30ms be encoded. Maybe together we 420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org won't exceed the limit. */ 421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->frame_nb = 1; 422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if ((frame_mode == 1) && (ISACencLB_obj->frame_nb == 1)) { 424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->frame_nb = 0; 425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH) { 428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_PAYLOAD_LARGER_THAN_LIMIT; 429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH) { 435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bytesSpecCoderUsed = STREAM_SIZE_MAX; 436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Being conservative */ 437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed * 0.5; 438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bytesSpecCoderUsed = ISACencLB_obj->bitstr_obj.stream_index - 440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.stream_index; 441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed; 442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* To be safe, we reduce the scale depending on 445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org the number of iterations. */ 446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodeScale *= (1.0 - (0.9 * (double)iterCntr / 447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (double)MAX_PAYLOAD_LIMIT_ITERATION)); 448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Scale the LPC Gains. */ 450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < SUBFRAMES; k++) { 451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lofilt_coef[(LPC_LOBAND_ORDER + 1) * k] = 452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.loFiltGain[k] * transcodeScale; 453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org hifilt_coef[(LPC_HIBAND_ORDER + 1) * k] = 454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.hiFiltGain[k] * transcodeScale; 455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.loFiltGain[k] = lofilt_coef[(LPC_LOBAND_ORDER + 1) * k]; 456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.hiFiltGain[k] = hifilt_coef[(LPC_HIBAND_ORDER + 1) * k]; 457b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Scale DFT coefficients. */ 460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < FRAMESAMPLES_HALF; k++) { 461fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org fre[k] = (int16_t)(fre[k] * transcodeScale); 462fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org fim[k] = (int16_t)(fim[k] * transcodeScale); 463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save data for multiple packets memory. */ 466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org my_index = ISACencLB_obj->SaveEnc_obj.startIdx * FRAMESAMPLES_HALF; 467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&ISACencLB_obj->SaveEnc_obj.fre[my_index], fre, sizeof(fre)); 468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&ISACencLB_obj->SaveEnc_obj.fim[my_index], fim, sizeof(fim)); 469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Re-store the state of arithmetic coder before coding LPC gains. */ 471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->bitstr_obj.W_upper = transcodingParam.W_upper; 472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->bitstr_obj.stream_index = transcodingParam.stream_index; 473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->bitstr_obj.streamval = transcodingParam.streamval; 474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index - 2] = 475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.stream[0]; 476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index - 1] = 477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.stream[1]; 478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index] = 479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.stream[2]; 480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Code gains. */ 482b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncodeLpcGainLb(lofilt_coef, hifilt_coef, 483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencLB_obj->bitstr_obj, 484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencLB_obj->SaveEnc_obj); 485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Update the number of bytes left for encoding the spectrum. */ 487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bytesLeftSpecCoding = payloadLimitBytes - transcodingParam.stream_index; 488b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Encode the spectrum. */ 490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_EncodeSpec(fre, fim, AvgPitchGain_Q12, kIsacLowerBand, 491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencLB_obj->bitstr_obj); 492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { 494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* There has been an error but it was not too large 495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org payload (we can cure too large payload). */ 496b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (frame_mode == 1 && ISACencLB_obj->frame_nb == 1) { 497b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* If this is the second 30 ms of a 60 ms frame reset 498b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org this such that in the next call encoder starts fresh. */ 499b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->frame_nb = 0; 500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 502b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 503b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org iterCntr++; 504b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 506b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* If 60 ms frame-size and just processed the first 30 ms, */ 507b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* go back to main function to buffer the other 30 ms speech frame. */ 508b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (frame_mode == 1) { 509b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (ISACencLB_obj->frame_nb == 0) { 510b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->frame_nb = 1; 511b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 512b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (ISACencLB_obj->frame_nb == 1) { 513b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->frame_nb = 0; 514b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Also update the frame-length for next packet, 515b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org in Adaptive mode only. */ 516b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (codingMode == 0 && (ISACencLB_obj->enforceFrameSize == 0)) { 517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->new_framelength = 518b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_GetNewFrameLength(ISACencLB_obj->bottleneck, 519b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->current_framesamples); 520b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 521b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 522b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 523b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencLB_obj->frame_nb = 0; 524b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 525b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 526b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Complete arithmetic coding. */ 527b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org stream_length = WebRtcIsac_EncTerminate(&ISACencLB_obj->bitstr_obj); 528b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return stream_length; 529b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 530b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 531b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 532b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 533b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic int LimitPayloadUb(ISACUBEncStruct* ISACencUB_obj, 534fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint16_t payloadLimitBytes, 535b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double bytesLeftSpecCoding, 536b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcode_obj* transcodingParam, 537fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t* fre, int16_t* fim, 538b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double* lpcGains, enum ISACBand band, int status) { 539b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 540b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int iterCntr = 0; 541b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 542b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double bytesSpecCoderUsed; 543b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double transcodeScale; 544fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int16_t kAveragePitchGain = 0.0; 545b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 546b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org do { 547b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) { 548b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* We were not able to limit the payload size. */ 549b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_PAYLOAD_LARGER_THAN_LIMIT; 550b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 551b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 552b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (status == -ISAC_DISALLOWED_BITSTREAM_LENGTH) { 553b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bytesSpecCoderUsed = STREAM_SIZE_MAX; 554b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Being conservative. */ 555b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed * 0.5; 556b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 557b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bytesSpecCoderUsed = ISACencUB_obj->bitstr_obj.stream_index - 558b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam->stream_index; 559b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed; 560b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 561b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 562b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* To be safe, we reduce the scale depending on the 563b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org number of iterations. */ 564b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodeScale *= (1.0 - (0.9 * (double)iterCntr / 565b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (double)MAX_PAYLOAD_LIMIT_ITERATION)); 566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 567b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Scale the LPC Gains. */ 568b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (band == kIsacUpperBand16) { 569b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Two sets of coefficients if 16 kHz. */ 570b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < SUBFRAMES; k++) { 571b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam->loFiltGain[k] *= transcodeScale; 572b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam->hiFiltGain[k] *= transcodeScale; 573b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 574b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 575b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* One sets of coefficients if 12 kHz. */ 576b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < SUBFRAMES; k++) { 577b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam->loFiltGain[k] *= transcodeScale; 578b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 579b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 580b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 581b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Scale DFT coefficients. */ 582b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < FRAMESAMPLES_HALF; k++) { 583fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org fre[k] = (int16_t)(fre[k] * transcodeScale + 0.5); 584fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org fim[k] = (int16_t)(fim[k] * transcodeScale + 0.5); 585b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 586b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store FFT coefficients for multiple encoding. */ 587b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre, 588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sizeof(ISACencUB_obj->SaveEnc_obj.realFFT)); 589b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(ISACencUB_obj->SaveEnc_obj.imagFFT, fim, 590b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sizeof(ISACencUB_obj->SaveEnc_obj.imagFFT)); 591b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 592b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store the state of arithmetic coder before coding LPC gains */ 593b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->bitstr_obj.W_upper = transcodingParam->W_upper; 594b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->bitstr_obj.stream_index = transcodingParam->stream_index; 595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->bitstr_obj.streamval = transcodingParam->streamval; 596b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index - 2] = 597b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam->stream[0]; 598b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index - 1] = 599b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam->stream[1]; 600b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index] = 601b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam->stream[2]; 602b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 603b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store the gains for multiple encoding. */ 604b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains, 605b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SUBFRAMES * sizeof(double)); 606b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Entropy Code lpc-gains, indices are stored for a later use.*/ 607b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncodeLpcGainUb(transcodingParam->loFiltGain, 608b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencUB_obj->bitstr_obj, 609b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->SaveEnc_obj.lpcGainIndex); 610b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 611b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* If 16kHz should do one more set. */ 612b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (band == kIsacUpperBand16) { 613b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store the gains for multiple encoding. */ 614b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&ISACencUB_obj->SaveEnc_obj.lpcGain[SUBFRAMES], 615b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &lpcGains[SUBFRAMES], SUBFRAMES * sizeof(double)); 616b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Entropy Code lpc-gains, indices are stored for a later use.*/ 617b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncodeLpcGainUb( 618b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam->hiFiltGain, &ISACencUB_obj->bitstr_obj, 619b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencUB_obj->SaveEnc_obj.lpcGainIndex[SUBFRAMES]); 620b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 621b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 622b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Update the number of bytes left for encoding the spectrum. */ 623b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bytesLeftSpecCoding = payloadLimitBytes - 624b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->bitstr_obj.stream_index; 625b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 626b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save the bit-stream object at this point for FEC. */ 627b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj, 628b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencUB_obj->bitstr_obj, sizeof(Bitstr)); 629b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 630b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Encode the spectrum. */ 631b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain, 632b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org band, &ISACencUB_obj->bitstr_obj); 633b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((status < 0) && (status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { 634b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* There has been an error but it was not too large payload 635b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (we can cure too large payload). */ 636b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 637b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 638b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org iterCntr++; 639b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } while ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) || 640b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (status == -ISAC_DISALLOWED_BITSTREAM_LENGTH)); 641b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 642b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 643b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 644b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint WebRtcIsac_EncodeUb16(float* in, ISACUBEncStruct* ISACencUB_obj, 645fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t jitterInfo) { 646b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int err; 647b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 648b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 649b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double lpcVecs[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME]; 650b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double percepFilterParams[(1 + UB_LPC_ORDER) * (SUBFRAMES << 1) + 651b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (1 + UB_LPC_ORDER)]; 652b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 653b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double LP_lookahead[FRAMESAMPLES]; 654fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t fre[FRAMESAMPLES_HALF]; /* Q7 */ 655fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t fim[FRAMESAMPLES_HALF]; /* Q7 */ 656b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 657b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int status = 0; 658b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 659b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double varscale[2]; 660b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double corr[SUBFRAMES << 1][UB_LPC_ORDER + 1]; 661b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double lpcGains[SUBFRAMES << 1]; 662b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcode_obj transcodingParam; 663fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint16_t payloadLimitBytes; 664b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double s2nr; 665fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int16_t kAveragePitchGain = 0.0; 666b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int bytesLeftSpecCoding; 667b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 668b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Buffer speech samples (by 10ms packet) until the frame-length is */ 669b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* reached (30 ms). */ 670b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /*********************************************************************/ 671b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 672b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* fill the buffer with 10ms input data */ 673b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&ISACencUB_obj->data_buffer_float[ISACencUB_obj->buffer_index], in, 674b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org FRAMESAMPLES_10ms * sizeof(float)); 675b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 676b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* If buffer size is not equal to current frame-size, and end of file is 677b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * not reached yet, we don't do encoding unless we have the whole frame. */ 678b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (ISACencUB_obj->buffer_index + FRAMESAMPLES_10ms < FRAMESAMPLES) { 679b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->buffer_index += FRAMESAMPLES_10ms; 680b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 681b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 682b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 683b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* End of buffer function. */ 684b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /**************************/ 685b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 686b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Encoding */ 687b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /************/ 688b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 689b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Reset bit-stream */ 690b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_ResetBitstream(&(ISACencUB_obj->bitstr_obj)); 691b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 692b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Encoding of bandwidth information. */ 693b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncodeJitterInfo(jitterInfo, &ISACencUB_obj->bitstr_obj); 694b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 695b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = WebRtcIsac_EncodeBandwidth(isac16kHz, &ISACencUB_obj->bitstr_obj); 696b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (status < 0) { 697b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 698b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 699b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 700b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org s2nr = WebRtcIsac_GetSnr(ISACencUB_obj->bottleneck, FRAMESAMPLES); 701b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 702b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(lpcVecs, ISACencUB_obj->lastLPCVec, UB_LPC_ORDER * sizeof(double)); 703b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 704b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < FRAMESAMPLES; k++) { 705b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LP_lookahead[k] = ISACencUB_obj->data_buffer_float[UB_LOOKAHEAD + k]; 706b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 707b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 708b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Find coefficients for perceptual pre-filters. */ 709b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_GetLpcCoefUb(LP_lookahead, &ISACencUB_obj->maskfiltstr_obj, 710b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &lpcVecs[UB_LPC_ORDER], corr, varscale, isac16kHz); 711b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 712b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(ISACencUB_obj->lastLPCVec, 713b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &lpcVecs[(UB16_LPC_VEC_PER_FRAME - 1) * (UB_LPC_ORDER)], 714b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sizeof(double) * UB_LPC_ORDER); 715b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 716b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Code LPC model and shape - gains not quantized yet. */ 717b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncodeLpcUB(lpcVecs, &ISACencUB_obj->bitstr_obj, 718b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org percepFilterParams, isac16kHz, 719b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencUB_obj->SaveEnc_obj); 720b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 721b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* the first set of lpc parameters are from the last sub-frame of 722b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * the previous frame. so we don't care about them. */ 723b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_GetLpcGain(s2nr, &percepFilterParams[UB_LPC_ORDER + 1], 724b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (SUBFRAMES << 1), lpcGains, corr, varscale); 725b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 726b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store the state of arithmetic coder before coding LPC gains */ 727b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.stream_index = ISACencUB_obj->bitstr_obj.stream_index; 728b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.W_upper = ISACencUB_obj->bitstr_obj.W_upper; 729b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.streamval = ISACencUB_obj->bitstr_obj.streamval; 730b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.stream[0] = 731b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index - 732b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2]; 733b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.stream[1] = 734b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index - 735b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1]; 736b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.stream[2] = 737b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index]; 738b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 739b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store LPC Gains before encoding them. */ 740b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < SUBFRAMES; k++) { 741b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.loFiltGain[k] = lpcGains[k]; 742b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.hiFiltGain[k] = lpcGains[SUBFRAMES + k]; 743b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 744b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 745b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store the gains for multiple encoding. */ 746b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains, 747b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (SUBFRAMES << 1) * sizeof(double)); 748b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 749b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncodeLpcGainUb(lpcGains, &ISACencUB_obj->bitstr_obj, 750b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->SaveEnc_obj.lpcGainIndex); 751b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncodeLpcGainUb( 752b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &lpcGains[SUBFRAMES], &ISACencUB_obj->bitstr_obj, 753b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencUB_obj->SaveEnc_obj.lpcGainIndex[SUBFRAMES]); 754b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 755b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Get the correct value for the payload limit and calculate the number of 756b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bytes left for coding the spectrum. It is a 30ms frame 757b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Subract 3 because termination process may add 3 bytes */ 758b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org payloadLimitBytes = ISACencUB_obj->maxPayloadSizeBytes - 759b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->numBytesUsed - 3; 760b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bytesLeftSpecCoding = payloadLimitBytes - 761b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->bitstr_obj.stream_index; 762b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 763b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < (SUBFRAMES << 1); k++) { 764b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org percepFilterParams[k * (UB_LPC_ORDER + 1) + (UB_LPC_ORDER + 1)] = 765b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lpcGains[k]; 766b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 767b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 768b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* LPC filtering (using normalized lattice filter), */ 769b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* first half-frame. */ 770b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_NormLatticeFilterMa(UB_LPC_ORDER, 771b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->maskfiltstr_obj.PreStateLoF, 772b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->maskfiltstr_obj.PreStateLoG, 773b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencUB_obj->data_buffer_float[0], 774b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &percepFilterParams[UB_LPC_ORDER + 1], 775b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &LP_lookahead[0]); 776b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 777b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Second half-frame filtering. */ 778b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_NormLatticeFilterMa( 779b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UB_LPC_ORDER, ISACencUB_obj->maskfiltstr_obj.PreStateLoF, 780b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->maskfiltstr_obj.PreStateLoG, 781b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencUB_obj->data_buffer_float[FRAMESAMPLES_HALF], 782b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &percepFilterParams[(UB_LPC_ORDER + 1) + SUBFRAMES * (UB_LPC_ORDER + 1)], 783b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &LP_lookahead[FRAMESAMPLES_HALF]); 784b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 785b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Time2Spec(&LP_lookahead[0], &LP_lookahead[FRAMESAMPLES_HALF], 786b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fre, fim, &ISACencUB_obj->fftstr_obj); 787b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 788b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store FFT coefficients for multiple encoding. */ 789b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre, sizeof(fre)); 790b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(ISACencUB_obj->SaveEnc_obj.imagFFT, fim, sizeof(fim)); 791b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 792b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Prepare the audio buffer for the next packet 793b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * move the last 3 ms to the beginning of the buffer. */ 794b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(ISACencUB_obj->data_buffer_float, 795b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencUB_obj->data_buffer_float[FRAMESAMPLES], 796b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LB_TOTAL_DELAY_SAMPLES * sizeof(float)); 797b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* start writing with 3 ms delay to compensate for the delay 798b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * of the lower-band. */ 799b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->buffer_index = LB_TOTAL_DELAY_SAMPLES; 800b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 801b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save the bit-stream object at this point for FEC. */ 802b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj, &ISACencUB_obj->bitstr_obj, 803b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sizeof(Bitstr)); 804b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 805b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Qantization and lossless coding */ 806b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Note that there is no pitch-gain for this band so kAveragePitchGain = 0 807b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * is passed to the function. In fact, the function ignores the 3rd parameter 808b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * for this band. */ 809b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain, kIsacUpperBand16, 810b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencUB_obj->bitstr_obj); 811b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { 812b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 813b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 814b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 815b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) || 816b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { 817b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = LimitPayloadUb(ISACencUB_obj, payloadLimitBytes, bytesLeftSpecCoding, 818b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &transcodingParam, fre, fim, lpcGains, 819b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kIsacUpperBand16, err); 820b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 821b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 822b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 823b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 824b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Complete arithmetic coding. */ 825b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return WebRtcIsac_EncTerminate(&ISACencUB_obj->bitstr_obj); 826b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 827b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 828b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 829b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint WebRtcIsac_EncodeUb12(float* in, ISACUBEncStruct* ISACencUB_obj, 830fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t jitterInfo) { 831b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int err; 832b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 833b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 834b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double lpcVecs[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME]; 835b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 836b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double percepFilterParams[(1 + UB_LPC_ORDER) * SUBFRAMES]; 837b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float LP[FRAMESAMPLES_HALF]; 838b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float HP[FRAMESAMPLES_HALF]; 839b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 840b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double LP_lookahead[FRAMESAMPLES_HALF]; 841b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double HP_lookahead[FRAMESAMPLES_HALF]; 842b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double LPw[FRAMESAMPLES_HALF]; 843b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 844b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double HPw[FRAMESAMPLES_HALF]; 845fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t fre[FRAMESAMPLES_HALF]; /* Q7 */ 846fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t fim[FRAMESAMPLES_HALF]; /* Q7 */ 847b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 848b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int status = 0; 849b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 850b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double varscale[1]; 851b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 852b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double corr[UB_LPC_GAIN_DIM][UB_LPC_ORDER + 1]; 853b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double lpcGains[SUBFRAMES]; 854b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcode_obj transcodingParam; 855fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint16_t payloadLimitBytes; 856b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double s2nr; 857fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int16_t kAveragePitchGain = 0.0; 858b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double bytesLeftSpecCoding; 859b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 860b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Buffer speech samples (by 10ms packet) until the framelength is */ 861b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* reached (30 ms). */ 862b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /********************************************************************/ 863b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 864b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Fill the buffer with 10ms input data. */ 865b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&ISACencUB_obj->data_buffer_float[ISACencUB_obj->buffer_index], in, 866b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org FRAMESAMPLES_10ms * sizeof(float)); 867b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 868b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* if buffer-size is not equal to current frame-size then increase the 869b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index and return. We do the encoding when we have enough audio. */ 870b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (ISACencUB_obj->buffer_index + FRAMESAMPLES_10ms < FRAMESAMPLES) { 871b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->buffer_index += FRAMESAMPLES_10ms; 872b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 873b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 874b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* If buffer reached the right size, reset index and continue 875b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org with encoding the frame */ 876b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->buffer_index = 0; 877b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 878b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* End of buffer function */ 879b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /**************************/ 880b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 881b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Encoding */ 882b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /************/ 883b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 884b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Reset bit-stream. */ 885b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_ResetBitstream(&(ISACencUB_obj->bitstr_obj)); 886b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 887b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Encoding bandwidth information. */ 888b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncodeJitterInfo(jitterInfo, &ISACencUB_obj->bitstr_obj); 889b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = WebRtcIsac_EncodeBandwidth(isac12kHz, &ISACencUB_obj->bitstr_obj); 890b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (status < 0) { 891b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 892b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 893b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 894b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org s2nr = WebRtcIsac_GetSnr(ISACencUB_obj->bottleneck, FRAMESAMPLES); 895b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 896b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Split signal in two bands. */ 897b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_SplitAndFilterFloat(ISACencUB_obj->data_buffer_float, HP, LP, 898b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org HP_lookahead, LP_lookahead, 899b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencUB_obj->prefiltbankstr_obj); 900b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 901b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Find coefficients for perceptual pre-filters. */ 902b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_GetLpcCoefUb(LP_lookahead, &ISACencUB_obj->maskfiltstr_obj, 903b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lpcVecs, corr, varscale, isac12kHz); 904b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 905b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Code LPC model and shape - gains not quantized yet. */ 906b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncodeLpcUB(lpcVecs, &ISACencUB_obj->bitstr_obj, 907b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org percepFilterParams, isac12kHz, 908b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencUB_obj->SaveEnc_obj); 909b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 910b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_GetLpcGain(s2nr, percepFilterParams, SUBFRAMES, lpcGains, corr, 911b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org varscale); 912b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 913b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store the state of arithmetic coder before coding LPC gains. */ 914b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.W_upper = ISACencUB_obj->bitstr_obj.W_upper; 915b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.stream_index = ISACencUB_obj->bitstr_obj.stream_index; 916b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.streamval = ISACencUB_obj->bitstr_obj.streamval; 917b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.stream[0] = 918b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index - 919b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2]; 920b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.stream[1] = 921b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index - 922b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1]; 923b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.stream[2] = 924b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index]; 925b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 926b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store LPC Gains before encoding them. */ 927b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < SUBFRAMES; k++) { 928b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org transcodingParam.loFiltGain[k] = lpcGains[k]; 929b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 930b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 931b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store the gains for multiple encoding. */ 932b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains, SUBFRAMES * 933b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sizeof(double)); 934b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 935b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncodeLpcGainUb(lpcGains, &ISACencUB_obj->bitstr_obj, 936b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->SaveEnc_obj.lpcGainIndex); 937b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 938b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < SUBFRAMES; k++) { 939b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org percepFilterParams[k * (UB_LPC_ORDER + 1)] = lpcGains[k]; 940b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 941b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 942b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* perceptual pre-filtering (using normalized lattice filter) */ 943b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* low-band filtering */ 944b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_NormLatticeFilterMa(UB_LPC_ORDER, 945b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->maskfiltstr_obj.PreStateLoF, 946b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->maskfiltstr_obj.PreStateLoG, LP, 947b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org percepFilterParams, LPw); 948b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 949b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Get the correct value for the payload limit and calculate the number 950b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org of bytes left for coding the spectrum. It is a 30ms frame Subract 3 951b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org because termination process may add 3 bytes */ 952b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org payloadLimitBytes = ISACencUB_obj->maxPayloadSizeBytes - 953b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->numBytesUsed - 3; 954b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bytesLeftSpecCoding = payloadLimitBytes - 955b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACencUB_obj->bitstr_obj.stream_index; 956b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 957b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(HPw, 0, sizeof(HPw)); 958b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 959b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Transform */ 960b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_Time2Spec(LPw, HPw, fre, fim, &ISACencUB_obj->fftstr_obj); 961b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 962b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store FFT coefficients for multiple encoding. */ 963b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre, 964b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sizeof(ISACencUB_obj->SaveEnc_obj.realFFT)); 965b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(ISACencUB_obj->SaveEnc_obj.imagFFT, fim, 966b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sizeof(ISACencUB_obj->SaveEnc_obj.imagFFT)); 967b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 968b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save the bit-stream object at this point for FEC. */ 969b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj, 970b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencUB_obj->bitstr_obj, sizeof(Bitstr)); 971b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 972b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Quantization and loss-less coding */ 973b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* The 4th parameter to this function is pitch-gain, which is only used 974b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * when encoding 0-8 kHz band, and irrelevant in this function, therefore, 975b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * we insert zero here. */ 976b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain, kIsacUpperBand12, 977b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACencUB_obj->bitstr_obj); 978b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { 979b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* There has been an error but it was not too large 980b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org payload (we can cure too large payload) */ 981b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 982b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 983b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 984b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) || 985b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { 986b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = LimitPayloadUb(ISACencUB_obj, payloadLimitBytes, bytesLeftSpecCoding, 987b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &transcodingParam, fre, fim, lpcGains, 988b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kIsacUpperBand12, err); 989b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 990b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 991b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 992b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 993b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Complete arithmetic coding. */ 994b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return WebRtcIsac_EncTerminate(&ISACencUB_obj->bitstr_obj); 995b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 996b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 997b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 998b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 999b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1000b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1001b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1002b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* This function is used to create a new bit-stream with new BWE. 1003b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org The same data as previously encoded with the function WebRtcIsac_Encoder(). 1004b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org The data needed is taken from the structure, where it was stored 1005b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org when calling the encoder. */ 1006b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1007b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint WebRtcIsac_EncodeStoredDataLb(const ISAC_SaveEncData_t* ISACSavedEnc_obj, 1008b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Bitstr* ISACBitStr_obj, int BWnumber, 1009b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float scale) { 1010b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int ii; 1011b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int status; 1012b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int BWno = BWnumber; 1013b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1014fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const uint16_t* WebRtcIsac_kQPitchGainCdf_ptr[1]; 1015fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const uint16_t** cdf; 1016b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1017b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double tmpLPCcoeffs_lo[(ORDERLO + 1)*SUBFRAMES * 2]; 1018b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double tmpLPCcoeffs_hi[(ORDERHI + 1)*SUBFRAMES * 2]; 1019b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int tmpLPCindex_g[12 * 2]; 1020fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t tmp_fre[FRAMESAMPLES], tmp_fim[FRAMESAMPLES]; 1021b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const int kModel = 0; 1022b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1023b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Sanity Check - possible values for BWnumber is 0 - 23. */ 1024b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((BWnumber < 0) || (BWnumber > 23)) { 1025b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_RANGE_ERROR_BW_ESTIMATOR; 1026b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1027b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1028b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Reset bit-stream. */ 1029b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_ResetBitstream(ISACBitStr_obj); 1030b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1031b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Encode frame length */ 1032b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = WebRtcIsac_EncodeFrameLen(ISACSavedEnc_obj->framelength, 1033b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACBitStr_obj); 1034b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (status < 0) { 1035b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Wrong frame size. */ 1036b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 1037b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1038b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1039b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Transcoding */ 1040b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((scale > 0.0) && (scale < 1.0)) { 1041b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Compensate LPC gain. */ 1042b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (ii = 0; 1043b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ii < ((ORDERLO + 1)* SUBFRAMES * (1 + ISACSavedEnc_obj->startIdx)); 1044b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ii++) { 1045b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpLPCcoeffs_lo[ii] = scale * ISACSavedEnc_obj->LPCcoeffs_lo[ii]; 1046b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1047b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (ii = 0; 1048b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ii < ((ORDERHI + 1) * SUBFRAMES * (1 + ISACSavedEnc_obj->startIdx)); 1049b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ii++) { 1050b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpLPCcoeffs_hi[ii] = scale * ISACSavedEnc_obj->LPCcoeffs_hi[ii]; 1051b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1052b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Scale DFT. */ 1053b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (ii = 0; 1054b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ii < (FRAMESAMPLES_HALF * (1 + ISACSavedEnc_obj->startIdx)); 1055b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ii++) { 1056fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp_fre[ii] = (int16_t)((scale) * (float)ISACSavedEnc_obj->fre[ii]); 1057fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp_fim[ii] = (int16_t)((scale) * (float)ISACSavedEnc_obj->fim[ii]); 1058b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1059b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1060b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (ii = 0; 1061b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ii < (KLT_ORDER_GAIN * (1 + ISACSavedEnc_obj->startIdx)); 1062b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ii++) { 1063b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmpLPCindex_g[ii] = ISACSavedEnc_obj->LPCindex_g[ii]; 1064b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1065b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (ii = 0; 1066b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ii < (FRAMESAMPLES_HALF * (1 + ISACSavedEnc_obj->startIdx)); 1067b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ii++) { 1068b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp_fre[ii] = ISACSavedEnc_obj->fre[ii]; 1069b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp_fim[ii] = ISACSavedEnc_obj->fim[ii]; 1070b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1071b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1072b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1073b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Encode bandwidth estimate. */ 1074b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncodeReceiveBw(&BWno, ISACBitStr_obj); 1075b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1076b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Loop over number of 30 msec */ 1077b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (ii = 0; ii <= ISACSavedEnc_obj->startIdx; ii++) { 1078b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Encode pitch gains. */ 1079b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *WebRtcIsac_kQPitchGainCdf_ptr = WebRtcIsac_kQPitchGainCdf; 1080b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(ISACBitStr_obj, 1081b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACSavedEnc_obj->pitchGain_index[ii], 1082b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kQPitchGainCdf_ptr, 1); 1083b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1084b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Entropy coding of quantization pitch lags */ 1085b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Voicing classification. */ 1086b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (ISACSavedEnc_obj->meanGain[ii] < 0.2) { 1087b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf = WebRtcIsac_kQPitchLagCdfPtrLo; 1088b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (ISACSavedEnc_obj->meanGain[ii] < 0.4) { 1089b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf = WebRtcIsac_kQPitchLagCdfPtrMid; 1090b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1091b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf = WebRtcIsac_kQPitchLagCdfPtrHi; 1092b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1093b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(ISACBitStr_obj, 1094b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACSavedEnc_obj->pitchIndex[PITCH_SUBFRAMES * ii], 1095b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cdf, PITCH_SUBFRAMES); 1096b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1097b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* LPC */ 1098b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Only one model exists. The entropy coding is done only for backward 1099b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * compatibility. */ 1100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(ISACBitStr_obj, &kModel, 1101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kQKltModelCdfPtr, 1); 1102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Entropy coding of quantization indices - LPC shape only. */ 1103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(ISACBitStr_obj, 1104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACSavedEnc_obj->LPCindex_s[KLT_ORDER_SHAPE * ii], 1105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kQKltCdfPtrShape, 1106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org KLT_ORDER_SHAPE); 1107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* If transcoding, get new LPC gain indices */ 1109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (scale < 1.0) { 1110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_TranscodeLPCCoef( 1111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &tmpLPCcoeffs_lo[(ORDERLO + 1) * SUBFRAMES * ii], 1112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &tmpLPCcoeffs_hi[(ORDERHI + 1)*SUBFRAMES * ii], 1113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &tmpLPCindex_g[KLT_ORDER_GAIN * ii]); 1114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Entropy coding of quantization indices - LPC gain. */ 1117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(ISACBitStr_obj, &tmpLPCindex_g[KLT_ORDER_GAIN * ii], 1118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kQKltCdfPtrGain, KLT_ORDER_GAIN); 1119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Quantization and loss-less coding. */ 1121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = WebRtcIsac_EncodeSpec(&tmp_fre[ii * FRAMESAMPLES_HALF], 1122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &tmp_fim[ii * FRAMESAMPLES_HALF], 1123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACSavedEnc_obj->AvgPitchGain[ii], 1124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kIsacLowerBand, ISACBitStr_obj); 1125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (status < 0) { 1126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 1127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Complete arithmetic coding. */ 1130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return WebRtcIsac_EncTerminate(ISACBitStr_obj); 1131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint WebRtcIsac_EncodeStoredDataUb( 1135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const ISACUBSaveEncDataStruct* ISACSavedEnc_obj, 1136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Bitstr* bitStream, 1137fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t jitterInfo, 1138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float scale, 1139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enum ISACBandwidth bandwidth) { 1140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int n; 1141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int err; 1142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double lpcGain[SUBFRAMES]; 1143fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t realFFT[FRAMESAMPLES_HALF]; 1144fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t imagFFT[FRAMESAMPLES_HALF]; 1145fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const uint16_t** shape_cdf; 1146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int shape_len; 1147fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int16_t kAveragePitchGain = 0.0; 1148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enum ISACBand band; 1149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Reset bitstream. */ 1150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_ResetBitstream(bitStream); 1151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Encode jitter index. */ 1153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncodeJitterInfo(jitterInfo, bitStream); 1154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_EncodeBandwidth(bandwidth, bitStream); 1156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 1157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 1158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Encode LPC-shape. */ 1161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (bandwidth == isac12kHz) { 1162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shape_cdf = WebRtcIsac_kLpcShapeCdfMatUb12; 1163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shape_len = UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME; 1164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org band = kIsacUpperBand12; 1165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shape_cdf = WebRtcIsac_kLpcShapeCdfMatUb16; 1167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shape_len = UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME; 1168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org band = kIsacUpperBand16; 1169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->indexLPCShape, 1171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shape_cdf, shape_len); 1172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((scale <= 0.0) || (scale >= 1.0)) { 1174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* We only consider scales between zero and one. */ 1175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->lpcGainIndex, 1176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kLpcGainCdfMat, UB_LPC_GAIN_DIM); 1177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (bandwidth == isac16kHz) { 1178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store gain indices of the second half. */ 1179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_EncHistMulti(bitStream, 1180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ISACSavedEnc_obj->lpcGainIndex[SUBFRAMES], 1181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kLpcGainCdfMat, UB_LPC_GAIN_DIM); 1182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store FFT coefficients. */ 1184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_EncodeSpec(ISACSavedEnc_obj->realFFT, 1185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACSavedEnc_obj->imagFFT, kAveragePitchGain, 1186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org band, bitStream); 1187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Scale LPC gain and FFT coefficients. */ 1189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < SUBFRAMES; n++) { 1190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lpcGain[n] = scale * ISACSavedEnc_obj->lpcGain[n]; 1191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store LPC gains. */ 1193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_StoreLpcGainUb(lpcGain, bitStream); 1194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (bandwidth == isac16kHz) { 1196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Scale and code the gains of the second half of the frame, if 16kHz. */ 1197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < SUBFRAMES; n++) { 1198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lpcGain[n] = scale * ISACSavedEnc_obj->lpcGain[n + SUBFRAMES]; 1199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_StoreLpcGainUb(lpcGain, bitStream); 1201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < FRAMESAMPLES_HALF; n++) { 1204fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org realFFT[n] = (int16_t)(scale * (float)ISACSavedEnc_obj->realFFT[n] + 1205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 0.5f); 1206fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org imagFFT[n] = (int16_t)(scale * (float)ISACSavedEnc_obj->imagFFT[n] + 1207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 0.5f); 1208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store FFT coefficients. */ 1210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_EncodeSpec(realFFT, imagFFT, kAveragePitchGain, 1211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org band, bitStream); 1212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 1214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Error happened while encoding FFT coefficients. */ 1215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 1216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Complete arithmetic coding. */ 1219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return WebRtcIsac_EncTerminate(bitStream); 1220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1222fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_GetRedPayloadUb( 1223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const ISACUBSaveEncDataStruct* ISACSavedEncObj, 1224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Bitstr* bitStreamObj, 1225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enum ISACBandwidth bandwidth) { 1226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int n; 1227fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t status; 1228fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t realFFT[FRAMESAMPLES_HALF]; 1229fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t imagFFT[FRAMESAMPLES_HALF]; 1230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enum ISACBand band; 1231fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int16_t kAveragePitchGain = 0.0; 1232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Store bit-stream object. */ 1233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(bitStreamObj, &ISACSavedEncObj->bitStreamObj, sizeof(Bitstr)); 1234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Scale FFT coefficients. */ 1236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (n = 0; n < FRAMESAMPLES_HALF; n++) { 1237fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org realFFT[n] = (int16_t)((float)ISACSavedEncObj->realFFT[n] * 1238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RCU_TRANSCODING_SCALE_UB + 0.5); 1239fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org imagFFT[n] = (int16_t)((float)ISACSavedEncObj->imagFFT[n] * 1240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RCU_TRANSCODING_SCALE_UB + 0.5); 1241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org band = (bandwidth == isac12kHz) ? kIsacUpperBand12 : kIsacUpperBand16; 1244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = WebRtcIsac_EncodeSpec(realFFT, imagFFT, kAveragePitchGain, band, 1245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bitStreamObj); 1246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (status < 0) { 1247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 1248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Terminate entropy coding */ 1250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return WebRtcIsac_EncTerminate(bitStreamObj); 1251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1253