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 #ifndef _WIN32
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
test_decoder_code0(int no_fuzz)51 int 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 opus_int32 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 #if !defined(OPUS_BUILD) && (OPUS_GNUC_PREREQ(4, 6) || (defined(__clang_major__) && __clang_major__ >= 3))
139 #pragma GCC diagnostic push
140 #pragma GCC diagnostic ignored "-Wnonnull"
141 #endif
142 out_samples = opus_decode(dec[t], packet, 0, 0, 0, fec);
143 #if !defined(OPUS_BUILD) && (OPUS_GNUC_PREREQ(4, 6) || (defined(__clang_major__) && __clang_major__ >= 3))
144 #pragma GCC diagnostic pop
145 #endif
146 if(out_samples>0)test_failed();
147 if(outbuf[0]!=32749)test_failed();
148
149 /*Invalid lengths*/
150 out_samples = opus_decode(dec[t], packet, -1, outbuf, MAX_FRAME_SAMP, fec);
151 if(out_samples>=0)test_failed();
152 out_samples = opus_decode(dec[t], packet, INT_MIN, outbuf, MAX_FRAME_SAMP, fec);
153 if(out_samples>=0)test_failed();
154 out_samples = opus_decode(dec[t], packet, -1, outbuf, -1, fec);
155 if(out_samples>=0)test_failed();
156
157 /*Crazy FEC values*/
158 out_samples = opus_decode(dec[t], packet, 1, outbuf, MAX_FRAME_SAMP, fec?-1:2);
159 if(out_samples>=0)test_failed();
160
161 /*Reset the decoder*/
162 if(opus_decoder_ctl(dec[t], OPUS_RESET_STATE)!=OPUS_OK)test_failed();
163 }
164 }
165 fprintf(stdout," dec[all] initial frame PLC OK.\n");
166
167 /*Count code 0 tests*/
168 for(i=0;i<64;i++)
169 {
170 opus_int32 dur;
171 int j,expected[5*2];
172 packet[0]=i<<2;
173 packet[1]=255;
174 packet[2]=255;
175 err=opus_packet_get_nb_channels(packet);
176 if(err!=(i&1)+1)test_failed();
177
178 for(t=0;t<5*2;t++){
179 expected[t]=opus_decoder_get_nb_samples(dec[t],packet,1);
180 if(expected[t]>2880)test_failed();
181 }
182
183 for(j=0;j<256;j++)
184 {
185 packet[1]=j;
186 for(t=0;t<5*2;t++)
187 {
188 out_samples = opus_decode(dec[t], packet, 3, outbuf, MAX_FRAME_SAMP, 0);
189 if(out_samples!=expected[t])test_failed();
190 if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
191 if(dur!=out_samples)test_failed();
192 opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
193 if(t==0)dec_final_range2=dec_final_range1;
194 else if(dec_final_range1!=dec_final_range2)test_failed();
195 }
196 }
197
198 for(t=0;t<5*2;t++){
199 int factor=48000/fsv[t>>1];
200 /* The PLC is run for 6 frames in order to get better PLC coverage. */
201 for(j=0;j<6;j++)
202 {
203 out_samples = opus_decode(dec[t], 0, 0, outbuf, expected[t], 0);
204 if(out_samples!=expected[t])test_failed();
205 if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
206 if(dur!=out_samples)test_failed();
207 }
208 /* Run the PLC once at 2.5ms, as a simulation of someone trying to
209 do small drift corrections. */
210 if(expected[t]!=120/factor)
211 {
212 out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, 0);
213 if(out_samples!=120/factor)test_failed();
214 if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
215 if(dur!=out_samples)test_failed();
216 }
217 out_samples = opus_decode(dec[t], packet, 2, outbuf, expected[t]-1, 0);
218 if(out_samples>0)test_failed();
219 }
220 }
221 fprintf(stdout," dec[all] all 2-byte prefix for length 3 and PLC, all modes (64) OK.\n");
222
223 if(no_fuzz)
224 {
225 fprintf(stdout," Skipping many tests which fuzz the decoder as requested.\n");
226 free(decbak);
227 for(t=0;t<5*2;t++)opus_decoder_destroy(dec[t]);
228 printf(" Decoders stopped.\n");
229
230 err=0;
231 for(i=0;i<8*2;i++)err|=outbuf_int[i]!=32749;
232 for(i=MAX_FRAME_SAMP*2;i<(MAX_FRAME_SAMP+8)*2;i++)err|=outbuf[i]!=32749;
233 if(err)test_failed();
234
235 free(outbuf_int);
236 free(packet);
237 return 0;
238 }
239
240 {
241 /*We only test a subset of the modes here simply because the longer
242 durations end up taking a long time.*/
243 static const int cmodes[4]={16,20,24,28};
244 static const opus_uint32 cres[4]={116290185,2172123586u,2172123586u,2172123586u};
245 static const opus_uint32 lres[3]={3285687739u,1481572662,694350475};
246 static const int lmodes[3]={0,4,8};
247 int mode=fast_rand()%4;
248
249 packet[0]=cmodes[mode]<<3;
250 dec_final_acc=0;
251 t=fast_rand()%10;
252
253 for(i=0;i<65536;i++)
254 {
255 int factor=48000/fsv[t>>1];
256 packet[1]=i>>8;
257 packet[2]=i&255;
258 packet[3]=255;
259 out_samples = opus_decode(dec[t], packet, 4, outbuf, MAX_FRAME_SAMP, 0);
260 if(out_samples!=120/factor)test_failed();
261 opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
262 dec_final_acc+=dec_final_range1;
263 }
264 if(dec_final_acc!=cres[mode])test_failed();
265 fprintf(stdout," dec[%3d] all 3-byte prefix for length 4, mode %2d OK.\n",t,cmodes[mode]);
266
267 mode=fast_rand()%3;
268 packet[0]=lmodes[mode]<<3;
269 dec_final_acc=0;
270 t=fast_rand()%10;
271 for(i=0;i<65536;i++)
272 {
273 int factor=48000/fsv[t>>1];
274 packet[1]=i>>8;
275 packet[2]=i&255;
276 packet[3]=255;
277 out_samples = opus_decode(dec[t], packet, 4, outbuf, MAX_FRAME_SAMP, 0);
278 if(out_samples!=480/factor)test_failed();
279 opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
280 dec_final_acc+=dec_final_range1;
281 }
282 if(dec_final_acc!=lres[mode])test_failed();
283 fprintf(stdout," dec[%3d] all 3-byte prefix for length 4, mode %2d OK.\n",t,lmodes[mode]);
284 }
285
286 skip=fast_rand()%7;
287 for(i=0;i<64;i++)
288 {
289 int j,expected[5*2];
290 packet[0]=i<<2;
291 for(t=0;t<5*2;t++)expected[t]=opus_decoder_get_nb_samples(dec[t],packet,1);
292 for(j=2+skip;j<1275;j+=4)
293 {
294 int jj;
295 for(jj=0;jj<j;jj++)packet[jj+1]=fast_rand()&255;
296 for(t=0;t<5*2;t++)
297 {
298 out_samples = opus_decode(dec[t], packet, j+1, outbuf, MAX_FRAME_SAMP, 0);
299 if(out_samples!=expected[t])test_failed();
300 opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
301 if(t==0)dec_final_range2=dec_final_range1;
302 else if(dec_final_range1!=dec_final_range2)test_failed();
303 }
304 }
305 }
306 fprintf(stdout," dec[all] random packets, all modes (64), every 8th size from from %d bytes to maximum OK.\n",2+skip);
307
308 debruijn2(64,modes);
309 plen=(fast_rand()%18+3)*8+skip+3;
310 for(i=0;i<4096;i++)
311 {
312 int j,expected[5*2];
313 packet[0]=modes[i]<<2;
314 for(t=0;t<5*2;t++)expected[t]=opus_decoder_get_nb_samples(dec[t],packet,plen);
315 for(j=0;j<plen;j++)packet[j+1]=(fast_rand()|fast_rand())&255;
316 memcpy(decbak,dec[0],decsize);
317 if(opus_decode(decbak, packet, plen+1, outbuf, expected[0], 1)!=expected[0])test_failed();
318 memcpy(decbak,dec[0],decsize);
319 if(opus_decode(decbak, 0, 0, outbuf, MAX_FRAME_SAMP, 1)<20)test_failed();
320 memcpy(decbak,dec[0],decsize);
321 if(opus_decode(decbak, 0, 0, outbuf, MAX_FRAME_SAMP, 0)<20)test_failed();
322 for(t=0;t<5*2;t++)
323 {
324 opus_int32 dur;
325 out_samples = opus_decode(dec[t], packet, plen+1, outbuf, MAX_FRAME_SAMP, 0);
326 if(out_samples!=expected[t])test_failed();
327 if(t==0)dec_final_range2=dec_final_range1;
328 else if(dec_final_range1!=dec_final_range2)test_failed();
329 if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
330 if(dur!=out_samples)test_failed();
331 }
332 }
333 fprintf(stdout," dec[all] random packets, all mode pairs (4096), %d bytes/frame OK.\n",plen+1);
334
335 plen=(fast_rand()%18+3)*8+skip+3;
336 t=rand()&3;
337 for(i=0;i<4096;i++)
338 {
339 int count,j,expected;
340 packet[0]=modes[i]<<2;
341 expected=opus_decoder_get_nb_samples(dec[t],packet,plen);
342 for(count=0;count<10;count++)
343 {
344 for(j=0;j<plen;j++)packet[j+1]=(fast_rand()|fast_rand())&255;
345 out_samples = opus_decode(dec[t], packet, plen+1, outbuf, MAX_FRAME_SAMP, 0);
346 if(out_samples!=expected)test_failed();
347 }
348 }
349 fprintf(stdout," dec[%3d] random packets, all mode pairs (4096)*10, %d bytes/frame OK.\n",t,plen+1);
350
351 {
352 int tmodes[1]={25<<2};
353 opus_uint32 tseeds[1]={140441};
354 int tlen[1]={157};
355 opus_int32 tret[1]={480};
356 t=fast_rand()&1;
357 for(i=0;i<1;i++)
358 {
359 int j;
360 packet[0]=tmodes[i];
361 Rw=Rz=tseeds[i];
362 for(j=1;j<tlen[i];j++)packet[j]=fast_rand()&255;
363 out_samples=opus_decode(dec[t], packet, tlen[i], outbuf, MAX_FRAME_SAMP, 0);
364 if(out_samples!=tret[i])test_failed();
365 }
366 fprintf(stdout," dec[%3d] pre-selected random packets OK.\n",t);
367 }
368
369 free(decbak);
370 for(t=0;t<5*2;t++)opus_decoder_destroy(dec[t]);
371 printf(" Decoders stopped.\n");
372
373 err=0;
374 for(i=0;i<8*2;i++)err|=outbuf_int[i]!=32749;
375 for(i=MAX_FRAME_SAMP*2;i<(MAX_FRAME_SAMP+8)*2;i++)err|=outbuf[i]!=32749;
376 if(err)test_failed();
377
378 free(outbuf_int);
379 free(packet);
380 return 0;
381 }
382
383 #ifndef DISABLE_FLOAT_API
test_soft_clip(void)384 void test_soft_clip(void)
385 {
386 int i,j;
387 float x[1024];
388 float s[8] = {0, 0, 0, 0, 0, 0, 0, 0};
389 fprintf(stdout," Testing opus_pcm_soft_clip... ");
390 for(i=0;i<1024;i++)
391 {
392 for (j=0;j<1024;j++)
393 {
394 x[j]=(j&255)*(1/32.f)-4.f;
395 }
396 opus_pcm_soft_clip(&x[i],1024-i,1,s);
397 for (j=i;j<1024;j++)
398 {
399 if(x[j]>1.f)test_failed();
400 if(x[j]<-1.f)test_failed();
401 }
402 }
403 for(i=1;i<9;i++)
404 {
405 for (j=0;j<1024;j++)
406 {
407 x[j]=(j&255)*(1/32.f)-4.f;
408 }
409 opus_pcm_soft_clip(x,1024/i,i,s);
410 for (j=0;j<(1024/i)*i;j++)
411 {
412 if(x[j]>1.f)test_failed();
413 if(x[j]<-1.f)test_failed();
414 }
415 }
416 opus_pcm_soft_clip(x,0,1,s);
417 opus_pcm_soft_clip(x,1,0,s);
418 opus_pcm_soft_clip(x,1,1,0);
419 opus_pcm_soft_clip(x,1,-1,s);
420 opus_pcm_soft_clip(x,-1,1,s);
421 opus_pcm_soft_clip(0,1,1,s);
422 printf("OK.\n");
423 }
424 #endif
425
main(int _argc,char ** _argv)426 int main(int _argc, char **_argv)
427 {
428 const char * oversion;
429 const char * env_seed;
430 int env_used;
431
432 if(_argc>2)
433 {
434 fprintf(stderr,"Usage: %s [<seed>]\n",_argv[0]);
435 return 1;
436 }
437
438 env_used=0;
439 env_seed=getenv("SEED");
440 if(_argc>1)iseed=atoi(_argv[1]);
441 else if(env_seed)
442 {
443 iseed=atoi(env_seed);
444 env_used=1;
445 }
446 else iseed=(opus_uint32)time(NULL)^(((opus_uint32)getpid()&65535)<<16);
447 Rw=Rz=iseed;
448
449 oversion=opus_get_version_string();
450 if(!oversion)test_failed();
451 fprintf(stderr,"Testing %s decoder. Random seed: %u (%.4X)\n", oversion, iseed, fast_rand() % 65535);
452 if(env_used)fprintf(stderr," Random seed set from the environment (SEED=%s).\n", env_seed);
453
454 /*Setting TEST_OPUS_NOFUZZ tells the tool not to send garbage data
455 into the decoders. This is helpful because garbage data
456 may cause the decoders to clip, which angers CLANG IOC.*/
457 test_decoder_code0(getenv("TEST_OPUS_NOFUZZ")!=NULL);
458 #ifndef DISABLE_FLOAT_API
459 test_soft_clip();
460 #endif
461
462 return 0;
463 }
464