• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_routines.h
13  *
14  * This file contains functions for arithmatically encoding and
15  * decoding DFT coefficients.
16  *
17  */
18 
19 
20 #include "modules/audio_coding/codecs/isac/main/source/arith_routines.h"
21 
22 
23 
24 static const int32_t kHistEdgesQ15[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 static const int kCdfSlopeQ0[51] = {  /* Q0 */
34   5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
35   5,  5,  13,  23,  47,  87,  154,  315,  700,  1088,
36   2471,  6064,  14221,  21463,  36634,  36924,  19750,  13270,  5806,  2312,
37   1095,  660,  316,  145,  86,  41,  32,  5,  5,  5,
38   5,  5,  5,  5,  5,  5,  5,  5,  5,  2, 0};
39 
40 
41 static const int kCdfQ16[51] = {  /* Q16 */
42   0,  2,  4,  6,  8,  10,  12,  14,  16,  18,
43   20,  22,  24,  29,  38,  57,  92,  153,  279,  559,
44   994,  1983,  4408,  10097,  18682,  33336,  48105,  56005,  61313,  63636,
45   64560,  64998,  65262,  65389,  65447,  65481,  65497,  65510,  65512,  65514,
46   65516,  65518,  65520,  65522,  65524,  65526,  65528,  65530,  65532,  65534,
47   65535};
48 
49 
50 
51 /* function to be converted to fixed point */
piecewise(int32_t xinQ15)52 static __inline uint32_t piecewise(int32_t xinQ15) {
53 
54   int32_t ind, qtmp1, qtmp2, qtmp3;
55   uint32_t tmpUW32;
56 
57 
58   qtmp2 = xinQ15;
59 
60   if (qtmp2 < kHistEdgesQ15[0]) {
61     qtmp2 = kHistEdgesQ15[0];
62   }
63   if (qtmp2 > kHistEdgesQ15[50]) {
64     qtmp2 = kHistEdgesQ15[50];
65   }
66 
67   qtmp1 = qtmp2 - kHistEdgesQ15[0];       /* Q15 - Q15 = Q15        */
68   ind = (qtmp1 * 5) >> 16;              /* 2^16 / 5 = 0.4 in Q15  */
69   /* Q15 -> Q0              */
70   qtmp1 = qtmp2 - kHistEdgesQ15[ind];     /* Q15 - Q15 = Q15        */
71   qtmp2 = kCdfSlopeQ0[ind] * qtmp1;      /* Q0 * Q15 = Q15         */
72   qtmp3 = qtmp2>>15;                    /* Q15 -> Q0              */
73 
74   tmpUW32 = kCdfQ16[ind] + qtmp3;    /* Q0 + Q0 = Q0           */
75   return tmpUW32;
76 }
77 
78 
79 
WebRtcIsac_EncLogisticMulti2(Bitstr * streamdata,int16_t * dataQ7,const uint16_t * envQ8,const int N,const int16_t isSWB12kHz)80 int WebRtcIsac_EncLogisticMulti2(
81     Bitstr *streamdata,      /* in-/output struct containing bitstream */
82     int16_t *dataQ7,    /* input: data vector */
83     const uint16_t *envQ8, /* input: side info vector defining the width of the pdf */
84     const int N,       /* input: data vector length / 2 */
85     const int16_t isSWB12kHz)
86 {
87   uint32_t W_lower, W_upper;
88   uint32_t W_upper_LSB, W_upper_MSB;
89   uint8_t *stream_ptr;
90   uint8_t *maxStreamPtr;
91   uint8_t *stream_ptr_carry;
92   uint32_t cdf_lo, cdf_hi;
93   int k;
94 
95   /* point to beginning of stream buffer */
96   stream_ptr = streamdata->stream + streamdata->stream_index;
97   W_upper = streamdata->W_upper;
98 
99   maxStreamPtr = streamdata->stream + STREAM_SIZE_MAX_60 - 1;
100   for (k = 0; k < N; k++)
101   {
102     /* compute cdf_lower and cdf_upper by evaluating the piecewise linear cdf */
103     cdf_lo = piecewise((*dataQ7 - 64) * *envQ8);
104     cdf_hi = piecewise((*dataQ7 + 64) * *envQ8);
105 
106     /* test and clip if probability gets too small */
107     while (cdf_lo+1 >= cdf_hi) {
108       /* clip */
109       if (*dataQ7 > 0) {
110         *dataQ7 -= 128;
111         cdf_hi = cdf_lo;
112         cdf_lo = piecewise((*dataQ7 - 64) * *envQ8);
113       } else {
114         *dataQ7 += 128;
115         cdf_lo = cdf_hi;
116         cdf_hi = piecewise((*dataQ7 + 64) * *envQ8);
117       }
118     }
119 
120     dataQ7++;
121     // increment only once per 4 iterations for SWB-16kHz or WB
122     // increment only once per 2 iterations for SWB-12kHz
123     envQ8 += (isSWB12kHz)? (k & 1):((k & 1) & (k >> 1));
124 
125 
126     /* update interval */
127     W_upper_LSB = W_upper & 0x0000FFFF;
128     W_upper_MSB = W_upper >> 16;
129     W_lower = W_upper_MSB * cdf_lo;
130     W_lower += (W_upper_LSB * cdf_lo) >> 16;
131     W_upper = W_upper_MSB * cdf_hi;
132     W_upper += (W_upper_LSB * cdf_hi) >> 16;
133 
134     /* shift interval such that it begins at zero */
135     W_upper -= ++W_lower;
136 
137     /* add integer to bitstream */
138     streamdata->streamval += W_lower;
139 
140     /* handle carry */
141     if (streamdata->streamval < W_lower)
142     {
143       /* propagate carry */
144       stream_ptr_carry = stream_ptr;
145       while (!(++(*--stream_ptr_carry)));
146     }
147 
148     /* renormalize interval, store most significant byte of streamval and update streamval */
149     while ( !(W_upper & 0xFF000000) )      /* W_upper < 2^24 */
150     {
151       W_upper <<= 8;
152       *stream_ptr++ = (uint8_t) (streamdata->streamval >> 24);
153 
154       if(stream_ptr > maxStreamPtr)
155       {
156         return -ISAC_DISALLOWED_BITSTREAM_LENGTH;
157       }
158       streamdata->streamval <<= 8;
159     }
160   }
161 
162   /* calculate new stream_index */
163   streamdata->stream_index = (int)(stream_ptr - streamdata->stream);
164   streamdata->W_upper = W_upper;
165 
166   return 0;
167 }
168 
169 
170 
WebRtcIsac_DecLogisticMulti2(int16_t * dataQ7,Bitstr * streamdata,const uint16_t * envQ8,const int16_t * ditherQ7,const int N,const int16_t isSWB12kHz)171 int WebRtcIsac_DecLogisticMulti2(
172     int16_t *dataQ7,       /* output: data vector */
173     Bitstr *streamdata,      /* in-/output struct containing bitstream */
174     const uint16_t *envQ8, /* input: side info vector defining the width of the pdf */
175     const int16_t *ditherQ7,/* input: dither vector */
176     const int N,         /* input: data vector length */
177     const int16_t isSWB12kHz)
178 {
179   uint32_t    W_lower, W_upper;
180   uint32_t    W_tmp;
181   uint32_t    W_upper_LSB, W_upper_MSB;
182   uint32_t    streamval;
183   const uint8_t *stream_ptr;
184   uint32_t    cdf_tmp;
185   int16_t     candQ7;
186   int             k;
187 
188   // Position just past the end of the stream. STREAM_SIZE_MAX_60 instead of
189   // STREAM_SIZE_MAX (which is the size of the allocated buffer) because that's
190   // the limit to how much data is filled in.
191   const uint8_t* const stream_end = streamdata->stream + STREAM_SIZE_MAX_60;
192 
193   stream_ptr = streamdata->stream + streamdata->stream_index;
194   W_upper = streamdata->W_upper;
195   if (streamdata->stream_index == 0)   /* first time decoder is called for this stream */
196   {
197     /* read first word from bytestream */
198     if (stream_ptr + 3 >= stream_end)
199       return -1;  // Would read out of bounds. Malformed input?
200     streamval = *stream_ptr << 24;
201     streamval |= *++stream_ptr << 16;
202     streamval |= *++stream_ptr << 8;
203     streamval |= *++stream_ptr;
204   } else {
205     streamval = streamdata->streamval;
206   }
207 
208 
209   for (k = 0; k < N; k++)
210   {
211     /* find the integer *data for which streamval lies in [W_lower+1, W_upper] */
212     W_upper_LSB = W_upper & 0x0000FFFF;
213     W_upper_MSB = W_upper >> 16;
214 
215     /* find first candidate by inverting the logistic cdf */
216     candQ7 = - *ditherQ7 + 64;
217     cdf_tmp = piecewise(candQ7 * *envQ8);
218 
219     W_tmp = W_upper_MSB * cdf_tmp;
220     W_tmp += (W_upper_LSB * cdf_tmp) >> 16;
221     if (streamval > W_tmp)
222     {
223       W_lower = W_tmp;
224       candQ7 += 128;
225       cdf_tmp = piecewise(candQ7 * *envQ8);
226 
227       W_tmp = W_upper_MSB * cdf_tmp;
228       W_tmp += (W_upper_LSB * cdf_tmp) >> 16;
229       while (streamval > W_tmp)
230       {
231         W_lower = W_tmp;
232         candQ7 += 128;
233         cdf_tmp = piecewise(candQ7 * *envQ8);
234 
235         W_tmp = W_upper_MSB * cdf_tmp;
236         W_tmp += (W_upper_LSB * cdf_tmp) >> 16;
237 
238         /* error check */
239         if (W_lower == W_tmp) return -1;
240       }
241       W_upper = W_tmp;
242 
243       /* another sample decoded */
244       *dataQ7 = candQ7 - 64;
245     }
246     else
247     {
248       W_upper = W_tmp;
249       candQ7 -= 128;
250       cdf_tmp = piecewise(candQ7 * *envQ8);
251 
252       W_tmp = W_upper_MSB * cdf_tmp;
253       W_tmp += (W_upper_LSB * cdf_tmp) >> 16;
254       while ( !(streamval > W_tmp) )
255       {
256         W_upper = W_tmp;
257         candQ7 -= 128;
258         cdf_tmp = piecewise(candQ7 * *envQ8);
259 
260         W_tmp = W_upper_MSB * cdf_tmp;
261         W_tmp += (W_upper_LSB * cdf_tmp) >> 16;
262 
263         /* error check */
264         if (W_upper == W_tmp) return -1;
265       }
266       W_lower = W_tmp;
267 
268       /* another sample decoded */
269       *dataQ7 = candQ7 + 64;
270     }
271     ditherQ7++;
272     dataQ7++;
273     // increment only once per 4 iterations for SWB-16kHz or WB
274     // increment only once per 2 iterations for SWB-12kHz
275     envQ8 += (isSWB12kHz)? (k & 1):((k & 1) & (k >> 1));
276 
277     /* shift interval to start at zero */
278     W_upper -= ++W_lower;
279 
280     /* add integer to bitstream */
281     streamval -= W_lower;
282 
283     /* renormalize interval and update streamval */
284     while ( !(W_upper & 0xFF000000) )    /* W_upper < 2^24 */
285     {
286       /* read next byte from stream */
287       if (stream_ptr + 1 >= stream_end)
288         return -1;  // Would read out of bounds. Malformed input?
289       streamval = (streamval << 8) | *++stream_ptr;
290       W_upper <<= 8;
291     }
292   }
293 
294   streamdata->stream_index = (int)(stream_ptr - streamdata->stream);
295   streamdata->W_upper = W_upper;
296   streamdata->streamval = streamval;
297 
298   /* find number of bytes in original stream (determined by current interval width) */
299   if ( W_upper > 0x01FFFFFF )
300     return streamdata->stream_index - 2;
301   else
302     return streamdata->stream_index - 1;
303 }
304