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