LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/audio_coding/codecs/isac/main/source - arith_routines_logist.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 114 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 3 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "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 */
      52           0 : static __inline uint32_t piecewise(int32_t xinQ15) {
      53             : 
      54             :   int32_t ind, qtmp1, qtmp2, qtmp3;
      55             :   uint32_t tmpUW32;
      56             : 
      57             : 
      58           0 :   qtmp2 = xinQ15;
      59             : 
      60           0 :   if (qtmp2 < kHistEdgesQ15[0]) {
      61           0 :     qtmp2 = kHistEdgesQ15[0];
      62             :   }
      63           0 :   if (qtmp2 > kHistEdgesQ15[50]) {
      64           0 :     qtmp2 = kHistEdgesQ15[50];
      65             :   }
      66             : 
      67           0 :   qtmp1 = qtmp2 - kHistEdgesQ15[0];       /* Q15 - Q15 = Q15        */
      68           0 :   ind = (qtmp1 * 5) >> 16;              /* 2^16 / 5 = 0.4 in Q15  */
      69             :   /* Q15 -> Q0              */
      70           0 :   qtmp1 = qtmp2 - kHistEdgesQ15[ind];     /* Q15 - Q15 = Q15        */
      71           0 :   qtmp2 = kCdfSlopeQ0[ind] * qtmp1;      /* Q0 * Q15 = Q15         */
      72           0 :   qtmp3 = qtmp2>>15;                    /* Q15 -> Q0              */
      73             : 
      74           0 :   tmpUW32 = kCdfQ16[ind] + qtmp3;    /* Q0 + Q0 = Q0           */
      75           0 :   return tmpUW32;
      76             : }
      77             : 
      78             : 
      79             : 
      80           0 : 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           0 :   stream_ptr = streamdata->stream + streamdata->stream_index;
      97           0 :   W_upper = streamdata->W_upper;
      98             : 
      99           0 :   maxStreamPtr = streamdata->stream + STREAM_SIZE_MAX_60 - 1;
     100           0 :   for (k = 0; k < N; k++)
     101             :   {
     102             :     /* compute cdf_lower and cdf_upper by evaluating the piecewise linear cdf */
     103           0 :     cdf_lo = piecewise((*dataQ7 - 64) * *envQ8);
     104           0 :     cdf_hi = piecewise((*dataQ7 + 64) * *envQ8);
     105             : 
     106             :     /* test and clip if probability gets too small */
     107           0 :     while (cdf_lo+1 >= cdf_hi) {
     108             :       /* clip */
     109           0 :       if (*dataQ7 > 0) {
     110           0 :         *dataQ7 -= 128;
     111           0 :         cdf_hi = cdf_lo;
     112           0 :         cdf_lo = piecewise((*dataQ7 - 64) * *envQ8);
     113             :       } else {
     114           0 :         *dataQ7 += 128;
     115           0 :         cdf_lo = cdf_hi;
     116           0 :         cdf_hi = piecewise((*dataQ7 + 64) * *envQ8);
     117             :       }
     118             :     }
     119             : 
     120           0 :     dataQ7++;
     121             :     // increment only once per 4 iterations for SWB-16kHz or WB
     122             :     // increment only once per 2 iterations for SWB-12kHz
     123           0 :     envQ8 += (isSWB12kHz)? (k & 1):((k & 1) & (k >> 1));
     124             : 
     125             : 
     126             :     /* update interval */
     127           0 :     W_upper_LSB = W_upper & 0x0000FFFF;
     128           0 :     W_upper_MSB = W_upper >> 16;
     129           0 :     W_lower = W_upper_MSB * cdf_lo;
     130           0 :     W_lower += (W_upper_LSB * cdf_lo) >> 16;
     131           0 :     W_upper = W_upper_MSB * cdf_hi;
     132           0 :     W_upper += (W_upper_LSB * cdf_hi) >> 16;
     133             : 
     134             :     /* shift interval such that it begins at zero */
     135           0 :     W_upper -= ++W_lower;
     136             : 
     137             :     /* add integer to bitstream */
     138           0 :     streamdata->streamval += W_lower;
     139             : 
     140             :     /* handle carry */
     141           0 :     if (streamdata->streamval < W_lower)
     142             :     {
     143             :       /* propagate carry */
     144           0 :       stream_ptr_carry = stream_ptr;
     145           0 :       while (!(++(*--stream_ptr_carry)));
     146             :     }
     147             : 
     148             :     /* renormalize interval, store most significant byte of streamval and update streamval */
     149           0 :     while ( !(W_upper & 0xFF000000) )      /* W_upper < 2^24 */
     150             :     {
     151           0 :       W_upper <<= 8;
     152           0 :       *stream_ptr++ = (uint8_t) (streamdata->streamval >> 24);
     153             : 
     154           0 :       if(stream_ptr > maxStreamPtr)
     155             :       {
     156           0 :         return -ISAC_DISALLOWED_BITSTREAM_LENGTH;
     157             :       }
     158           0 :       streamdata->streamval <<= 8;
     159             :     }
     160             :   }
     161             : 
     162             :   /* calculate new stream_index */
     163           0 :   streamdata->stream_index = (int)(stream_ptr - streamdata->stream);
     164           0 :   streamdata->W_upper = W_upper;
     165             : 
     166           0 :   return 0;
     167             : }
     168             : 
     169             : 
     170             : 
     171           0 : 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           0 :   const uint8_t* const stream_end = streamdata->stream + STREAM_SIZE_MAX_60;
     192             : 
     193           0 :   stream_ptr = streamdata->stream + streamdata->stream_index;
     194           0 :   W_upper = streamdata->W_upper;
     195           0 :   if (streamdata->stream_index == 0)   /* first time decoder is called for this stream */
     196             :   {
     197             :     /* read first word from bytestream */
     198           0 :     if (stream_ptr + 3 >= stream_end)
     199           0 :       return -1;  // Would read out of bounds. Malformed input?
     200           0 :     streamval = *stream_ptr << 24;
     201           0 :     streamval |= *++stream_ptr << 16;
     202           0 :     streamval |= *++stream_ptr << 8;
     203           0 :     streamval |= *++stream_ptr;
     204             :   } else {
     205           0 :     streamval = streamdata->streamval;
     206             :   }
     207             : 
     208             : 
     209           0 :   for (k = 0; k < N; k++)
     210             :   {
     211             :     /* find the integer *data for which streamval lies in [W_lower+1, W_upper] */
     212           0 :     W_upper_LSB = W_upper & 0x0000FFFF;
     213           0 :     W_upper_MSB = W_upper >> 16;
     214             : 
     215             :     /* find first candidate by inverting the logistic cdf */
     216           0 :     candQ7 = - *ditherQ7 + 64;
     217           0 :     cdf_tmp = piecewise(candQ7 * *envQ8);
     218             : 
     219           0 :     W_tmp = W_upper_MSB * cdf_tmp;
     220           0 :     W_tmp += (W_upper_LSB * cdf_tmp) >> 16;
     221           0 :     if (streamval > W_tmp)
     222             :     {
     223           0 :       W_lower = W_tmp;
     224           0 :       candQ7 += 128;
     225           0 :       cdf_tmp = piecewise(candQ7 * *envQ8);
     226             : 
     227           0 :       W_tmp = W_upper_MSB * cdf_tmp;
     228           0 :       W_tmp += (W_upper_LSB * cdf_tmp) >> 16;
     229           0 :       while (streamval > W_tmp)
     230             :       {
     231           0 :         W_lower = W_tmp;
     232           0 :         candQ7 += 128;
     233           0 :         cdf_tmp = piecewise(candQ7 * *envQ8);
     234             : 
     235           0 :         W_tmp = W_upper_MSB * cdf_tmp;
     236           0 :         W_tmp += (W_upper_LSB * cdf_tmp) >> 16;
     237             : 
     238             :         /* error check */
     239           0 :         if (W_lower == W_tmp) return -1;
     240             :       }
     241           0 :       W_upper = W_tmp;
     242             : 
     243             :       /* another sample decoded */
     244           0 :       *dataQ7 = candQ7 - 64;
     245             :     }
     246             :     else
     247             :     {
     248           0 :       W_upper = W_tmp;
     249           0 :       candQ7 -= 128;
     250           0 :       cdf_tmp = piecewise(candQ7 * *envQ8);
     251             : 
     252           0 :       W_tmp = W_upper_MSB * cdf_tmp;
     253           0 :       W_tmp += (W_upper_LSB * cdf_tmp) >> 16;
     254           0 :       while ( !(streamval > W_tmp) )
     255             :       {
     256           0 :         W_upper = W_tmp;
     257           0 :         candQ7 -= 128;
     258           0 :         cdf_tmp = piecewise(candQ7 * *envQ8);
     259             : 
     260           0 :         W_tmp = W_upper_MSB * cdf_tmp;
     261           0 :         W_tmp += (W_upper_LSB * cdf_tmp) >> 16;
     262             : 
     263             :         /* error check */
     264           0 :         if (W_upper == W_tmp) return -1;
     265             :       }
     266           0 :       W_lower = W_tmp;
     267             : 
     268             :       /* another sample decoded */
     269           0 :       *dataQ7 = candQ7 + 64;
     270             :     }
     271           0 :     ditherQ7++;
     272           0 :     dataQ7++;
     273             :     // increment only once per 4 iterations for SWB-16kHz or WB
     274             :     // increment only once per 2 iterations for SWB-12kHz
     275           0 :     envQ8 += (isSWB12kHz)? (k & 1):((k & 1) & (k >> 1));
     276             : 
     277             :     /* shift interval to start at zero */
     278           0 :     W_upper -= ++W_lower;
     279             : 
     280             :     /* add integer to bitstream */
     281           0 :     streamval -= W_lower;
     282             : 
     283             :     /* renormalize interval and update streamval */
     284           0 :     while ( !(W_upper & 0xFF000000) )    /* W_upper < 2^24 */
     285             :     {
     286             :       /* read next byte from stream */
     287           0 :       if (stream_ptr + 1 >= stream_end)
     288           0 :         return -1;  // Would read out of bounds. Malformed input?
     289           0 :       streamval = (streamval << 8) | *++stream_ptr;
     290           0 :       W_upper <<= 8;
     291             :     }
     292             :   }
     293             : 
     294           0 :   streamdata->stream_index = (int)(stream_ptr - streamdata->stream);
     295           0 :   streamdata->W_upper = W_upper;
     296           0 :   streamdata->streamval = streamval;
     297             : 
     298             :   /* find number of bytes in original stream (determined by current interval width) */
     299           0 :   if ( W_upper > 0x01FFFFFF )
     300           0 :     return streamdata->stream_index - 2;
     301             :   else
     302           0 :     return streamdata->stream_index - 1;
     303             : }

Generated by: LCOV version 1.13