Added support for codebooks up to 64 bits.
authorJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Tue, 11 Dec 2007 03:52:56 +0000 (14:52 +1100)
committerJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Tue, 11 Dec 2007 03:52:56 +0000 (14:52 +1100)
libcelt/arch.h
libcelt/cwrs.c
libcelt/cwrs.h
libcelt/modes.c
libcelt/vq.c

index a12a0d0..610f6e2 100644 (file)
@@ -66,6 +66,7 @@
 
 #endif
 
+typedef unsigned long long celt_uint64_t;
 typedef int spx_int32_t;
 typedef short spx_int16_t;
 
index 19e9731..91a408b 100644 (file)
@@ -95,6 +95,30 @@ unsigned ncwrs(int _n,int _m){
 }
 #endif
 
+celt_uint64_t ncwrs64(int _n,int _m){
+   celt_uint64_t ret;
+   celt_uint64_t f;
+   celt_uint64_t d;
+   int      i;
+   if(_n<0||_m<0)return 0;
+   if(_m==0)return 1;
+   if(_n==0)return 0;
+   ret=0;
+   f=_n;
+   d=1;
+   for(i=1;i<=_m;i++){
+      ret+=f*d<<i;
+#if 0
+      f=umuldiv(f,_n-i,i+1);
+      d=umuldiv(d,_m-i,i);
+#else
+      f=(f*(_n-i))/(i+1);
+      d=(d*(_m-i))/i;
+#endif
+   }
+   return ret;
+}
+
 /*Returns the _i'th combination of _m elements chosen from a set of size _n
    with associated sign bits.
   _x:      Returns the combination with elements sorted in ascending order.
@@ -161,6 +185,74 @@ unsigned icwrs(int _n,int _m,const int *_x,const int *_s){
   return i;
 }
 
+
+/*Returns the _i'th combination of _m elements chosen from a set of size _n
+   with associated sign bits.
+  _x:      Returns the combination with elements sorted in ascending order.
+  _s:      Returns the associated sign bits.*/
+void cwrsi64(int _n,int _m,celt_uint64_t _i,int *_x,int *_s){
+   celt_uint64_t pn;
+   int      j;
+   int      k;
+   pn=ncwrs64(_n-1,_m);
+   for(k=j=0;k<_m;k++){
+      celt_uint64_t pp;
+      celt_uint64_t p;
+      celt_uint64_t t;
+      pp=0;
+      p=ncwrs64(_n-j,_m-k)-pn;
+      if(k>0){
+         t=p>>1;
+         if(t<=_i||_s[k-1])_i+=t;
+      }
+      pn=ncwrs64(_n-j-1,_m-k-1);
+      while(p<=_i){
+         pp=p;
+         j++;
+         p+=pn;
+         pn=ncwrs64(_n-j-1,_m-k-1);
+         p+=pn;
+      }
+      t=p-pp>>1;
+      _s[k]=_i-pp>=t;
+      _x[k]=j;
+      _i-=pp;
+      if(_s[k])_i-=t;
+   }
+}
+
+/*Returns the index of the given combination of _m elements chosen from a set
+   of size _n with associated sign bits.
+  _x:      The combination with elements sorted in ascending order.
+  _s:      The associated sign bits.*/
+celt_uint64_t icwrs64(int _n,int _m,const int *_x,const int *_s){
+   celt_uint64_t pn;
+   celt_uint64_t i;
+   int      j;
+   int      k;
+   i=0;
+   pn=ncwrs64(_n-1,_m);
+   for(k=j=0;k<_m;k++){
+      celt_uint64_t pp;
+      celt_uint64_t p;
+      pp=0;
+      p=ncwrs64(_n-j,_m-k)-pn;
+      if(k>0)p>>=1;
+      pn=ncwrs64(_n-j-1,_m-k-1);
+      while(j<_x[k]){
+         pp=p;
+         j++;
+         p+=pn;
+         pn=ncwrs64(_n-j-1,_m-k-1);
+         p+=pn;
+      }
+      i+=pp;
+      if((k==0||_x[k]!=_x[k-1])&&_s[k])i+=p-pp>>1;
+   }
+   return i;
+}
+
+
 /*Converts a combination _x of _m unit pulses with associated sign bits _s into
    a pulse vector _y of length _n.
   _y: Returns the vector of pulses.
@@ -244,3 +336,50 @@ int main(int _argc,char **_argv){
   return 0;
 }
 */
+
+/*
+#include <stdio.h>
+#define NMAX (32)
+#define MMAX (16)
+
+int main(int _argc,char **_argv){
+   int n;
+   for(n=0;n<=NMAX;n+=3){
+      int m;
+      for(m=0;m<=MMAX;m++){
+         celt_uint64_t nc;
+         celt_uint64_t i;
+         nc=ncwrs64(n,m);
+         printf("%d/%d: %llu",n,m, nc);
+         for(i=0;i<nc;i+=100000){
+            int x[MMAX];
+            int s[MMAX];
+            int x2[MMAX];
+            int s2[MMAX];
+            int y[NMAX];
+            int j;
+            int k;
+            cwrsi64(n,m,i,x,s);
+            //printf("%llu of %llu:",i,nc);
+            for(k=0;k<m;k++){
+               //printf(" %c%i",k>0&&x[k]==x[k-1]?' ':s[k]?'-':'+',x[k]);
+            }
+            //printf(" ->");
+            if(icwrs64(n,m,x,s)!=i){
+               fprintf(stderr,"Combination-index mismatch.\n");
+            }
+            comb2pulse(n,m,y,x,s);
+            //for(j=0;j<n;j++)printf(" %c%i",y[j]?y[j]<0?'-':'+':' ',abs(y[j]));
+            //printf("\n");
+            pulse2comb(n,m,x2,s2,y);
+            for(k=0;k<m;k++)if(x[k]!=x2[k]||s[k]!=s2[k]){
+               fprintf(stderr,"Pulse-combination mismatch.\n");
+               break;
+            }
+         }
+         printf("\n");
+      }
+   }
+   return 0;
+}
+*/
index 8eae063..7181256 100644 (file)
@@ -32,6 +32,7 @@
 #ifndef CWRS_H
 #define CWRS_H
 
+#include "arch.h"
 
 unsigned ncwrs(int _n,int _m);
 
@@ -43,4 +44,11 @@ void comb2pulse(int _n,int _m,int *_y,const int *_x,const int *_s);
 
 void pulse2comb(int _n,int _m,int *_x,int *_s,const int *_y);
 
+/* 64-bit versions */
+celt_uint64_t ncwrs64(int _n,int _m);
+
+void cwrsi64(int _n,int _m,celt_uint64_t _i,int *_x,int *_s);
+
+celt_uint64_t icwrs64(int _n,int _m,const int *_x,const int *_s);
+
 #endif /* CWRS_H */
index 0db2872..36c48de 100644 (file)
@@ -39,6 +39,7 @@ const int qbank1[NBANDS128+2] =   {0, 2, 4, 6, 8, 12, 16, 20, 24, 28, 36, 44, 52
 
 const int qpulses1[NBANDS128] =   {7, 5, 5, 5, 4,  5,  4,  5,  5,  4, -2, 0, 0, 0,  0};
 const int qpulses2[NBANDS128] =   {28,24,20,16,24,20, 18, 12, 10,  10,-7, -4, 0, 0,  0};
+const int qpulses2b[NBANDS128] =   {32,28,24,20,28,24, 22, 18, 16,  15,-12, -12, 12, 12,  0};
 
 const int pbank1[PBANDS128+2] =   {0, 4, 8, 12, 20, PITCH_END128, 128};
 
index 54d0ee0..8469e29 100644 (file)
@@ -187,7 +187,7 @@ void alg_quant(float *x, int N, int K, float *p, ec_enc *enc)
    //for (i=0;i<N;i++)
    //   printf ("%d ", iy[0][i]);
    pulse2comb(N, K, comb, signs, iy[0]); 
-   ec_enc_uint(enc,icwrs(N, K, comb, signs),ncwrs(N, K));
+   ec_enc_uint64(enc,icwrs64(N, K, comb, signs),ncwrs64(N, K));
 }
 
 static const float pg[5] = {1.f, .82f, .75f, 0.7f, 0.6f};
@@ -264,7 +264,7 @@ void copy_quant(float *x, int N, int K, float *Y, int B, int N0, ec_enc *enc)
 void alg_unquant(float *x, int N, int K, float *p, ec_dec *dec)
 {
    int i;
-   unsigned int id;
+   celt_uint64_t id;
    int comb[K];
    int signs[K];
    int iy[N];
@@ -273,8 +273,8 @@ void alg_unquant(float *x, int N, int K, float *p, ec_dec *dec)
    float Rpp=0, Ryp=0, Ryy=0;
    float g;
    
-   id = ec_dec_uint(dec, ncwrs(N, K));
-   cwrsi(N, K, id, comb, signs);
+   id = ec_dec_uint64(dec, ncwrs64(N, K));
+   cwrsi64(N, K, id, comb, signs);
    comb2pulse(N, K, iy, comb, signs);
    //for (i=0;i<N;i++)
    //   printf ("%d ", iy[i]);