Blame libcelt/cwrs.c

Packit 664db3
/* (C) 2007-2008 Timothy B. Terriberry
Packit 664db3
   (C) 2008 Jean-Marc Valin */
Packit 664db3
/*
Packit 664db3
   Redistribution and use in source and binary forms, with or without
Packit 664db3
   modification, are permitted provided that the following conditions
Packit 664db3
   are met:
Packit 664db3
Packit 664db3
   - Redistributions of source code must retain the above copyright
Packit 664db3
   notice, this list of conditions and the following disclaimer.
Packit 664db3
Packit 664db3
   - Redistributions in binary form must reproduce the above copyright
Packit 664db3
   notice, this list of conditions and the following disclaimer in the
Packit 664db3
   documentation and/or other materials provided with the distribution.
Packit 664db3
Packit 664db3
   - Neither the name of the Xiph.org Foundation nor the names of its
Packit 664db3
   contributors may be used to endorse or promote products derived from
Packit 664db3
   this software without specific prior written permission.
Packit 664db3
Packit 664db3
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit 664db3
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit 664db3
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Packit 664db3
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
Packit 664db3
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
Packit 664db3
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
Packit 664db3
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
Packit 664db3
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
Packit 664db3
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
Packit 664db3
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Packit 664db3
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 664db3
*/
Packit 664db3
Packit 664db3
/* Functions for encoding and decoding pulse vectors.
Packit 664db3
   These are based on the function
Packit 664db3
     U(n,m) = U(n-1,m) + U(n,m-1) + U(n-1,m-1),
Packit 664db3
     U(n,1) = U(1,m) = 2,
Packit 664db3
    which counts the number of ways of placing m pulses in n dimensions, where
Packit 664db3
     at least one pulse lies in dimension 0.
Packit 664db3
   For more details, see: http://people.xiph.org/~tterribe/notes/cwrs.html
Packit 664db3
*/
Packit 664db3
Packit 664db3
#ifdef HAVE_CONFIG_H
Packit 664db3
#include "config.h"
Packit 664db3
#endif
Packit 664db3
Packit 664db3
#include "os_support.h"
Packit 664db3
#include <stdlib.h>
Packit 664db3
#include <string.h>
Packit 664db3
#include "cwrs.h"
Packit 664db3
#include "mathops.h"
Packit 664db3
#include "arch.h"
Packit 664db3
Packit 664db3
/*Guaranteed to return a conservatively large estimate of the binary logarithm
Packit 664db3
   with frac bits of fractional precision.
Packit 664db3
  Tested for all possible 32-bit inputs with frac=4, where the maximum
Packit 664db3
   overestimation is 0.06254243 bits.*/
Packit 664db3
int log2_frac(ec_uint32 val, int frac)
Packit 664db3
{
Packit 664db3
  int l;
Packit 664db3
  l=EC_ILOG(val);
Packit 664db3
  if(val&val-1){
Packit 664db3
    /*This is (val>>l-16), but guaranteed to round up, even if adding a bias
Packit 664db3
       before the shift would cause overflow (e.g., for 0xFFFFxxxx).*/
Packit 664db3
    if(l>16)val=(val>>l-16)+((val&(1<<l-16)-1)+(1<<l-16)-1>>l-16);
Packit 664db3
    else val<<=16-l;
Packit 664db3
    l=l-1<
Packit 664db3
    /*Note that we always need one iteration, since the rounding up above means
Packit 664db3
       that we might need to adjust the integer part of the logarithm.*/
Packit 664db3
    do{
Packit 664db3
      int b;
Packit 664db3
      b=(int)(val>>16);
Packit 664db3
      l+=b<
Packit 664db3
      val=val+b>>b;
Packit 664db3
      val=val*val+0x7FFF>>15;
Packit 664db3
    }
Packit 664db3
    while(frac-->0);
Packit 664db3
    /*If val is not exactly 0x8000, then we have to round up the remainder.*/
Packit 664db3
    return l+(val>0x8000);
Packit 664db3
  }
Packit 664db3
  /*Exact powers of two require no rounding.*/
Packit 664db3
  else return l-1<
Packit 664db3
}
Packit 664db3
Packit 664db3
int fits_in32(int _n, int _m)
Packit 664db3
{
Packit 664db3
   static const celt_int16_t maxN[15] = {
Packit 664db3
      255, 255, 255, 255, 255, 109,  60,  40,
Packit 664db3
       29,  24,  20,  18,  16,  14,  13};
Packit 664db3
   static const celt_int16_t maxM[15] = {
Packit 664db3
      255, 255, 255, 255, 255, 238,  95,  53,
Packit 664db3
       36,  27,  22,  18,  16,  15,  13};
Packit 664db3
   if (_n>=14)
Packit 664db3
   {
Packit 664db3
      if (_m>=14)
Packit 664db3
         return 0;
Packit 664db3
      else
Packit 664db3
         return _n <= maxN[_m];
Packit 664db3
   } else {
Packit 664db3
      return _m <= maxM[_n];
Packit 664db3
   }   
Packit 664db3
}
Packit 664db3
Packit 664db3
#define MASK32 (0xFFFFFFFF)
Packit 664db3
Packit 664db3
/*INV_TABLE[i] holds the multiplicative inverse of (2*i-1) mod 2**32.*/
Packit 664db3
static const celt_uint32_t INV_TABLE[128]={
Packit 664db3
  0x00000001,0xAAAAAAAB,0xCCCCCCCD,0xB6DB6DB7,
Packit 664db3
  0x38E38E39,0xBA2E8BA3,0xC4EC4EC5,0xEEEEEEEF,
Packit 664db3
  0xF0F0F0F1,0x286BCA1B,0x3CF3CF3D,0xE9BD37A7,
Packit 664db3
  0xC28F5C29,0x684BDA13,0x4F72C235,0xBDEF7BDF,
Packit 664db3
  0x3E0F83E1,0x8AF8AF8B,0x914C1BAD,0x96F96F97,
Packit 664db3
  0xC18F9C19,0x2FA0BE83,0xA4FA4FA5,0x677D46CF,
Packit 664db3
  0x1A1F58D1,0xFAFAFAFB,0x8C13521D,0x586FB587,
Packit 664db3
  0xB823EE09,0xA08AD8F3,0xC10C9715,0xBEFBEFBF,
Packit 664db3
  0xC0FC0FC1,0x07A44C6B,0xA33F128D,0xE327A977,
Packit 664db3
  0xC7E3F1F9,0x962FC963,0x3F2B3885,0x613716AF,
Packit 664db3
  0x781948B1,0x2B2E43DB,0xFCFCFCFD,0x6FD0EB67,
Packit 664db3
  0xFA3F47E9,0xD2FD2FD3,0x3F4FD3F5,0xD4E25B9F,
Packit 664db3
  0x5F02A3A1,0xBF5A814B,0x7C32B16D,0xD3431B57,
Packit 664db3
  0xD8FD8FD9,0x8D28AC43,0xDA6C0965,0xDB195E8F,
Packit 664db3
  0x0FDBC091,0x61F2A4BB,0xDCFDCFDD,0x46FDD947,
Packit 664db3
  0x56BE69C9,0xEB2FDEB3,0x26E978D5,0xEFDFBF7F,
Packit 664db3
  0x0FE03F81,0xC9484E2B,0xE133F84D,0xE1A8C537,
Packit 664db3
  0x077975B9,0x70586723,0xCD29C245,0xFAA11E6F,
Packit 664db3
  0x0FE3C071,0x08B51D9B,0x8CE2CABD,0xBF937F27,
Packit 664db3
  0xA8FE53A9,0x592FE593,0x2C0685B5,0x2EB11B5F,
Packit 664db3
  0xFCD1E361,0x451AB30B,0x72CFE72D,0xDB35A717,
Packit 664db3
  0xFB74A399,0xE80BFA03,0x0D516325,0x1BCB564F,
Packit 664db3
  0xE02E4851,0xD962AE7B,0x10F8ED9D,0x95AEDD07,
Packit 664db3
  0xE9DC0589,0xA18A4473,0xEA53FA95,0xEE936F3F,
Packit 664db3
  0x90948F41,0xEAFEAFEB,0x3D137E0D,0xEF46C0F7,
Packit 664db3
  0x028C1979,0x791064E3,0xC04FEC05,0xE115062F,
Packit 664db3
  0x32385831,0x6E68575B,0xA10D387D,0x6FECF2E7,
Packit 664db3
  0x3FB47F69,0xED4BFB53,0x74FED775,0xDB43BB1F,
Packit 664db3
  0x87654321,0x9BA144CB,0x478BBCED,0xBFB912D7,
Packit 664db3
  0x1FDCD759,0x14B2A7C3,0xCB125CE5,0x437B2E0F,
Packit 664db3
  0x10FEF011,0xD2B3183B,0x386CAB5D,0xEF6AC0C7,
Packit 664db3
  0x0E64C149,0x9A020A33,0xE6B41C55,0xFEFEFEFF
Packit 664db3
};
Packit 664db3
Packit 664db3
/*Computes (_a*_b-_c)/(2*_d-1) when the quotient is known to be exact.
Packit 664db3
  _a, _b, _c, and _d may be arbitrary so long as the arbitrary precision result
Packit 664db3
   fits in 32 bits, but currently the table for multiplicative inverses is only
Packit 664db3
   valid for _d<128.*/
Packit 664db3
static inline celt_uint32_t imusdiv32odd(celt_uint32_t _a,celt_uint32_t _b,
Packit 664db3
 celt_uint32_t _c,celt_uint32_t _d){
Packit 664db3
  return (_a*_b-_c)*INV_TABLE[_d]&MASK32;
Packit 664db3
}
Packit 664db3
Packit 664db3
/*Computes (_a*_b-_c)/_d when the quotient is known to be exact.
Packit 664db3
  _d does not actually have to be even, but imusdiv32odd will be faster when
Packit 664db3
   it's odd, so you should use that instead.
Packit 664db3
  _a and _d are assumed to be small (e.g., _a*_d fits in 32 bits; currently the
Packit 664db3
   table for multiplicative inverses is only valid for _d<256).
Packit 664db3
  _b and _c may be arbitrary so long as the arbitrary precision reuslt fits in
Packit 664db3
   32 bits.*/
Packit 664db3
static inline celt_uint32_t imusdiv32even(celt_uint32_t _a,celt_uint32_t _b,
Packit 664db3
 celt_uint32_t _c,celt_uint32_t _d){
Packit 664db3
  celt_uint32_t inv;
Packit 664db3
  int      mask;
Packit 664db3
  int      shift;
Packit 664db3
  int      one;
Packit 664db3
  shift=EC_ILOG(_d^_d-1);
Packit 664db3
  inv=INV_TABLE[_d-1>>shift];
Packit 664db3
  shift--;
Packit 664db3
  one=1<
Packit 664db3
  mask=one-1;
Packit 664db3
  return (_a*(_b>>shift)-(_c>>shift)+
Packit 664db3
   (_a*(_b&mask)+one-(_c&mask)>>shift)-1)*inv&MASK32;
Packit 664db3
}
Packit 664db3
Packit 664db3
/*Computes the next row/column of any recurrence that obeys the relation
Packit 664db3
   u[i][j]=u[i-1][j]+u[i][j-1]+u[i-1][j-1].
Packit 664db3
  _ui0 is the base case for the new row/column.*/
Packit 664db3
static inline void unext32(celt_uint32_t *_ui,int _len,celt_uint32_t _ui0){
Packit 664db3
  celt_uint32_t ui1;
Packit 664db3
  int           j;
Packit 664db3
  /* doing a do-while would overrun the array if we had less than 2 samples */
Packit 664db3
  j=1; do {
Packit 664db3
    ui1=UADD32(UADD32(_ui[j],_ui[j-1]),_ui0);
Packit 664db3
    _ui[j-1]=_ui0;
Packit 664db3
    _ui0=ui1;
Packit 664db3
  } while (++j<_len);
Packit 664db3
  _ui[j-1]=_ui0;
Packit 664db3
}
Packit 664db3
Packit 664db3
/*Computes the previous row/column of any recurrence that obeys the relation
Packit 664db3
   u[i-1][j]=u[i][j]-u[i][j-1]-u[i-1][j-1].
Packit 664db3
  _ui0 is the base case for the new row/column.*/
Packit 664db3
static inline void uprev32(celt_uint32_t *_ui,int _n,celt_uint32_t _ui0){
Packit 664db3
  celt_uint32_t ui1;
Packit 664db3
  int           j;
Packit 664db3
  /* doing a do-while would overrun the array if we had less than 2 samples */
Packit 664db3
  j=1; do {
Packit 664db3
    ui1=USUB32(USUB32(_ui[j],_ui[j-1]),_ui0);
Packit 664db3
    _ui[j-1]=_ui0;
Packit 664db3
    _ui0=ui1;
Packit 664db3
  } while (++j<_n);
Packit 664db3
  _ui[j-1]=_ui0;
Packit 664db3
}
Packit 664db3
Packit 664db3
/*Returns the number of ways of choosing _m elements from a set of size _n with
Packit 664db3
   replacement when a sign bit is needed for each unique element.
Packit 664db3
  _u: On exit, _u[i] contains U(_n,i) for i in [0..._m+1].*/
Packit 664db3
celt_uint32_t ncwrs_u32(int _n,int _m,celt_uint32_t *_u){
Packit 664db3
  celt_uint32_t um2;
Packit 664db3
  int           k;
Packit 664db3
  int           len;
Packit 664db3
  len=_m+2;
Packit 664db3
  _u[0]=0;
Packit 664db3
  _u[1]=um2=1;
Packit 664db3
  if(_n<=6){
Packit 664db3
    /*If _n==0, _u[0] should be 1 and the rest should be 0.*/
Packit 664db3
    /*If _n==1, _u[i] should be 1 for i>1.*/
Packit 664db3
    celt_assert(_n>=2);
Packit 664db3
    /*If _m==0, the following do-while loop will overflow the buffer.*/
Packit 664db3
    celt_assert(_m>0);
Packit 664db3
    k=2;
Packit 664db3
    do _u[k]=(k<<1)-1;
Packit 664db3
    while(++k
Packit 664db3
    for(k=2;k<_n;k++)
Packit 664db3
      unext32(_u+1,_m+1,1);
Packit 664db3
  }
Packit 664db3
  else{
Packit 664db3
    celt_uint32_t um1;
Packit 664db3
    celt_uint32_t n2m1;
Packit 664db3
    _u[2]=n2m1=um1=(_n<<1)-1;
Packit 664db3
    for(k=3;k
Packit 664db3
      /*U(n,m) = ((2*n-1)*U(n,m-1)-U(n,m-2))/(m-1) + U(n,m-2)*/
Packit 664db3
      _u[k]=um2=imusdiv32even(n2m1,um1,um2,k-1)+um2;
Packit 664db3
      if(++k>=len)break;
Packit 664db3
      _u[k]=um1=imusdiv32odd(n2m1,um2,um1,k-1>>1)+um1;
Packit 664db3
    }
Packit 664db3
  }
Packit 664db3
  return _u[_m]+_u[_m+1];
Packit 664db3
}
Packit 664db3
Packit 664db3
Packit 664db3
Packit 664db3
/*Returns the _i'th combination of _m elements chosen from a set of size _n
Packit 664db3
   with associated sign bits.
Packit 664db3
  _y: Returns the vector of pulses.
Packit 664db3
  _u: Must contain entries [0..._m+1] of row _n of U() on input.
Packit 664db3
      Its contents will be destructively modified.*/
Packit 664db3
void cwrsi32(int _n,int _m,celt_uint32_t _i,int *_y,celt_uint32_t *_u){
Packit 664db3
  int j;
Packit 664db3
  int k;
Packit 664db3
  celt_assert(_n>0);
Packit 664db3
  j=0;
Packit 664db3
  k=_m;
Packit 664db3
  do{
Packit 664db3
    celt_uint32_t p;
Packit 664db3
    int           s;
Packit 664db3
    int           yj;
Packit 664db3
    p=_u[k+1];
Packit 664db3
    s=_i>=p;
Packit 664db3
    if(s)_i-=p;
Packit 664db3
    yj=k;
Packit 664db3
    p=_u[k];
Packit 664db3
    while(p>_i)p=_u[--k];
Packit 664db3
    _i-=p;
Packit 664db3
    yj-=k;
Packit 664db3
    _y[j]=yj-(yj<<1&-s);
Packit 664db3
    uprev32(_u,k+2,0);
Packit 664db3
  }
Packit 664db3
  while(++j<_n);
Packit 664db3
}
Packit 664db3
Packit 664db3
Packit 664db3
/*Returns the index of the given combination of _m elements chosen from a set
Packit 664db3
   of size _n with associated sign bits.
Packit 664db3
  _y:  The vector of pulses, whose sum of absolute values must be _m.
Packit 664db3
  _nc: Returns V(_n,_m).*/
Packit 664db3
celt_uint32_t icwrs32(int _n,int _m,celt_uint32_t *_nc,const int *_y,
Packit 664db3
 celt_uint32_t *_u){
Packit 664db3
  celt_uint32_t i;
Packit 664db3
  int           j;
Packit 664db3
  int           k;
Packit 664db3
  /*We can't unroll the first two iterations of the loop unless _n>=2.*/
Packit 664db3
  celt_assert(_n>=2);
Packit 664db3
  i=_y[_n-1]<0;
Packit 664db3
  _u[0]=0;
Packit 664db3
  for(k=1;k<=_m+1;k++)_u[k]=(k<<1)-1;
Packit 664db3
  k=abs(_y[_n-1]);
Packit 664db3
  j=_n-2;
Packit 664db3
  i+=_u[k];
Packit 664db3
  k+=abs(_y[j]);
Packit 664db3
  if(_y[j]<0)i+=_u[k+1];
Packit 664db3
  while(j-->0){
Packit 664db3
    unext32(_u,_m+2,0);
Packit 664db3
    i+=_u[k];
Packit 664db3
    k+=abs(_y[j]);
Packit 664db3
    if(_y[j]<0)i+=_u[k+1];
Packit 664db3
  }
Packit 664db3
  *_nc=_u[_m]+_u[_m+1];
Packit 664db3
  return i;
Packit 664db3
}
Packit 664db3
Packit 664db3
static inline void encode_pulse32(int _n,int _m,const int *_y,ec_enc *_enc){
Packit 664db3
  VARDECL(celt_uint32_t,u);
Packit 664db3
  celt_uint32_t nc;
Packit 664db3
  celt_uint32_t i;
Packit 664db3
  SAVE_STACK;
Packit 664db3
  ALLOC(u,_m+2,celt_uint32_t);
Packit 664db3
  i=icwrs32(_n,_m,&nc,_y,u);
Packit 664db3
  ec_enc_uint(_enc,i,nc);
Packit 664db3
  RESTORE_STACK;
Packit 664db3
}
Packit 664db3
Packit 664db3
int get_required_bits32(int N, int K, int frac)
Packit 664db3
{
Packit 664db3
   int nbits;
Packit 664db3
   VARDECL(celt_uint32_t,u);
Packit 664db3
   SAVE_STACK;
Packit 664db3
   ALLOC(u,K+2,celt_uint32_t);
Packit 664db3
   nbits = log2_frac(ncwrs_u32(N,K,u), frac);
Packit 664db3
   RESTORE_STACK;
Packit 664db3
   return nbits;
Packit 664db3
}
Packit 664db3
Packit 664db3
void get_required_bits(celt_int16_t *bits,int N, int MAXK, int frac)
Packit 664db3
{
Packit 664db3
   int k;
Packit 664db3
   /*We special case k==0 below, since fits_in32 could reject it for large N.*/
Packit 664db3
   celt_assert(MAXK>0);
Packit 664db3
   if(fits_in32(N,MAXK-1)){
Packit 664db3
      bits[0]=0;
Packit 664db3
      /*This could be sped up one heck of a lot if we didn't recompute u in
Packit 664db3
         ncwrs_u32 every time.*/
Packit 664db3
      for(k=1;k
Packit 664db3
   }
Packit 664db3
   else{
Packit 664db3
      VARDECL(celt_int16_t,n1bits);
Packit 664db3
      VARDECL(celt_int16_t,_n2bits);
Packit 664db3
      celt_int16_t *n2bits;
Packit 664db3
      SAVE_STACK;
Packit 664db3
      ALLOC(n1bits,MAXK,celt_int16_t);
Packit 664db3
      ALLOC(_n2bits,MAXK,celt_int16_t);
Packit 664db3
      get_required_bits(n1bits,(N+1)/2,MAXK,frac);
Packit 664db3
      if(N&1){
Packit 664db3
        n2bits=_n2bits;
Packit 664db3
        get_required_bits(n2bits,N/2,MAXK,frac);
Packit 664db3
      }else{
Packit 664db3
        n2bits=n1bits;
Packit 664db3
      }
Packit 664db3
      bits[0]=0;
Packit 664db3
      for(k=1;k
Packit 664db3
         if(fits_in32(N,k))bits[k]=get_required_bits32(N,k,frac);
Packit 664db3
         else{
Packit 664db3
            int worst_bits;
Packit 664db3
            int i;
Packit 664db3
            worst_bits=0;
Packit 664db3
            for(i=0;i<=k;i++){
Packit 664db3
               int split_bits;
Packit 664db3
               split_bits=n1bits[i]+n2bits[k-i];
Packit 664db3
               if(split_bits>worst_bits)worst_bits=split_bits;
Packit 664db3
            }
Packit 664db3
            bits[k]=log2_frac(k+1,frac)+worst_bits;
Packit 664db3
         }
Packit 664db3
      }
Packit 664db3
   RESTORE_STACK;
Packit 664db3
   }
Packit 664db3
}
Packit 664db3
Packit 664db3
Packit 664db3
void encode_pulses(int *_y, int N, int K, ec_enc *enc)
Packit 664db3
{
Packit 664db3
   if (K==0) {
Packit 664db3
   } else if (N==1)
Packit 664db3
   {
Packit 664db3
      ec_enc_bits(enc, _y[0]<0, 1);
Packit 664db3
   } else if(fits_in32(N,K))
Packit 664db3
   {
Packit 664db3
      encode_pulse32(N, K, _y, enc);
Packit 664db3
   } else {
Packit 664db3
     int i;
Packit 664db3
     int count=0;
Packit 664db3
     int split;
Packit 664db3
     split = (N+1)/2;
Packit 664db3
     for (i=0;i
Packit 664db3
        count += abs(_y[i]);
Packit 664db3
     ec_enc_uint(enc,count,K+1);
Packit 664db3
     encode_pulses(_y, split, count, enc);
Packit 664db3
     encode_pulses(_y+split, N-split, K-count, enc);
Packit 664db3
   }
Packit 664db3
}
Packit 664db3
Packit 664db3
static inline void decode_pulse32(int _n,int _m,int *_y,ec_dec *_dec){
Packit 664db3
  VARDECL(celt_uint32_t,u);
Packit 664db3
  SAVE_STACK;
Packit 664db3
  ALLOC(u,_m+2,celt_uint32_t);
Packit 664db3
  cwrsi32(_n,_m,ec_dec_uint(_dec,ncwrs_u32(_n,_m,u)),_y,u);
Packit 664db3
  RESTORE_STACK;
Packit 664db3
}
Packit 664db3
Packit 664db3
void decode_pulses(int *_y, int N, int K, ec_dec *dec)
Packit 664db3
{
Packit 664db3
   if (K==0) {
Packit 664db3
      int i;
Packit 664db3
      for (i=0;i
Packit 664db3
         _y[i] = 0;
Packit 664db3
   } else if (N==1)
Packit 664db3
   {
Packit 664db3
      int s = ec_dec_bits(dec, 1);
Packit 664db3
      if (s==0)
Packit 664db3
         _y[0] = K;
Packit 664db3
      else
Packit 664db3
         _y[0] = -K;
Packit 664db3
   } else if(fits_in32(N,K))
Packit 664db3
   {
Packit 664db3
      decode_pulse32(N, K, _y, dec);
Packit 664db3
   } else {
Packit 664db3
     int split;
Packit 664db3
     int count = ec_dec_uint(dec,K+1);
Packit 664db3
     split = (N+1)/2;
Packit 664db3
     decode_pulses(_y, split, count, dec);
Packit 664db3
     decode_pulses(_y+split, N-split, K-count, dec);
Packit 664db3
   }
Packit 664db3
}