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