ref: f8db800c44a5f12f6bf88288e6d4886e0858570c
parent: f13fea7b530a178ff69dfe4682f3d50ac79537e0
author: Jean-Marc Valin <[email protected]>
date: Tue Dec 11 09:52:56 EST 2007
Added support for codebooks up to 64 bits.
--- a/libcelt/arch.h
+++ b/libcelt/arch.h
@@ -66,6 +66,7 @@
#endif
+typedef unsigned long long celt_uint64_t;
typedef int spx_int32_t;
typedef short spx_int16_t;
--- a/libcelt/cwrs.c
+++ b/libcelt/cwrs.c
@@ -95,6 +95,30 @@
}
#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 @@
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.
@@ -242,5 +334,52 @@
}
}
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;
}
*/
--- a/libcelt/cwrs.h
+++ b/libcelt/cwrs.h
@@ -32,6 +32,7 @@
#ifndef CWRS_H
#define CWRS_H
+#include "arch.h"
unsigned ncwrs(int _n,int _m);
@@ -42,5 +43,12 @@
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 */
--- a/libcelt/modes.c
+++ b/libcelt/modes.c
@@ -39,6 +39,7 @@
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};
--- a/libcelt/vq.c
+++ b/libcelt/vq.c
@@ -187,7 +187,7 @@
//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 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 @@
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]);