|
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 |
}
|