1a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* 2a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * 4a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Use of this source code is governed by a BSD-style license 5a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * that can be found in the LICENSE file in the root of the source 6a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * tree. An additional intellectual property rights grant can be found 7a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * in the file PATENTS. All contributing project authors may 8a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * be found in the AUTHORS file in the root of the source tree. 9a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin */ 10a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 11a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* 12a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * arith_routinslogist.c 13a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * 14a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * This C file contains arithmetic encode and decode logistic 15a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * 16a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin */ 17a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 18a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin#include "arith_routins.h" 19a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 20a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 21a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* Tables for piecewise linear cdf functions: y = k*x */ 22a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 23a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* x Points for function piecewise() in Q15 */ 24a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinstatic const WebRtc_Word32 kHistEdges[51] = { 25a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin -327680, -314573, -301466, -288359, -275252, -262144, -249037, -235930, -222823, -209716, 26a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin -196608, -183501, -170394, -157287, -144180, -131072, -117965, -104858, -91751, -78644, 27a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin -65536, -52429, -39322, -26215, -13108, 0, 13107, 26214, 39321, 52428, 28a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 65536, 78643, 91750, 104857, 117964, 131072, 144179, 157286, 170393, 183500, 29a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 196608, 209715, 222822, 235929, 249036, 262144, 275251, 288358, 301465, 314572, 30a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 327680 31a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}; 32a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 33a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 34a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* k Points for function piecewise() in Q0 */ 35a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinstatic const WebRtc_UWord16 kCdfSlope[51] = { 36a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 37a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 5, 5, 13, 23, 47, 87, 154, 315, 700, 1088, 38a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 2471, 6064, 14221, 21463, 36634, 36924, 19750, 13270, 5806, 2312, 39a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 1095, 660, 316, 145, 86, 41, 32, 5, 5, 5, 40a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 41a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 0 42a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}; 43a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 44a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* y Points for function piecewise() in Q0 */ 45a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinstatic const WebRtc_UWord16 kCdfLogistic[51] = { 46a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 47a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 20, 22, 24, 29, 38, 57, 92, 153, 279, 559, 48a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 994, 1983, 4408, 10097, 18682, 33336, 48105, 56005, 61313, 63636, 49a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 64560, 64998, 65262, 65389, 65447, 65481, 65497, 65510, 65512, 65514, 50a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 65516, 65518, 65520, 65522, 65524, 65526, 65528, 65530, 65532, 65534, 51a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 65535 52a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}; 53a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 54a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 55a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/**************************************************************************** 56a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * WebRtcIsacfix_Piecewise(...) 57a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * 58a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Piecewise linear function 59a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * 60a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Input: 61a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * - xinQ15 : input value x in Q15 62a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * 63a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Return value : korresponding y-value in Q0 64a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin */ 65a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 66a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 67a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinstatic __inline WebRtc_UWord16 WebRtcIsacfix_Piecewise(WebRtc_Word32 xinQ15) { 68a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_Word32 ind; 69a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_Word32 qtmp1; 70a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_UWord16 qtmp2; 71a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 72a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* Find index for x-value */ 73a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin qtmp1 = WEBRTC_SPL_SAT(kHistEdges[50],xinQ15,kHistEdges[0]); 74a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin ind = WEBRTC_SPL_MUL(5, qtmp1 - kHistEdges[0]); 75a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin ind = WEBRTC_SPL_RSHIFT_W32(ind, 16); 76a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 77a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* Calculate corresponding y-value ans return*/ 78a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin qtmp1 = qtmp1 - kHistEdges[ind]; 79a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin qtmp2 = (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_U32( 80a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WEBRTC_SPL_UMUL_32_16(qtmp1,kCdfSlope[ind]), 15); 81a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return (kCdfLogistic[ind] + qtmp2); 82a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} 83a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 84a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/**************************************************************************** 85a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * WebRtcIsacfix_EncLogisticMulti2(...) 86a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * 87a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Arithmetic coding of spectrum. 88a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * 89a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Input: 90a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * - streamData : in-/output struct containing bitstream 91a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * - dataQ7 : data vector in Q7 92a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * - envQ8 : side info vector defining the width of the pdf 93a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * in Q8 94a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * - lenData : data vector length 95a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * 96a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Return value : 0 if ok, 97a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * <0 otherwise. 98a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin */ 99a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinint WebRtcIsacfix_EncLogisticMulti2(Bitstr_enc *streamData, 100a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_Word16 *dataQ7, 101a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin const WebRtc_UWord16 *envQ8, 102a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin const WebRtc_Word16 lenData) 103a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{ 104a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_UWord32 W_lower; 105a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_UWord32 W_upper; 106a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_UWord16 W_upper_LSB; 107a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_UWord16 W_upper_MSB; 108a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_UWord16 *streamPtr; 109a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_UWord16 *maxStreamPtr; 110a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_UWord16 *streamPtrCarry; 111a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_UWord16 negcarry; 112a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_UWord32 cdfLo; 113a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_UWord32 cdfHi; 114a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin int k; 115a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 116a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* point to beginning of stream buffer 117a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * and set maximum streamPtr value */ 118a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamPtr = streamData->stream + streamData->stream_index; 119a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin maxStreamPtr = streamData->stream + STREAM_MAXW16_60MS - 1; 120a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_upper = streamData->W_upper; 121a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 122a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin for (k = 0; k < lenData; k++) 123a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 124a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* compute cdf_lower and cdf_upper by evaluating the 125a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * WebRtcIsacfix_Piecewise linear cdf */ 126a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cdfLo = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(*dataQ7 - 64, *envQ8)); 127a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cdfHi = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(*dataQ7 + 64, *envQ8)); 128a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 129a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* test and clip if probability gets too small */ 130a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin while ((cdfLo + 1) >= cdfHi) { 131a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* clip */ 132a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (*dataQ7 > 0) { 133a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *dataQ7 -= 128; 134a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cdfHi = cdfLo; 135a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cdfLo = WebRtcIsacfix_Piecewise( 136a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WEBRTC_SPL_MUL_16_U16(*dataQ7 - 64, *envQ8)); 137a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } else { 138a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *dataQ7 += 128; 139a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cdfLo = cdfHi; 140a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cdfHi = WebRtcIsacfix_Piecewise( 141a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WEBRTC_SPL_MUL_16_U16(*dataQ7 + 64, *envQ8)); 142a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 143a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 144a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 145a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin dataQ7++; 146a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* increment only once per 4 iterations */ 147a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin envQ8 += (k & 1) & (k >> 1); 148a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 149a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 150a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* update interval */ 151a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_upper_LSB = (WebRtc_UWord16)W_upper; 152a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_upper_MSB = (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_U32(W_upper, 16); 153a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_lower = WEBRTC_SPL_UMUL_32_16(cdfLo, W_upper_MSB); 154a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_lower += WEBRTC_SPL_UMUL_32_16_RSFT16(cdfLo, W_upper_LSB); 155a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_upper = WEBRTC_SPL_UMUL_32_16(cdfHi, W_upper_MSB); 156a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_upper += WEBRTC_SPL_UMUL_32_16_RSFT16(cdfHi, W_upper_LSB); 157a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 158a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* shift interval such that it begins at zero */ 159a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_upper -= ++W_lower; 160a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 161a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* add integer to bitstream */ 162a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamData->streamval += W_lower; 163a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 164a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* handle carry */ 165a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (streamData->streamval < W_lower) 166a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 167a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* propagate carry */ 168a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamPtrCarry = streamPtr; 169a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (streamData->full == 0) { 170a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin negcarry = *streamPtrCarry; 171a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin negcarry += 0x0100; 172a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *streamPtrCarry = negcarry; 173a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin while (!(negcarry)) 174a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 175a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin negcarry = *--streamPtrCarry; 176a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin negcarry++; 177a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *streamPtrCarry = negcarry; 178a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 179a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } else { 180a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin while (!(++(*--streamPtrCarry))); 181a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 182a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 183a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 184a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* renormalize interval, store most significant byte of streamval and update streamval 185a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * W_upper < 2^24 */ 186a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin while ( !(W_upper & 0xFF000000) ) 187a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 188a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_upper = WEBRTC_SPL_LSHIFT_U32(W_upper, 8); 189a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (streamData->full == 0) { 190a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *streamPtr++ += (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_U32( 191a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamData->streamval, 24); 192a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamData->full = 1; 193a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } else { 194a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *streamPtr = (WebRtc_UWord16) WEBRTC_SPL_LSHIFT_U32( 195a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WEBRTC_SPL_RSHIFT_U32(streamData->streamval, 24), 8); 196a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamData->full = 0; 197a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 198a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 199a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if( streamPtr > maxStreamPtr ) 200a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return -ISAC_DISALLOWED_BITSTREAM_LENGTH; 201a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 202a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamData->streamval = WEBRTC_SPL_LSHIFT_U32(streamData->streamval, 8); 203a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 204a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 205a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 206a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* calculate new stream_index */ 207a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamData->stream_index = streamPtr - streamData->stream; 208a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamData->W_upper = W_upper; 209a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 210a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return 0; 211a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} 212a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 213a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 214a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/**************************************************************************** 215a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * WebRtcIsacfix_DecLogisticMulti2(...) 216a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * 217a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Arithmetic decoding of spectrum. 218a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * 219a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Input: 220a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * - streamData : in-/output struct containing bitstream 221a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * - envQ8 : side info vector defining the width of the pdf 222a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * in Q8 223a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * - lenData : data vector length 224a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * 225a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Input/Output: 226a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * - dataQ7 : input: dither vector, output: data vector 227a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * 228a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Return value : number of bytes in the stream so far 229a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * -1 if error detected 230a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin */ 231a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinWebRtc_Word16 WebRtcIsacfix_DecLogisticMulti2(WebRtc_Word16 *dataQ7, 232a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin Bitstr_dec *streamData, 233a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin const WebRtc_Word32 *envQ8, 234a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin const WebRtc_Word16 lenData) 235a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{ 236a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_UWord32 W_lower; 237a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_UWord32 W_upper; 238a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_UWord32 W_tmp; 239a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_UWord16 W_upper_LSB; 240a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_UWord16 W_upper_MSB; 241a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_UWord32 streamVal; 242a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_UWord16 cdfTmp; 243a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_Word32 res; 244a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_Word32 inSqrt; 245a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_Word32 newRes; 246a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin const WebRtc_UWord16 *streamPtr; 247a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_Word16 candQ7; 248a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_Word16 envCount; 249a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_UWord16 tmpARSpecQ8 = 0; 250a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin int k, i; 251a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 252a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 253a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* point to beginning of stream buffer */ 254a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamPtr = streamData->stream + streamData->stream_index; 255a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_upper = streamData->W_upper; 256a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 257a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* Check if it is first time decoder is called for this stream */ 258a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (streamData->stream_index == 0) 259a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 260a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* read first word from bytestream */ 261a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamVal = WEBRTC_SPL_LSHIFT_U32(*streamPtr++, 16); 262a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamVal |= *streamPtr++; 263a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 264a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } else { 265a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamVal = streamData->streamval; 266a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 267a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 268a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 269a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin res = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, 270a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WEBRTC_SPL_RSHIFT_W16(WebRtcSpl_GetSizeInBits(envQ8[0]), 1)); 271a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin envCount = 0; 272a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 273a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* code assumes lenData%4 == 0 */ 274a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin for (k = 0; k < lenData; k += 4) 275a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 276a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin int k4; 277a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 278a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* convert to magnitude spectrum, by doing square-roots (modified from SPLIB) */ 279a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin inSqrt = envQ8[envCount]; 280a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin i = 10; 281a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 282a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* For safty reasons */ 283a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (inSqrt < 0) 284a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin inSqrt=-inSqrt; 285a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 286a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(inSqrt, res) + res, 1); 287a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin do 288a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 289a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin res = newRes; 290a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(inSqrt, res) + res, 1); 291a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } while (newRes != res && i-- > 0); 292a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 293a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin tmpARSpecQ8 = (WebRtc_UWord16)newRes; 294a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 295a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin for(k4 = 0; k4 < 4; k4++) 296a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 297a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* find the integer *data for which streamVal lies in [W_lower+1, W_upper] */ 298a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_upper_LSB = (WebRtc_UWord16) (W_upper & 0x0000FFFF); 299a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_upper_MSB = (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_U32(W_upper, 16); 300a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 301a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* find first candidate by inverting the logistic cdf 302a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Input dither value collected from io-stream */ 303a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin candQ7 = - *dataQ7 + 64; 304a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cdfTmp = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8)); 305a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 306a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB); 307a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_tmp += WEBRTC_SPL_UMUL_16_16_RSFT16(cdfTmp, W_upper_LSB); 308a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 309a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (streamVal > W_tmp) 310a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 311a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_lower = W_tmp; 312a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin candQ7 += 128; 313a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cdfTmp = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8)); 314a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 315a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB); 316a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_tmp += WEBRTC_SPL_UMUL_16_16_RSFT16(cdfTmp, W_upper_LSB); 317a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 318a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin while (streamVal > W_tmp) 319a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 320a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_lower = W_tmp; 321a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin candQ7 += 128; 322a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cdfTmp = WebRtcIsacfix_Piecewise( 323a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8)); 324a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 325a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB); 326a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_tmp += WEBRTC_SPL_UMUL_16_16_RSFT16(cdfTmp, W_upper_LSB); 327a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 328a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* error check */ 329a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (W_lower == W_tmp) { 330a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return -1; 331a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 332a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 333a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_upper = W_tmp; 334a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 335a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* Output value put in dataQ7: another sample decoded */ 336a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *dataQ7 = candQ7 - 64; 337a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 338a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin else 339a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 340a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_upper = W_tmp; 341a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin candQ7 -= 128; 342a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cdfTmp = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8)); 343a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 344a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB); 345a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_tmp += WEBRTC_SPL_UMUL_16_16_RSFT16(cdfTmp, W_upper_LSB); 346a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 347a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin while ( !(streamVal > W_tmp) ) 348a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 349a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_upper = W_tmp; 350a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin candQ7 -= 128; 351a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cdfTmp = WebRtcIsacfix_Piecewise( 352a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8)); 353a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 354a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB); 355a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_tmp += WEBRTC_SPL_UMUL_16_16_RSFT16(cdfTmp, W_upper_LSB); 356a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 357a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* error check */ 358a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (W_upper == W_tmp){ 359a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return -1; 360a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 361a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 362a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_lower = W_tmp; 363a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 364a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* Output value put in dataQ7: another sample decoded */ 365a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *dataQ7 = candQ7 + 64; 366a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 367a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 368a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin dataQ7++; 369a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 370a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* shift interval to start at zero */ 371a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_upper -= ++W_lower; 372a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 373a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* add integer to bitstream */ 374a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamVal -= W_lower; 375a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 376a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* renormalize interval and update streamVal 377a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * W_upper < 2^24 */ 378a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin while ( !(W_upper & 0xFF000000) ) 379a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 380a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* read next byte from stream */ 381a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (streamData->full == 0) { 382a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamVal = WEBRTC_SPL_LSHIFT_W32(streamVal, 8) | (*streamPtr++ & 0x00FF); 383a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamData->full = 1; 384a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } else { 385a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamVal = WEBRTC_SPL_LSHIFT_W32(streamVal, 8) | 386a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WEBRTC_SPL_RSHIFT_U16(*streamPtr, 8); 387a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamData->full = 0; 388a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 389a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin W_upper = WEBRTC_SPL_LSHIFT_W32(W_upper, 8); 390a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 391a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 392a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin envCount++; 393a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 394a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 395a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamData->stream_index = streamPtr - streamData->stream; 396a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamData->W_upper = W_upper; 397a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin streamData->streamval = streamVal; 398a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 399a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin /* find number of bytes in original stream (determined by current interval width) */ 400a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if ( W_upper > 0x01FFFFFF ) 401a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return (streamData->stream_index*2 - 3 + !streamData->full); 402a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin else 403a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return (streamData->stream_index*2 - 2 + !streamData->full); 404a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} 405