fb8fe5eefb0139d783e8bc074be945c250e158ec
[opus.git] / libcelt / tests / ectest.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <math.h>
8 #include <time.h>
9 #include "entcode.h"
10 #include "entenc.h"
11 #include "entdec.h"
12 #include <string.h>
13
14 #include "../libcelt/entenc.c"
15 #include "../libcelt/entdec.c"
16 #include "../libcelt/entcode.c"
17
18 #ifndef M_LOG2E
19 # define M_LOG2E    1.4426950408889634074
20 #endif
21 #define DATA_SIZE 10000000
22 #define DATA_SIZE2 10000
23
24 int main(int _argc,char **_argv){
25   ec_enc         enc;
26   ec_dec         dec;
27   long           nbits;
28   long           nbits2;
29   double         entropy;
30   int            ft;
31   int            ftb;
32   int            sz;
33   int            i;
34   int            ret;
35   unsigned int   sym;
36   unsigned int   seed;
37   unsigned char *ptr;
38   ret=0;
39   entropy=0;
40     if (_argc > 2) {
41         fprintf(stderr, "Usage: %s [<seed>]\n", _argv[0]);
42         return 1;
43     }
44     if (_argc > 1)
45         seed = atoi(_argv[1]);
46     else
47         seed = time(NULL);
48   /*Testing encoding of raw bit values.*/
49   ptr = (unsigned char *)malloc(DATA_SIZE);
50   ec_enc_init(&enc,ptr, DATA_SIZE);
51   for(ft=2;ft<1024;ft++){
52     for(i=0;i<ft;i++){
53       entropy+=log(ft)*M_LOG2E;
54       ec_enc_uint(&enc,i,ft);
55     }
56   }
57   /*Testing encoding of raw bit values.*/
58   for(ftb=0;ftb<16;ftb++){
59     for(i=0;i<(1<<ftb);i++){
60       entropy+=ftb;
61       nbits=ec_tell(&enc);
62       ec_enc_bits(&enc,i,ftb);
63       nbits2=ec_tell(&enc);
64       if(nbits2-nbits!=ftb){
65         fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
66          nbits2-nbits,ftb);
67         ret=-1;
68       }
69     }
70   }
71   nbits=ec_tell_frac(&enc);
72   ec_enc_done(&enc);
73   fprintf(stderr,
74    "Encoded %0.2lf bits of entropy to %0.2lf bits (%0.3lf%% wasted).\n",
75    entropy,ldexp(nbits,-3),100*(nbits-ldexp(entropy,3))/nbits);
76   fprintf(stderr,"Packed to %li bytes.\n",(long)ec_range_bytes(&enc));
77   ec_dec_init(&dec,ptr,DATA_SIZE);
78   for(ft=2;ft<1024;ft++){
79     for(i=0;i<ft;i++){
80       sym=ec_dec_uint(&dec,ft);
81       if(sym!=(unsigned)i){
82         fprintf(stderr,"Decoded %i instead of %i with ft of %i.\n",sym,i,ft);
83         ret=-1;
84       }
85     }
86   }
87   for(ftb=0;ftb<16;ftb++){
88     for(i=0;i<(1<<ftb);i++){
89       sym=ec_dec_bits(&dec,ftb);
90       if(sym!=(unsigned)i){
91         fprintf(stderr,"Decoded %i instead of %i with ftb of %i.\n",sym,i,ftb);
92         ret=-1;
93       }
94     }
95   }
96   nbits2=ec_tell_frac(&dec);
97   if(nbits!=nbits2){
98     fprintf(stderr,
99      "Reported number of bits used was %0.2lf, should be %0.2lf.\n",
100      ldexp(nbits2,-3),ldexp(nbits,-3));
101     ret=-1;
102   }
103   srand(seed);
104   fprintf(stderr,"Testing random streams... Random seed: %u (%.4X)\n", seed, rand() % 65536);
105   for(i=0;i<409600;i++){
106     unsigned *data;
107     unsigned *tell;
108     unsigned tell_bits;
109     int       j;
110     int zeros;
111     ft=rand()/((RAND_MAX>>(rand()%11))+1)+10;
112     sz=rand()/((RAND_MAX>>(rand()%9))+1);
113     data=(unsigned *)malloc(sz*sizeof(*data));
114     tell=(unsigned *)malloc((sz+1)*sizeof(*tell));
115     ec_enc_init(&enc,ptr,DATA_SIZE2);
116     zeros = rand()%13==0;
117     tell[0]=ec_tell_frac(&enc);
118     for(j=0;j<sz;j++){
119       if (zeros)
120         data[j]=0;
121       else
122         data[j]=rand()%ft;
123       ec_enc_uint(&enc,data[j],ft);
124       tell[j+1]=ec_tell_frac(&enc);
125     }
126     if (rand()%2==0)
127       while(ec_tell(&enc)%8 != 0)
128         ec_enc_uint(&enc, rand()%2, 2);
129     tell_bits = ec_tell(&enc);
130     ec_enc_done(&enc);
131     if(tell_bits!=(unsigned)ec_tell(&enc)){
132       fprintf(stderr,"ec_tell() changed after ec_enc_done(): %i instead of %i (Random seed: %u)\n",
133        ec_tell(&enc),tell_bits,seed);
134       ret=-1;
135     }
136     if ((tell_bits+7)/8 < ec_range_bytes(&enc))
137     {
138       fprintf (stderr, "ec_tell() lied, there's %i bytes instead of %d (Random seed: %u)\n",
139                ec_range_bytes(&enc), (tell_bits+7)/8,seed);
140       ret=-1;
141     }
142     tell_bits -= 8*ec_range_bytes(&enc);
143     ec_dec_init(&dec,ptr,DATA_SIZE2);
144     if(ec_tell_frac(&dec)!=tell[0]){
145       fprintf(stderr,
146        "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
147        0,ec_tell_frac(&dec),tell[0],seed);
148     }
149     for(j=0;j<sz;j++){
150       sym=ec_dec_uint(&dec,ft);
151       if(sym!=data[j]){
152         fprintf(stderr,
153          "Decoded %i instead of %i with ft of %i at position %i of %i (Random seed: %u).\n",
154          sym,data[j],ft,j,sz,seed);
155         ret=-1;
156       }
157       if(ec_tell_frac(&dec)!=tell[j+1]){
158         fprintf(stderr,
159          "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
160          j+1,ec_tell_frac(&dec),tell[j+1],seed);
161       }
162     }
163     free(tell);
164     free(data);
165   }
166   /*Test compatibility between multiple different encode/decode routines.*/
167   for(i=0;i<409600;i++){
168     unsigned *logp1;
169     unsigned *data;
170     unsigned *tell;
171     unsigned *enc_method;
172     int       j;
173     sz=rand()/((RAND_MAX>>(rand()%9))+1);
174     logp1=(unsigned *)malloc(sz*sizeof(*logp1));
175     data=(unsigned *)malloc(sz*sizeof(*data));
176     tell=(unsigned *)malloc((sz+1)*sizeof(*tell));
177     enc_method=(unsigned *)malloc(sz*sizeof(*enc_method));
178     ec_enc_init(&enc,ptr,DATA_SIZE2);
179     tell[0]=ec_tell_frac(&enc);
180     for(j=0;j<sz;j++){
181       data[j]=rand()/((RAND_MAX>>1)+1);
182       logp1[j]=(rand()%15)+1;
183       enc_method[j]=rand()/((RAND_MAX>>2)+1);
184       switch(enc_method[j]){
185         case 0:{
186           ec_encode(&enc,data[j]?(1<<logp1[j])-1:0,
187            (1<<logp1[j])-(data[j]?0:1),1<<logp1[j]);
188         }break;
189         case 1:{
190           ec_encode_bin(&enc,data[j]?(1<<logp1[j])-1:0,
191            (1<<logp1[j])-(data[j]?0:1),logp1[j]);
192         }break;
193         case 2:{
194           ec_enc_bit_logp(&enc,data[j],logp1[j]);
195         }break;
196         case 3:{
197           unsigned char icdf[2];
198           icdf[0]=1;
199           icdf[1]=0;
200           ec_enc_icdf(&enc,data[j],icdf,logp1[j]);
201         }break;
202       }
203       tell[j+1]=ec_tell_frac(&enc);
204     }
205     ec_enc_done(&enc);
206     if((ec_tell(&enc)+7U)/8U<ec_range_bytes(&enc)){
207       fprintf(stderr,"tell() lied, there's %i bytes instead of %d (Random seed: %u)\n",
208        ec_range_bytes(&enc),(ec_tell(&enc)+7)/8,seed);
209       ret=-1;
210     }
211     ec_dec_init(&dec,ptr,DATA_SIZE2);
212     if(ec_tell_frac(&dec)!=tell[0]){
213       fprintf(stderr,
214        "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
215        0,ec_tell_frac(&dec),tell[0],seed);
216     }
217     for(j=0;j<sz;j++){
218       int fs;
219       int dec_method;
220       dec_method=rand()/((RAND_MAX>>2)+1);
221       switch(dec_method){
222         case 0:{
223           fs=ec_decode(&dec,1<<logp1[j]);
224           sym=fs>=(1<<logp1[j])-1;
225           ec_dec_update(&dec,sym?(1<<logp1[j])-1:0,
226            (1<<logp1[j])-(sym?0:1),1<<logp1[j]);
227         }break;
228         case 1:{
229           fs=ec_decode_bin(&dec,logp1[j]);
230           sym=fs>=(1<<logp1[j])-1;
231           ec_dec_update(&dec,sym?(1<<logp1[j])-1:0,
232            (1<<logp1[j])-(sym?0:1),1<<logp1[j]);
233         }break;
234         case 2:{
235           sym=ec_dec_bit_logp(&dec,logp1[j]);
236         }break;
237         case 3:{
238           unsigned char icdf[2];
239           icdf[0]=1;
240           icdf[1]=0;
241           sym=ec_dec_icdf(&dec,icdf,logp1[j]);
242         }break;
243       }
244       if(sym!=data[j]){
245         fprintf(stderr,
246          "Decoded %i instead of %i with logp1 of %i at position %i of %i (Random seed: %u).\n",
247          sym,data[j],logp1[j],j,sz,seed);
248         fprintf(stderr,"Encoding method: %i, decoding method: %i\n",
249          enc_method[j],dec_method);
250         ret=-1;
251       }
252       if(ec_tell_frac(&dec)!=tell[j+1]){
253         fprintf(stderr,
254          "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
255          j+1,ec_tell_frac(&dec),tell[j+1],seed);
256       }
257     }
258     free(enc_method);
259     free(tell);
260     free(data);
261     free(logp1);
262   }
263   free(ptr);
264   return ret;
265 }