a9a1c58b0a32eda2f2837f34baa513f711af2907
[opus.git] / tests / test_opus_encode.c
1 /* Copyright (c) 2011 Xiph.Org Foundation
2    Written by Gregory Maxwell */
3 /*
4    Redistribution and use in source and binary forms, with or without
5    modification, are permitted provided that the following conditions
6    are met:
7
8    - Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10
11    - Redistributions in binary form must reproduce the above copyright
12    notice, this list of conditions and the following disclaimer in the
13    documentation and/or other materials provided with the distribution.
14
15    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <limits.h>
35 #include <stdint.h>
36 #include <math.h>
37 #include <string.h>
38 #include <time.h>
39 #if (!defined WIN32 && !defined _WIN32) || defined(__MINGW32__)
40 #include <unistd.h>
41 #else
42 #include <process.h>
43 #define getpid _getpid
44 #endif
45 #include "opus_multistream.h"
46 #include "opus.h"
47 #include "../src/opus_private.h"
48 #include "test_opus_common.h"
49
50 #define MAX_PACKET (1500)
51 #define SAMPLES (48000*30)
52 #define SSAMPLES (SAMPLES/3)
53 #define MAX_FRAME_SAMP (5760)
54
55 #define PI (3.141592653589793238462643f)
56
57 void generate_music(short *buf, opus_int32 len)
58 {
59    opus_int32 a1,b1,a2,b2;
60    opus_int32 c1,c2,d1,d2;
61    opus_int32 i,j;
62    a1=b1=a2=b2=0;
63    c1=c2=d1=d2=0;
64    j=0;
65    /*60ms silence*/
66    for(i=0;i<2880;i++)buf[i*2]=buf[i*2+1]=0;
67    for(i=2880;i<len;i++)
68    {
69      opus_uint32 r;
70      opus_int32 v1,v2;
71      v1=v2=(((j*((j>>12)^((j>>10|j>>12)&26&j>>7)))&128)+128)<<15;
72      r=fast_rand();v1+=r&65535;v1-=r>>16;
73      r=fast_rand();v2+=r&65535;v2-=r>>16;
74      b1=v1-a1+((b1*61+32)>>6);a1=v1;
75      b2=v2-a2+((b2*61+32)>>6);a2=v2;
76      c1=(30*(c1+b1+d1)+32)>>6;d1=b1;
77      c2=(30*(c2+b2+d2)+32)>>6;d2=b2;
78      v1=(c1+128)>>8;
79      v2=(c2+128)>>8;
80      buf[i*2]=v1>32767?32767:(v1<-32768?-32768:v1);
81      buf[i*2+1]=v2>32767?32767:(v2<-32768?-32768:v2);
82      if(i%6==0)j++;
83    }
84 }
85
86 #if 0
87 static int save_ctr = 0;
88 static void int_to_char(opus_uint32 i, unsigned char ch[4])
89 {
90     ch[0] = i>>24;
91     ch[1] = (i>>16)&0xFF;
92     ch[2] = (i>>8)&0xFF;
93     ch[3] = i&0xFF;
94 }
95
96 static inline void save_packet(unsigned char* p, int len, opus_uint32 rng)
97 {
98    FILE *fout;
99    unsigned char int_field[4];
100    char name[256];
101    snprintf(name,255,"test_opus_encode.%llu.%d.bit",(unsigned long long)iseed,save_ctr);
102    fprintf(stdout,"writing %d byte packet to %s\n",len,name);
103    fout=fopen(name, "wb+");
104    if(fout==NULL)test_failed();
105    int_to_char(len, int_field);
106    fwrite(int_field, 1, 4, fout);
107    int_to_char(rng, int_field);
108    fwrite(int_field, 1, 4, fout);
109    fwrite(p, 1, len, fout);
110    fclose(fout);
111    save_ctr++;
112 }
113 #endif
114
115 int run_test1(int no_fuzz)
116 {
117    static const int fsizes[6]={960*3,960*2,120,240,480,960};
118    static const char *mstrings[3] = {"    LP","Hybrid","  MDCT"};
119    unsigned char mapping[256] = {0,1,255};
120    unsigned char db62[36];
121    opus_int32 i;
122    int rc,j,err;
123    OpusEncoder *enc;
124    OpusMSEncoder *MSenc;
125    OpusDecoder *dec;
126    OpusMSDecoder *MSdec;
127    OpusMSDecoder *MSdec_err;
128    OpusDecoder *dec_err[10];
129    short *inbuf;
130    short *outbuf;
131    short *out2buf;
132    opus_int32 bitrate_bps;
133    unsigned char packet[MAX_PACKET];
134    opus_uint32 enc_final_range;
135    opus_uint32 dec_final_range;
136    int fswitch;
137    int fsize;
138    int count;
139
140   /*FIXME: encoder api tests, fs!=48k, mono, VBR*/
141
142    fprintf(stdout,"  Encode+Decode tests.\n");
143
144    enc = opus_encoder_create(48000, 2, OPUS_APPLICATION_VOIP, &err);
145    if(err != OPUS_OK || enc==NULL)test_failed();
146
147    MSenc = opus_multistream_encoder_create(8000, 2, 2, 0, mapping, OPUS_APPLICATION_AUDIO, &err);
148    if(err != OPUS_OK || MSenc==NULL)test_failed();
149
150    /*Some multistream encoder API tests*/
151    if(opus_multistream_encoder_ctl(MSenc, OPUS_GET_BITRATE(&i))!=OPUS_OK)test_failed();
152    if(opus_multistream_encoder_ctl(MSenc, OPUS_GET_LSB_DEPTH(&i))!=OPUS_OK)test_failed();
153    if(i<16)test_failed();
154
155    {
156       OpusEncoder *tmp_enc;
157       if(opus_multistream_encoder_ctl(MSenc,  OPUS_MULTISTREAM_GET_ENCODER_STATE(1,&tmp_enc))!=OPUS_OK)test_failed();
158       if(opus_encoder_ctl(tmp_enc, OPUS_GET_LSB_DEPTH(&j))!=OPUS_OK)test_failed();
159       if(i!=j)test_failed();
160       if(opus_multistream_encoder_ctl(MSenc,  OPUS_MULTISTREAM_GET_ENCODER_STATE(2,&tmp_enc))!=OPUS_BAD_ARG)test_failed();
161    }
162
163    dec = opus_decoder_create(48000, 2, &err);
164    if(err != OPUS_OK || dec==NULL)test_failed();
165
166    MSdec = opus_multistream_decoder_create(48000, 2, 2, 0, mapping, &err);
167    if(err != OPUS_OK || MSdec==NULL)test_failed();
168
169    MSdec_err = opus_multistream_decoder_create(48000, 3, 2, 0, mapping, &err);
170    if(err != OPUS_OK || MSdec_err==NULL)test_failed();
171
172    dec_err[0]=(OpusDecoder *)malloc(opus_decoder_get_size(2));
173    memcpy(dec_err[0],dec,opus_decoder_get_size(2));
174    dec_err[1] = opus_decoder_create(48000, 1, &err);
175    dec_err[2] = opus_decoder_create(24000, 2, &err);
176    dec_err[3] = opus_decoder_create(24000, 1, &err);
177    dec_err[4] = opus_decoder_create(16000, 2, &err);
178    dec_err[5] = opus_decoder_create(16000, 1, &err);
179    dec_err[6] = opus_decoder_create(12000, 2, &err);
180    dec_err[7] = opus_decoder_create(12000, 1, &err);
181    dec_err[8] = opus_decoder_create(8000, 2, &err);
182    dec_err[9] = opus_decoder_create(8000, 1, &err);
183    for(i=0;i<10;i++)if(dec_err[i]==NULL)test_failed();
184
185    {
186       OpusEncoder *enccpy;
187       /*The opus state structures contain no pointers and can be freely copied*/
188       enccpy=(OpusEncoder *)malloc(opus_encoder_get_size(2));
189       memcpy(enccpy,enc,opus_encoder_get_size(2));
190       memset(enc,255,opus_encoder_get_size(2));
191       opus_encoder_destroy(enc);
192       enc=enccpy;
193    }
194
195    inbuf=(short *)malloc(sizeof(short)*SAMPLES*2);
196    outbuf=(short *)malloc(sizeof(short)*SAMPLES*2);
197    out2buf=(short *)malloc(sizeof(short)*MAX_FRAME_SAMP*3);
198    if(inbuf==NULL || outbuf==NULL || out2buf==NULL)test_failed();
199
200    generate_music(inbuf,SAMPLES);
201
202 /*   FILE *foo;
203    foo = fopen("foo.sw", "wb+");
204    fwrite(inbuf, 1, SAMPLES*2*2, foo);
205    fclose(foo);*/
206
207    if(opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO))!=OPUS_OK)test_failed();
208    if(opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(-2))!=OPUS_BAD_ARG)test_failed();
209
210    for(rc=0;rc<3;rc++)
211    {
212       if(opus_encoder_ctl(enc, OPUS_SET_VBR(rc<2))!=OPUS_OK)test_failed();
213       if(opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(rc==1))!=OPUS_OK)test_failed();
214       if(opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(rc==1))!=OPUS_OK)test_failed();
215       if(opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(rc==0))!=OPUS_OK)test_failed();
216       for(j=0;j<13;j++)
217       {
218          int rate;
219          int modes[13]={0,0,0,1,1,1,1,2,2,2,2,2,2};
220          int rates[13]={6000,12000,48000,16000,32000,48000,64000,512000,13000,24000,48000,64000,96000};
221          int frame[13]={960*2,960,480,960,960,960,480,960*3,960*3,960,480,240,120};
222          rate=rates[j]+fast_rand()%rates[j];
223          count=i=0;
224          do {
225             int bw,len,out_samples,frame_size;
226             frame_size=frame[j];
227             if(fast_rand()%50==0)opus_encoder_ctl(enc, OPUS_RESET_STATE);
228             if(fast_rand()%50==0)opus_decoder_ctl(dec, OPUS_RESET_STATE);
229             if(opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(rc==0))!=OPUS_OK)test_failed();
230             if(opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_SILK_ONLY+modes[j]))!=OPUS_OK)test_failed();
231             if(opus_encoder_ctl(enc, OPUS_SET_DTX(fast_rand()&1))!=OPUS_OK)test_failed();
232             if(opus_encoder_ctl(enc, OPUS_SET_BITRATE(rate))!=OPUS_OK)test_failed();
233             if(opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS((rates[j]>=64000?2:1)))!=OPUS_OK)test_failed();
234             if(opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY((count>>2)%11))!=OPUS_OK)test_failed();
235             if(opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC((fast_rand()&15)&(fast_rand()%15)))!=OPUS_OK)test_failed();
236             bw=modes[j]==0?OPUS_BANDWIDTH_NARROWBAND+(fast_rand()%3):
237                modes[j]==1?OPUS_BANDWIDTH_SUPERWIDEBAND+(fast_rand()&1):
238                            OPUS_BANDWIDTH_NARROWBAND+(fast_rand()%5);
239             if(modes[j]==2&&bw==OPUS_BANDWIDTH_MEDIUMBAND)bw+=3;
240             if(opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bw))!=OPUS_OK)test_failed();
241             len = opus_encode(enc, &inbuf[i<<1], frame_size, packet, MAX_PACKET);
242             if(len<0 || len>MAX_PACKET)test_failed();
243             if(opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range))!=OPUS_OK)test_failed();
244             out_samples = opus_decode(dec, packet, len, &outbuf[i<<1], MAX_FRAME_SAMP, 0);
245             if(out_samples!=frame_size)test_failed();
246             if(opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range))!=OPUS_OK)test_failed();
247             if(enc_final_range!=dec_final_range)test_failed();
248             /*LBRR decode*/
249             out_samples = opus_decode(dec_err[0], packet, len, out2buf, MAX_FRAME_SAMP, (fast_rand()&3)!=0);
250             if(out_samples!=frame_size)test_failed();
251             out_samples = opus_decode(dec_err[1], packet, (fast_rand()&3)==0?0:len, out2buf, MAX_FRAME_SAMP, (fast_rand()&7)!=0);
252             if(out_samples<120)test_failed();
253             i+=frame_size;
254             count++;
255          }while(i<(SSAMPLES-MAX_FRAME_SAMP));
256          fprintf(stdout,"    Mode %s FB encode %s, %6d bps OK.\n",mstrings[modes[j]],rc==0?" VBR":rc==1?"CVBR":" CBR",rate);
257       }
258    }
259
260    if(opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(OPUS_AUTO))!=OPUS_OK)test_failed();
261    if(opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(OPUS_AUTO))!=OPUS_OK)test_failed();
262    if(opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0))!=OPUS_OK)test_failed();
263    if(opus_encoder_ctl(enc, OPUS_SET_DTX(0))!=OPUS_OK)test_failed();
264
265    for(rc=0;rc<3;rc++)
266    {
267       if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_VBR(rc<2))!=OPUS_OK)test_failed();
268       if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_VBR_CONSTRAINT(rc==1))!=OPUS_OK)test_failed();
269       if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_VBR_CONSTRAINT(rc==1))!=OPUS_OK)test_failed();
270       if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_INBAND_FEC(rc==0))!=OPUS_OK)test_failed();
271       for(j=0;j<16;j++)
272       {
273          int rate;
274          int modes[16]={0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2};
275          int rates[16]={4000,12000,32000,8000,16000,32000,48000,88000,4000,12000,32000,8000,16000,32000,48000,88000};
276          int frame[16]={160*1,160,80,160,160,80,40,20,160*1,160,80,160,160,80,40,20};
277          if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_INBAND_FEC(rc==0&&j==1))!=OPUS_OK)test_failed();
278          if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_FORCE_MODE(MODE_SILK_ONLY+modes[j]))!=OPUS_OK)test_failed();
279          rate=rates[j]+fast_rand()%rates[j];
280          if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_DTX(fast_rand()&1))!=OPUS_OK)test_failed();
281          if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_BITRATE(rate))!=OPUS_OK)test_failed();
282          count=i=0;
283          do {
284             int len,out_samples,frame_size,loss;
285             frame_size=frame[j];
286             if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_COMPLEXITY((count>>2)%11))!=OPUS_OK)test_failed();
287             if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_PACKET_LOSS_PERC((fast_rand()&15)&(fast_rand()%15)))!=OPUS_OK)test_failed();
288             len = opus_multistream_encode(MSenc, &inbuf[i<<1], frame_size, packet, MAX_PACKET);
289             if(len<0 || len>MAX_PACKET)test_failed();
290             if(opus_multistream_encoder_ctl(MSenc, OPUS_GET_FINAL_RANGE(&enc_final_range))!=OPUS_OK)test_failed();
291             out_samples = opus_multistream_decode(MSdec, packet, len, out2buf, MAX_FRAME_SAMP, 0);
292             if(out_samples!=frame_size*6)test_failed();
293             if(opus_multistream_decoder_ctl(MSdec, OPUS_GET_FINAL_RANGE(&dec_final_range))!=OPUS_OK)test_failed();
294             if(enc_final_range!=dec_final_range)test_failed();
295             /*LBRR decode*/
296             loss=(fast_rand()&63)==0;
297             out_samples = opus_multistream_decode(MSdec_err, packet, loss?0:len, out2buf, MAX_FRAME_SAMP, (fast_rand()&3)!=0);
298             if(loss?out_samples<120:out_samples!=(frame_size*6))test_failed();
299             i+=frame_size;
300             count++;
301          }while(i<(SSAMPLES/12-MAX_FRAME_SAMP));
302          fprintf(stdout,"    Mode %s NB dual-mono MS encode %s, %6d bps OK.\n",mstrings[modes[j]],rc==0?" VBR":rc==1?"CVBR":" CBR",rate);
303       }
304    }
305
306    bitrate_bps=512000;
307    fsize=fast_rand()%31;
308    fswitch=100;
309
310    debruijn2(6,db62);
311    count=i=0;
312    do {
313       unsigned char toc;
314       const unsigned char *frames[48];
315       short size[48];
316       int payload_offset;
317       opus_uint32 dec_final_range2;
318       int jj,dec2;
319       int len,out_samples;
320       int frame_size=fsizes[db62[fsize]];
321       opus_int32 offset=i%(SAMPLES-MAX_FRAME_SAMP);
322
323       opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
324
325       len = opus_encode(enc, &inbuf[offset<<1], frame_size, packet, MAX_PACKET);
326       if(len<0 || len>MAX_PACKET)test_failed();
327       count++;
328
329       opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range));
330
331       out_samples = opus_decode(dec, packet, len, &outbuf[offset<<1], MAX_FRAME_SAMP, 0);
332       if(out_samples!=frame_size)test_failed();
333
334       opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range));
335
336       /* compare final range encoder rng values of encoder and decoder */
337       if(dec_final_range!=enc_final_range)test_failed();
338
339       /* We fuzz the packet, but take care not to only corrupt the payload
340          Corrupted headers are tested elsewhere and we need to actually run
341          the decoders in order to compare them. */
342       if(opus_packet_parse(packet,len,&toc,frames,size,&payload_offset)<=0)test_failed();
343       if((fast_rand()&1023)==0)len=0;
344       for(j=(frames[0]-packet);j<len;j++)for(jj=0;jj<8;jj++)packet[j]^=((!no_fuzz)&&((fast_rand()&1023)==0))<<jj;
345       out_samples = opus_decode(dec_err[0], len>0?packet:NULL, len, out2buf, MAX_FRAME_SAMP, 0);
346       if(out_samples<0||out_samples>MAX_FRAME_SAMP)test_failed();
347       if((len>0&&out_samples!=frame_size))test_failed(); /*FIXME use lastframe*/
348
349       opus_decoder_ctl(dec_err[0], OPUS_GET_FINAL_RANGE(&dec_final_range));
350
351       /*randomly select one of the decoders to compare with*/
352       dec2=fast_rand()%9+1;
353       out_samples = opus_decode(dec_err[dec2], len>0?packet:NULL, len, out2buf, MAX_FRAME_SAMP, 0);
354       if(out_samples<0||out_samples>MAX_FRAME_SAMP)test_failed(); /*FIXME, use factor, lastframe for loss*/
355
356       opus_decoder_ctl(dec_err[dec2], OPUS_GET_FINAL_RANGE(&dec_final_range2));
357       if(len>0&&dec_final_range!=dec_final_range2)test_failed();
358
359       fswitch--;
360       if(fswitch<1)
361       {
362         int new_size;
363         fsize=(fsize+1)%36;
364         new_size=fsizes[db62[fsize]];
365         if(new_size==960||new_size==480)fswitch=2880/new_size*(fast_rand()%19+1);
366         else fswitch=(fast_rand()%(2880/new_size))+1;
367       }
368       bitrate_bps=((fast_rand()%508000+4000)+bitrate_bps)>>1;
369       i+=frame_size;
370    }while(i<SAMPLES*4);
371    fprintf(stdout,"    All framesize pairs switching encode, %d frames OK.\n",count);
372
373    opus_encoder_destroy(enc);
374    opus_multistream_encoder_destroy(MSenc);
375    opus_decoder_destroy(dec);
376    opus_multistream_decoder_destroy(MSdec);
377    opus_multistream_decoder_destroy(MSdec_err);
378    for(i=0;i<10;i++)opus_decoder_destroy(dec_err[i]);
379    free(inbuf);
380    free(outbuf);
381    free(out2buf);
382    return 0;
383 }
384
385 int main(int _argc, char **_argv)
386 {
387    const char * oversion;
388    const char * env_seed;
389    int env_used;
390
391    if(_argc>2)
392    {
393       fprintf(stderr,"Usage: %s [<seed>]\n",_argv[0]);
394       return 1;
395    }
396
397    env_used=0;
398    env_seed=getenv("SEED");
399    if(_argc>1)iseed=atoi(_argv[1]);
400    else if(env_seed)
401    {
402       iseed=atoi(env_seed);
403       env_used=1;
404    }
405    else iseed=(opus_uint32)time(NULL)^((getpid()&65535)<<16);
406    Rw=Rz=iseed;
407
408    oversion=opus_get_version_string();
409    if(!oversion)test_failed();
410    fprintf(stderr,"Testing %s encoder. Random seed: %u (%.4X)\n", oversion, iseed, fast_rand() % 65535);
411    if(env_used)fprintf(stderr,"  Random seed set from the environment (SEED=%s).\n", env_seed);
412
413    /*Setting TEST_OPUS_NOFUZZ tells the tool not to send garbage data
414      into the decoders. This is helpful because garbage data
415      may cause the decoders to clip, which angers CLANG IOC.*/
416    run_test1(getenv("TEST_OPUS_NOFUZZ")!=NULL);
417
418    fprintf(stderr,"Tests completed successfully.\n");
419
420    return 0;
421 }