1/* Copyright (c) 2011-2013 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.h"
46#include "test_opus_common.h"
47
48#define MAX_PACKET (1500)
49#define MAX_FRAME_SAMP (5760)
50
51int test_decoder_code0(int no_fuzz)
52{
53   static const opus_int32 fsv[5]={48000,24000,16000,12000,8000};
54   int err,skip,plen;
55   int out_samples,fec;
56   int t;
57   opus_int32 i;
58   OpusDecoder *dec[5*2];
59   opus_int32 decsize;
60   OpusDecoder *decbak;
61   opus_uint32 dec_final_range1,dec_final_range2,dec_final_acc;
62   unsigned char *packet;
63   unsigned char modes[4096];
64   short *outbuf_int;
65   short *outbuf;
66
67   dec_final_range1=dec_final_range2=2;
68
69   packet=malloc(sizeof(unsigned char)*MAX_PACKET);
70   if(packet==NULL)test_failed();
71
72   outbuf_int=malloc(sizeof(short)*(MAX_FRAME_SAMP+16)*2);
73   for(i=0;i<(MAX_FRAME_SAMP+16)*2;i++)outbuf_int[i]=32749;
74   outbuf=&outbuf_int[8*2];
75
76   fprintf(stdout,"  Starting %d decoders...\n",5*2);
77   for(t=0;t<5*2;t++)
78   {
79      int fs=fsv[t>>1];
80      int c=(t&1)+1;
81      err=OPUS_INTERNAL_ERROR;
82      dec[t] = opus_decoder_create(fs, c, &err);
83      if(err!=OPUS_OK || dec[t]==NULL)test_failed();
84      fprintf(stdout,"    opus_decoder_create(%5d,%d) OK. Copy ",fs,c);
85      {
86         OpusDecoder *dec2;
87         /*The opus state structures contain no pointers and can be freely copied*/
88         dec2=(OpusDecoder *)malloc(opus_decoder_get_size(c));
89         if(dec2==NULL)test_failed();
90         memcpy(dec2,dec[t],opus_decoder_get_size(c));
91         memset(dec[t],255,opus_decoder_get_size(c));
92         opus_decoder_destroy(dec[t]);
93         printf("OK.\n");
94         dec[t]=dec2;
95      }
96   }
97
98   decsize=opus_decoder_get_size(1);
99   decbak=(OpusDecoder *)malloc(decsize);
100   if(decbak==NULL)test_failed();
101
102   for(t=0;t<5*2;t++)
103   {
104      int factor=48000/fsv[t>>1];
105      for(fec=0;fec<2;fec++)
106      {
107         int dur;
108         /*Test PLC on a fresh decoder*/
109         out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, fec);
110         if(out_samples!=120/factor)test_failed();
111         if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
112         if(dur!=120/factor)test_failed();
113
114         /*Test on a size which isn't a multiple of 2.5ms*/
115         out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor+2, fec);
116         if(out_samples!=OPUS_BAD_ARG)test_failed();
117
118         /*Test null pointer input*/
119         out_samples = opus_decode(dec[t], 0, -1, outbuf, 120/factor, fec);
120         if(out_samples!=120/factor)test_failed();
121         out_samples = opus_decode(dec[t], 0, 1, outbuf, 120/factor, fec);
122         if(out_samples!=120/factor)test_failed();
123         out_samples = opus_decode(dec[t], 0, 10, outbuf, 120/factor, fec);
124         if(out_samples!=120/factor)test_failed();
125         out_samples = opus_decode(dec[t], 0, fast_rand(), outbuf, 120/factor, fec);
126         if(out_samples!=120/factor)test_failed();
127         if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
128         if(dur!=120/factor)test_failed();
129
130         /*Zero lengths*/
131         out_samples = opus_decode(dec[t], packet, 0, outbuf, 120/factor, fec);
132         if(out_samples!=120/factor)test_failed();
133
134         /*Zero buffer*/
135         outbuf[0]=32749;
136         out_samples = opus_decode(dec[t], packet, 0, outbuf, 0, fec);
137         if(out_samples>0)test_failed();
138         out_samples = opus_decode(dec[t], packet, 0, 0, 0, fec);
139         if(out_samples>0)test_failed();
140         if(outbuf[0]!=32749)test_failed();
141
142         /*Invalid lengths*/
143         out_samples = opus_decode(dec[t], packet, -1, outbuf, MAX_FRAME_SAMP, fec);
144         if(out_samples>=0)test_failed();
145         out_samples = opus_decode(dec[t], packet, INT_MIN, outbuf, MAX_FRAME_SAMP, fec);
146         if(out_samples>=0)test_failed();
147         out_samples = opus_decode(dec[t], packet, -1, outbuf, -1, fec);
148         if(out_samples>=0)test_failed();
149
150         /*Crazy FEC values*/
151         out_samples = opus_decode(dec[t], packet, 1, outbuf, MAX_FRAME_SAMP, fec?-1:2);
152         if(out_samples>=0)test_failed();
153
154         /*Reset the decoder*/
155         if(opus_decoder_ctl(dec[t], OPUS_RESET_STATE)!=OPUS_OK)test_failed();
156      }
157   }
158   fprintf(stdout,"  dec[all] initial frame PLC OK.\n");
159
160   /*Count code 0 tests*/
161   for(i=0;i<64;i++)
162   {
163      int dur;
164      int j,expected[5*2];
165      packet[0]=i<<2;
166      packet[1]=255;
167      packet[2]=255;
168      err=opus_packet_get_nb_channels(packet);
169      if(err!=(i&1)+1)test_failed();
170
171      for(t=0;t<5*2;t++){
172         expected[t]=opus_decoder_get_nb_samples(dec[t],packet,1);
173         if(expected[t]>2880)test_failed();
174      }
175
176      for(j=0;j<256;j++)
177      {
178         packet[1]=j;
179         for(t=0;t<5*2;t++)
180         {
181            out_samples = opus_decode(dec[t], packet, 3, outbuf, MAX_FRAME_SAMP, 0);
182            if(out_samples!=expected[t])test_failed();
183            if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
184            if(dur!=out_samples)test_failed();
185            opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
186            if(t==0)dec_final_range2=dec_final_range1;
187            else if(dec_final_range1!=dec_final_range2)test_failed();
188         }
189      }
190
191      for(t=0;t<5*2;t++){
192         int factor=48000/fsv[t>>1];
193         /* The PLC is run for 6 frames in order to get better PLC coverage. */
194         for(j=0;j<6;j++)
195         {
196            out_samples = opus_decode(dec[t], 0, 0, outbuf, expected[t], 0);
197            if(out_samples!=expected[t])test_failed();
198            if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
199            if(dur!=out_samples)test_failed();
200         }
201         /* Run the PLC once at 2.5ms, as a simulation of someone trying to
202            do small drift corrections. */
203         if(expected[t]!=120/factor)
204         {
205            out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, 0);
206            if(out_samples!=120/factor)test_failed();
207            if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
208            if(dur!=out_samples)test_failed();
209         }
210         out_samples = opus_decode(dec[t], packet, 2, outbuf, expected[t]-1, 0);
211         if(out_samples>0)test_failed();
212      }
213   }
214   fprintf(stdout,"  dec[all] all 2-byte prefix for length 3 and PLC, all modes (64) OK.\n");
215
216   if(no_fuzz)
217   {
218      fprintf(stdout,"  Skipping many tests which fuzz the decoder as requested.\n");
219      free(decbak);
220      for(t=0;t<5*2;t++)opus_decoder_destroy(dec[t]);
221      printf("  Decoders stopped.\n");
222
223      err=0;
224      for(i=0;i<8*2;i++)err|=outbuf_int[i]!=32749;
225      for(i=MAX_FRAME_SAMP*2;i<(MAX_FRAME_SAMP+8)*2;i++)err|=outbuf[i]!=32749;
226      if(err)test_failed();
227
228      free(outbuf_int);
229      free(packet);
230      return 0;
231   }
232
233   {
234     /*We only test a subset of the modes here simply because the longer
235       durations end up taking a long time.*/
236      static const int cmodes[4]={16,20,24,28};
237      static const opus_uint32 cres[4]={116290185,2172123586u,2172123586u,2172123586u};
238      static const opus_uint32 lres[3]={3285687739u,1481572662,694350475};
239      static const int lmodes[3]={0,4,8};
240      int mode=fast_rand()%4;
241
242      packet[0]=cmodes[mode]<<3;
243      dec_final_acc=0;
244      t=fast_rand()%10;
245
246      for(i=0;i<65536;i++)
247      {
248         int factor=48000/fsv[t>>1];
249         packet[1]=i>>8;
250         packet[2]=i&255;
251         packet[3]=255;
252         out_samples = opus_decode(dec[t], packet, 4, outbuf, MAX_FRAME_SAMP, 0);
253         if(out_samples!=120/factor)test_failed();
254         opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
255         dec_final_acc+=dec_final_range1;
256      }
257      if(dec_final_acc!=cres[mode])test_failed();
258      fprintf(stdout,"  dec[%3d] all 3-byte prefix for length 4, mode %2d OK.\n",t,cmodes[mode]);
259
260      mode=fast_rand()%3;
261      packet[0]=lmodes[mode]<<3;
262      dec_final_acc=0;
263      t=fast_rand()%10;
264      for(i=0;i<65536;i++)
265      {
266         int factor=48000/fsv[t>>1];
267         packet[1]=i>>8;
268         packet[2]=i&255;
269         packet[3]=255;
270         out_samples = opus_decode(dec[t], packet, 4, outbuf, MAX_FRAME_SAMP, 0);
271         if(out_samples!=480/factor)test_failed();
272         opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
273         dec_final_acc+=dec_final_range1;
274      }
275      if(dec_final_acc!=lres[mode])test_failed();
276      fprintf(stdout,"  dec[%3d] all 3-byte prefix for length 4, mode %2d OK.\n",t,lmodes[mode]);
277   }
278
279   skip=fast_rand()%7;
280   for(i=0;i<64;i++)
281   {
282      int j,expected[5*2];
283      packet[0]=i<<2;
284      for(t=0;t<5*2;t++)expected[t]=opus_decoder_get_nb_samples(dec[t],packet,1);
285      for(j=2+skip;j<1275;j+=4)
286      {
287         int jj;
288         for(jj=0;jj<j;jj++)packet[jj+1]=fast_rand()&255;
289         for(t=0;t<5*2;t++)
290         {
291            out_samples = opus_decode(dec[t], packet, j+1, outbuf, MAX_FRAME_SAMP, 0);
292            if(out_samples!=expected[t])test_failed();
293            opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
294            if(t==0)dec_final_range2=dec_final_range1;
295            else if(dec_final_range1!=dec_final_range2)test_failed();
296         }
297      }
298   }
299   fprintf(stdout,"  dec[all] random packets, all modes (64), every 8th size from from %d bytes to maximum OK.\n",2+skip);
300
301   debruijn2(64,modes);
302   plen=(fast_rand()%18+3)*8+skip+3;
303   for(i=0;i<4096;i++)
304   {
305      int j,expected[5*2];
306      packet[0]=modes[i]<<2;
307      for(t=0;t<5*2;t++)expected[t]=opus_decoder_get_nb_samples(dec[t],packet,plen);
308      for(j=0;j<plen;j++)packet[j+1]=(fast_rand()|fast_rand())&255;
309      memcpy(decbak,dec[0],decsize);
310      if(opus_decode(decbak, packet, plen+1, outbuf, expected[0], 1)!=expected[0])test_failed();
311      memcpy(decbak,dec[0],decsize);
312      if(opus_decode(decbak,  0, 0, outbuf, MAX_FRAME_SAMP, 1)<20)test_failed();
313      memcpy(decbak,dec[0],decsize);
314      if(opus_decode(decbak,  0, 0, outbuf, MAX_FRAME_SAMP, 0)<20)test_failed();
315      for(t=0;t<5*2;t++)
316      {
317         int dur;
318         out_samples = opus_decode(dec[t], packet, plen+1, outbuf, MAX_FRAME_SAMP, 0);
319         if(out_samples!=expected[t])test_failed();
320         if(t==0)dec_final_range2=dec_final_range1;
321         else if(dec_final_range1!=dec_final_range2)test_failed();
322         if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
323         if(dur!=out_samples)test_failed();
324      }
325   }
326   fprintf(stdout,"  dec[all] random packets, all mode pairs (4096), %d bytes/frame OK.\n",plen+1);
327
328   plen=(fast_rand()%18+3)*8+skip+3;
329   t=rand()&3;
330   for(i=0;i<4096;i++)
331   {
332      int count,j,expected;
333      packet[0]=modes[i]<<2;
334      expected=opus_decoder_get_nb_samples(dec[t],packet,plen);
335      for(count=0;count<10;count++)
336      {
337         for(j=0;j<plen;j++)packet[j+1]=(fast_rand()|fast_rand())&255;
338         out_samples = opus_decode(dec[t], packet, plen+1, outbuf, MAX_FRAME_SAMP, 0);
339         if(out_samples!=expected)test_failed();
340      }
341   }
342   fprintf(stdout,"  dec[%3d] random packets, all mode pairs (4096)*10, %d bytes/frame OK.\n",t,plen+1);
343
344   {
345      int tmodes[1]={25<<2};
346      opus_uint32 tseeds[1]={140441};
347      int tlen[1]={157};
348      opus_int32 tret[1]={480};
349      t=fast_rand()&1;
350      for(i=0;i<1;i++)
351      {
352         int j;
353         packet[0]=tmodes[i];
354         Rw=Rz=tseeds[i];
355         for(j=1;j<tlen[i];j++)packet[j]=fast_rand()&255;
356         out_samples=opus_decode(dec[t], packet, tlen[i], outbuf, MAX_FRAME_SAMP, 0);
357         if(out_samples!=tret[i])test_failed();
358      }
359      fprintf(stdout,"  dec[%3d] pre-selected random packets OK.\n",t);
360   }
361
362   free(decbak);
363   for(t=0;t<5*2;t++)opus_decoder_destroy(dec[t]);
364   printf("  Decoders stopped.\n");
365
366   err=0;
367   for(i=0;i<8*2;i++)err|=outbuf_int[i]!=32749;
368   for(i=MAX_FRAME_SAMP*2;i<(MAX_FRAME_SAMP+8)*2;i++)err|=outbuf[i]!=32749;
369   if(err)test_failed();
370
371   free(outbuf_int);
372   free(packet);
373   return 0;
374}
375
376#ifndef DISABLE_FLOAT_API
377void test_soft_clip(void)
378{
379   int i,j;
380   float x[1024];
381   float s[8] = {0, 0, 0, 0, 0, 0, 0, 0};
382   fprintf(stdout,"  Testing opus_pcm_soft_clip... ");
383   for(i=0;i<1024;i++)
384   {
385      for (j=0;j<1024;j++)
386      {
387        x[j]=(i&255)*(1/32.f)-4.f;
388      }
389      opus_pcm_soft_clip(&x[i],1024-i,1,s);
390      for (j=i;j<1024;j++)
391      {
392        if(x[i]>1.f)test_failed();
393        if(x[i]<-1.f)test_failed();
394      }
395   }
396   for(i=1;i<9;i++)
397   {
398      for (j=0;j<1024;j++)
399      {
400        x[j]=(i&255)*(1/32.f)-4.f;
401      }
402      opus_pcm_soft_clip(x,1024/i,i,s);
403      for (j=0;j<(1024/i)*i;j++)
404      {
405        if(x[i]>1.f)test_failed();
406        if(x[i]<-1.f)test_failed();
407      }
408   }
409   opus_pcm_soft_clip(x,0,1,s);
410   opus_pcm_soft_clip(x,1,0,s);
411   opus_pcm_soft_clip(x,1,1,0);
412   opus_pcm_soft_clip(x,1,-1,s);
413   opus_pcm_soft_clip(x,-1,1,s);
414   opus_pcm_soft_clip(0,1,1,s);
415   printf("OK.\n");
416}
417#endif
418
419int main(int _argc, char **_argv)
420{
421   const char * oversion;
422   const char * env_seed;
423   int env_used;
424
425   if(_argc>2)
426   {
427      fprintf(stderr,"Usage: %s [<seed>]\n",_argv[0]);
428      return 1;
429   }
430
431   env_used=0;
432   env_seed=getenv("SEED");
433   if(_argc>1)iseed=atoi(_argv[1]);
434   else if(env_seed)
435   {
436      iseed=atoi(env_seed);
437      env_used=1;
438   }
439   else iseed=(opus_uint32)time(NULL)^((getpid()&65535)<<16);
440   Rw=Rz=iseed;
441
442   oversion=opus_get_version_string();
443   if(!oversion)test_failed();
444   fprintf(stderr,"Testing %s decoder. Random seed: %u (%.4X)\n", oversion, iseed, fast_rand() % 65535);
445   if(env_used)fprintf(stderr,"  Random seed set from the environment (SEED=%s).\n", env_seed);
446
447   /*Setting TEST_OPUS_NOFUZZ tells the tool not to send garbage data
448     into the decoders. This is helpful because garbage data
449     may cause the decoders to clip, which angers CLANG IOC.*/
450   test_decoder_code0(getenv("TEST_OPUS_NOFUZZ")!=NULL);
451#ifndef DISABLE_FLOAT_API
452   test_soft_clip();
453#endif
454
455   return 0;
456}
457