Makes variable framesize less aggressive at lower rates
[opus.git] / src / opus_demo.c
1 /* Copyright (c) 2007-2008 CSIRO
2    Copyright (c) 2007-2009 Xiph.Org Foundation
3    Written by Jean-Marc Valin */
4 /*
5    Redistribution and use in source and binary forms, with or without
6    modification, are permitted provided that the following conditions
7    are met:
8
9    - Redistributions of source code must retain the above copyright
10    notice, this list of conditions and the following disclaimer.
11
12    - Redistributions in binary form must reproduce the above copyright
13    notice, this list of conditions and the following disclaimer in the
14    documentation and/or other materials provided with the distribution.
15
16    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <math.h>
36 #include <string.h>
37 #include "opus.h"
38 #include "debug.h"
39 #include "opus_types.h"
40 #include "opus_private.h"
41
42 #define MAX_PACKET 1500
43
44 void print_usage( char* argv[] )
45 {
46     fprintf(stderr, "Usage: %s [-e] <application> <sampling rate (Hz)> <channels (1/2)> "
47         "<bits per second>  [options] <input> <output>\n", argv[0]);
48     fprintf(stderr, "       %s -d <sampling rate (Hz)> <channels (1/2)> "
49         "[options] <input> <output>\n\n", argv[0]);
50     fprintf(stderr, "mode: voip | audio | restricted-lowdelay\n" );
51     fprintf(stderr, "options:\n" );
52     fprintf(stderr, "-e                   : only runs the encoder (output the bit-stream)\n" );
53     fprintf(stderr, "-d                   : only runs the decoder (reads the bit-stream as input)\n" );
54     fprintf(stderr, "-cbr                 : enable constant bitrate; default: variable bitrate\n" );
55     fprintf(stderr, "-cvbr                : enable constrained variable bitrate; default: unconstrained\n" );
56     fprintf(stderr, "-variable-duration   : enable frames of variable duration (experts only); default: disabled\n" );
57     fprintf(stderr, "-bandwidth <NB|MB|WB|SWB|FB> : audio bandwidth (from narrowband to fullband); default: sampling rate\n" );
58     fprintf(stderr, "-framesize <2.5|5|10|20|40|60> : frame size in ms; default: 20 \n" );
59     fprintf(stderr, "-max_payload <bytes> : maximum payload size in bytes, default: 1024\n" );
60     fprintf(stderr, "-complexity <comp>   : complexity, 0 (lowest) ... 10 (highest); default: 10\n" );
61     fprintf(stderr, "-inbandfec           : enable SILK inband FEC\n" );
62     fprintf(stderr, "-forcemono           : force mono encoding, even for stereo input\n" );
63     fprintf(stderr, "-dtx                 : enable SILK DTX\n" );
64     fprintf(stderr, "-loss <perc>         : simulate packet loss, in percent (0-100); default: 0\n" );
65 }
66
67 static void int_to_char(opus_uint32 i, unsigned char ch[4])
68 {
69     ch[0] = i>>24;
70     ch[1] = (i>>16)&0xFF;
71     ch[2] = (i>>8)&0xFF;
72     ch[3] = i&0xFF;
73 }
74
75 static opus_uint32 char_to_int(unsigned char ch[4])
76 {
77     return ((opus_uint32)ch[0]<<24) | ((opus_uint32)ch[1]<<16)
78          | ((opus_uint32)ch[2]<< 8) |  (opus_uint32)ch[3];
79 }
80
81 static void check_decoder_option(int encode_only, const char *opt)
82 {
83    if (encode_only)
84    {
85       fprintf(stderr, "option %s is only for decoding\n", opt);
86       exit(EXIT_FAILURE);
87    }
88 }
89
90 static void check_encoder_option(int decode_only, const char *opt)
91 {
92    if (decode_only)
93    {
94       fprintf(stderr, "option %s is only for encoding\n", opt);
95       exit(EXIT_FAILURE);
96    }
97 }
98
99 static const int silk8_test[][4] = {
100       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 1},
101       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 1},
102       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960,   1},
103       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480,   1},
104       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 2},
105       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 2},
106       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960,   2},
107       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480,   2}
108 };
109
110 static const int silk12_test[][4] = {
111       {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 1},
112       {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 1},
113       {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960,   1},
114       {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480,   1},
115       {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 2},
116       {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 2},
117       {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960,   2},
118       {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480,   2}
119 };
120
121 static const int silk16_test[][4] = {
122       {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 1},
123       {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 1},
124       {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960,   1},
125       {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480,   1},
126       {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 2},
127       {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 2},
128       {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960,   2},
129       {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480,   2}
130 };
131
132 static const int hybrid24_test[][4] = {
133       {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1},
134       {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1},
135       {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2},
136       {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2}
137 };
138
139 static const int hybrid48_test[][4] = {
140       {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 1},
141       {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 1},
142       {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2},
143       {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2}
144 };
145
146 static const int celt_test[][4] = {
147       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      960, 1},
148       {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1},
149       {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      960, 1},
150       {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    960, 1},
151
152       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      480, 1},
153       {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1},
154       {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      480, 1},
155       {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    480, 1},
156
157       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      240, 1},
158       {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 240, 1},
159       {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      240, 1},
160       {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    240, 1},
161
162       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      120, 1},
163       {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 120, 1},
164       {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      120, 1},
165       {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    120, 1},
166
167       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      960, 2},
168       {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2},
169       {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      960, 2},
170       {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    960, 2},
171
172       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      480, 2},
173       {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2},
174       {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      480, 2},
175       {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    480, 2},
176
177       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      240, 2},
178       {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 240, 2},
179       {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      240, 2},
180       {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    240, 2},
181
182       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      120, 2},
183       {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 120, 2},
184       {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      120, 2},
185       {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    120, 2},
186
187 };
188
189 static const int celt_hq_test[][4] = {
190       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      960, 2},
191       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      480, 2},
192       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      240, 2},
193       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      120, 2},
194 };
195
196 int main(int argc, char *argv[])
197 {
198     int err;
199     char *inFile, *outFile;
200     FILE *fin, *fout;
201     OpusEncoder *enc=NULL;
202     OpusDecoder *dec=NULL;
203     int args;
204     int len[2];
205     int frame_size, channels;
206     opus_int32 bitrate_bps=0;
207     unsigned char *data[2];
208     unsigned char *fbytes;
209     opus_int32 sampling_rate;
210     int use_vbr;
211     int max_payload_bytes;
212     int complexity;
213     int use_inbandfec;
214     int use_dtx;
215     int forcechannels;
216     int cvbr = 0;
217     int packet_loss_perc;
218     opus_int32 count=0, count_act=0;
219     int k;
220     opus_int32 skip=0;
221     int stop=0;
222     short *in, *out;
223     int application=OPUS_APPLICATION_AUDIO;
224     double bits=0.0, bits_max=0.0, bits_act=0.0, bits2=0.0, nrg;
225     double tot_samples=0;
226     opus_uint64 tot_in, tot_out;
227     int bandwidth=-1;
228     const char *bandwidth_string;
229     int lost = 0, lost_prev = 1;
230     int toggle = 0;
231     opus_uint32 enc_final_range[2];
232     opus_uint32 dec_final_range;
233     int encode_only=0, decode_only=0;
234     int max_frame_size = 960*6;
235     int curr_read=0;
236     int sweep_bps = 0;
237     int random_framesize=0, newsize=0, delayed_celt=0;
238     int sweep_max=0, sweep_min=0;
239     int random_fec=0;
240     const int (*mode_list)[4]=NULL;
241     int nb_modes_in_list=0;
242     int curr_mode=0;
243     int curr_mode_count=0;
244     int mode_switch_time = 48000;
245     int nb_encoded;
246     int remaining=0;
247     int variable_duration=0;
248
249     if (argc < 5 )
250     {
251        print_usage( argv );
252        return EXIT_FAILURE;
253     }
254
255     tot_in=tot_out=0;
256     fprintf(stderr, "%s\n", opus_get_version_string());
257
258     args = 1;
259     if (strcmp(argv[args], "-e")==0)
260     {
261         encode_only = 1;
262         args++;
263     } else if (strcmp(argv[args], "-d")==0)
264     {
265         decode_only = 1;
266         args++;
267     }
268     if (!decode_only && argc < 7 )
269     {
270        print_usage( argv );
271        return EXIT_FAILURE;
272     }
273
274     if (!decode_only)
275     {
276        if (strcmp(argv[args], "voip")==0)
277           application = OPUS_APPLICATION_VOIP;
278        else if (strcmp(argv[args], "restricted-lowdelay")==0)
279           application = OPUS_APPLICATION_RESTRICTED_LOWDELAY;
280        else if (strcmp(argv[args], "audio")!=0) {
281           fprintf(stderr, "unknown application: %s\n", argv[args]);
282           print_usage(argv);
283           return EXIT_FAILURE;
284        }
285        args++;
286     }
287     sampling_rate = (opus_int32)atol(argv[args]);
288     args++;
289     channels = atoi(argv[args]);
290     args++;
291     if (!decode_only)
292     {
293        bitrate_bps = (opus_int32)atol(argv[args]);
294        args++;
295     }
296
297     if (sampling_rate != 8000 && sampling_rate != 12000
298      && sampling_rate != 16000 && sampling_rate != 24000
299      && sampling_rate != 48000)
300     {
301         fprintf(stderr, "Supported sampling rates are 8000, 12000, "
302                 "16000, 24000 and 48000.\n");
303         return EXIT_FAILURE;
304     }
305     frame_size = sampling_rate/50;
306
307     /* defaults: */
308     use_vbr = 1;
309     bandwidth = OPUS_AUTO;
310     max_payload_bytes = MAX_PACKET;
311     complexity = 10;
312     use_inbandfec = 0;
313     forcechannels = OPUS_AUTO;
314     use_dtx = 0;
315     packet_loss_perc = 0;
316     max_frame_size = 960*6;
317     curr_read=0;
318
319     while( args < argc - 2 ) {
320         /* process command line options */
321         if( strcmp( argv[ args ], "-cbr" ) == 0 ) {
322             check_encoder_option(decode_only, "-cbr");
323             use_vbr = 0;
324             args++;
325         } else if( strcmp( argv[ args ], "-bandwidth" ) == 0 ) {
326             check_encoder_option(decode_only, "-bandwidth");
327             if (strcmp(argv[ args + 1 ], "NB")==0)
328                 bandwidth = OPUS_BANDWIDTH_NARROWBAND;
329             else if (strcmp(argv[ args + 1 ], "MB")==0)
330                 bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
331             else if (strcmp(argv[ args + 1 ], "WB")==0)
332                 bandwidth = OPUS_BANDWIDTH_WIDEBAND;
333             else if (strcmp(argv[ args + 1 ], "SWB")==0)
334                 bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
335             else if (strcmp(argv[ args + 1 ], "FB")==0)
336                 bandwidth = OPUS_BANDWIDTH_FULLBAND;
337             else {
338                 fprintf(stderr, "Unknown bandwidth %s. "
339                                 "Supported are NB, MB, WB, SWB, FB.\n",
340                                 argv[ args + 1 ]);
341                 return EXIT_FAILURE;
342             }
343             args += 2;
344         } else if( strcmp( argv[ args ], "-framesize" ) == 0 ) {
345             check_encoder_option(decode_only, "-framesize");
346             if (strcmp(argv[ args + 1 ], "2.5")==0)
347                 frame_size = sampling_rate/400;
348             else if (strcmp(argv[ args + 1 ], "5")==0)
349                 frame_size = sampling_rate/200;
350             else if (strcmp(argv[ args + 1 ], "10")==0)
351                 frame_size = sampling_rate/100;
352             else if (strcmp(argv[ args + 1 ], "20")==0)
353                 frame_size = sampling_rate/50;
354             else if (strcmp(argv[ args + 1 ], "40")==0)
355                 frame_size = sampling_rate/25;
356             else if (strcmp(argv[ args + 1 ], "60")==0)
357                 frame_size = 3*sampling_rate/50;
358             else {
359                 fprintf(stderr, "Unsupported frame size: %s ms. "
360                                 "Supported are 2.5, 5, 10, 20, 40, 60.\n",
361                                 argv[ args + 1 ]);
362                 return EXIT_FAILURE;
363             }
364             args += 2;
365         } else if( strcmp( argv[ args ], "-max_payload" ) == 0 ) {
366             check_encoder_option(decode_only, "-max_payload");
367             max_payload_bytes = atoi( argv[ args + 1 ] );
368             args += 2;
369         } else if( strcmp( argv[ args ], "-complexity" ) == 0 ) {
370             check_encoder_option(decode_only, "-complexity");
371             complexity = atoi( argv[ args + 1 ] );
372             args += 2;
373         } else if( strcmp( argv[ args ], "-inbandfec" ) == 0 ) {
374             use_inbandfec = 1;
375             args++;
376         } else if( strcmp( argv[ args ], "-forcemono" ) == 0 ) {
377             check_encoder_option(decode_only, "-forcemono");
378             forcechannels = 1;
379             args++;
380         } else if( strcmp( argv[ args ], "-cvbr" ) == 0 ) {
381             check_encoder_option(decode_only, "-cvbr");
382             cvbr = 1;
383             args++;
384         } else if( strcmp( argv[ args ], "-variable-duration" ) == 0 ) {
385             check_encoder_option(decode_only, "-variable-duration");
386             variable_duration = 1;
387             args++;
388         } else if( strcmp( argv[ args ], "-dtx") == 0 ) {
389             check_encoder_option(decode_only, "-dtx");
390             use_dtx = 1;
391             args++;
392         } else if( strcmp( argv[ args ], "-loss" ) == 0 ) {
393             check_decoder_option(encode_only, "-loss");
394             packet_loss_perc = atoi( argv[ args + 1 ] );
395             args += 2;
396         } else if( strcmp( argv[ args ], "-sweep" ) == 0 ) {
397             check_encoder_option(decode_only, "-sweep");
398             sweep_bps = atoi( argv[ args + 1 ] );
399             args += 2;
400         } else if( strcmp( argv[ args ], "-random_framesize" ) == 0 ) {
401             check_encoder_option(decode_only, "-random_framesize");
402             random_framesize = 1;
403             args++;
404         } else if( strcmp( argv[ args ], "-sweep_max" ) == 0 ) {
405             check_encoder_option(decode_only, "-sweep_max");
406             sweep_max = atoi( argv[ args + 1 ] );
407             args += 2;
408         } else if( strcmp( argv[ args ], "-random_fec" ) == 0 ) {
409             check_encoder_option(decode_only, "-random_fec");
410             random_fec = 1;
411             args++;
412         } else if( strcmp( argv[ args ], "-silk8k_test" ) == 0 ) {
413             check_encoder_option(decode_only, "-silk8k_test");
414             mode_list = silk8_test;
415             nb_modes_in_list = 8;
416             args++;
417         } else if( strcmp( argv[ args ], "-silk12k_test" ) == 0 ) {
418             check_encoder_option(decode_only, "-silk12k_test");
419             mode_list = silk12_test;
420             nb_modes_in_list = 8;
421             args++;
422         } else if( strcmp( argv[ args ], "-silk16k_test" ) == 0 ) {
423             check_encoder_option(decode_only, "-silk16k_test");
424             mode_list = silk16_test;
425             nb_modes_in_list = 8;
426             args++;
427         } else if( strcmp( argv[ args ], "-hybrid24k_test" ) == 0 ) {
428             check_encoder_option(decode_only, "-hybrid24k_test");
429             mode_list = hybrid24_test;
430             nb_modes_in_list = 4;
431             args++;
432         } else if( strcmp( argv[ args ], "-hybrid48k_test" ) == 0 ) {
433             check_encoder_option(decode_only, "-hybrid48k_test");
434             mode_list = hybrid48_test;
435             nb_modes_in_list = 4;
436             args++;
437         } else if( strcmp( argv[ args ], "-celt_test" ) == 0 ) {
438             check_encoder_option(decode_only, "-celt_test");
439             mode_list = celt_test;
440             nb_modes_in_list = 32;
441             args++;
442         } else if( strcmp( argv[ args ], "-celt_hq_test" ) == 0 ) {
443             check_encoder_option(decode_only, "-celt_hq_test");
444             mode_list = celt_hq_test;
445             nb_modes_in_list = 4;
446             args++;
447         } else {
448             printf( "Error: unrecognized setting: %s\n\n", argv[ args ] );
449             print_usage( argv );
450             return EXIT_FAILURE;
451         }
452     }
453
454     if (sweep_max)
455        sweep_min = bitrate_bps;
456
457     if (max_payload_bytes < 0 || max_payload_bytes > MAX_PACKET)
458     {
459         fprintf (stderr, "max_payload_bytes must be between 0 and %d\n",
460                           MAX_PACKET);
461         return EXIT_FAILURE;
462     }
463
464     inFile = argv[argc-2];
465     fin = fopen(inFile, "rb");
466     if (!fin)
467     {
468         fprintf (stderr, "Could not open input file %s\n", argv[argc-2]);
469         return EXIT_FAILURE;
470     }
471     if (mode_list)
472     {
473        int size;
474        fseek(fin, 0, SEEK_END);
475        size = ftell(fin);
476        fprintf(stderr, "File size is %d bytes\n", size);
477        fseek(fin, 0, SEEK_SET);
478        mode_switch_time = size/sizeof(short)/channels/nb_modes_in_list;
479        fprintf(stderr, "Switching mode every %d samples\n", mode_switch_time);
480     }
481
482     outFile = argv[argc-1];
483     fout = fopen(outFile, "wb+");
484     if (!fout)
485     {
486         fprintf (stderr, "Could not open output file %s\n", argv[argc-1]);
487         fclose(fin);
488         return EXIT_FAILURE;
489     }
490
491     if (!decode_only)
492     {
493        enc = opus_encoder_create(sampling_rate, channels, application, &err);
494        if (err != OPUS_OK)
495        {
496           fprintf(stderr, "Cannot create encoder: %s\n", opus_strerror(err));
497           fclose(fin);
498           fclose(fout);
499           return EXIT_FAILURE;
500        }
501        opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
502        opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bandwidth));
503        opus_encoder_ctl(enc, OPUS_SET_VBR(use_vbr));
504        opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(cvbr));
505        opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity));
506        opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(use_inbandfec));
507        opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(forcechannels));
508        opus_encoder_ctl(enc, OPUS_SET_DTX(use_dtx));
509        opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packet_loss_perc));
510
511        opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&skip));
512        opus_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(16));
513        opus_encoder_ctl(enc, OPUS_SET_EXPERT_VARIABLE_DURATION(variable_duration));
514     }
515     if (!encode_only)
516     {
517        dec = opus_decoder_create(sampling_rate, channels, &err);
518        if (err != OPUS_OK)
519        {
520           fprintf(stderr, "Cannot create decoder: %s\n", opus_strerror(err));
521           fclose(fin);
522           fclose(fout);
523           return EXIT_FAILURE;
524        }
525     }
526
527
528     switch(bandwidth)
529     {
530     case OPUS_BANDWIDTH_NARROWBAND:
531          bandwidth_string = "narrowband";
532          break;
533     case OPUS_BANDWIDTH_MEDIUMBAND:
534          bandwidth_string = "mediumband";
535          break;
536     case OPUS_BANDWIDTH_WIDEBAND:
537          bandwidth_string = "wideband";
538          break;
539     case OPUS_BANDWIDTH_SUPERWIDEBAND:
540          bandwidth_string = "superwideband";
541          break;
542     case OPUS_BANDWIDTH_FULLBAND:
543          bandwidth_string = "fullband";
544          break;
545     case OPUS_AUTO:
546          bandwidth_string = "auto";
547          break;
548     default:
549          bandwidth_string = "unknown";
550          break;
551     }
552
553     if (decode_only)
554        fprintf(stderr, "Decoding with %ld Hz output (%d channels)\n",
555                        (long)sampling_rate, channels);
556     else
557        fprintf(stderr, "Encoding %ld Hz input at %.3f kb/s "
558                        "in %s mode with %d-sample frames.\n",
559                        (long)sampling_rate, bitrate_bps*0.001,
560                        bandwidth_string, frame_size);
561
562     in = (short*)malloc(max_frame_size*channels*sizeof(short));
563     out = (short*)malloc(max_frame_size*channels*sizeof(short));
564     fbytes = (unsigned char*)malloc(max_frame_size*channels*sizeof(short));
565     data[0] = (unsigned char*)calloc(max_payload_bytes,sizeof(char));
566     if ( use_inbandfec ) {
567         data[1] = (unsigned char*)calloc(max_payload_bytes,sizeof(char));
568     }
569     while (!stop)
570     {
571         if (delayed_celt)
572         {
573             frame_size = newsize;
574             delayed_celt = 0;
575         } else if (random_framesize && rand()%20==0)
576         {
577             newsize = rand()%6;
578             switch(newsize)
579             {
580             case 0: newsize=sampling_rate/400; break;
581             case 1: newsize=sampling_rate/200; break;
582             case 2: newsize=sampling_rate/100; break;
583             case 3: newsize=sampling_rate/50; break;
584             case 4: newsize=sampling_rate/25; break;
585             case 5: newsize=3*sampling_rate/50; break;
586             }
587             while (newsize < sampling_rate/25 && bitrate_bps-fabs(sweep_bps) <= 3*12*sampling_rate/newsize)
588                newsize*=2;
589             if (newsize < sampling_rate/100 && frame_size >= sampling_rate/100)
590             {
591                 opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
592                 delayed_celt=1;
593             } else {
594                 frame_size = newsize;
595             }
596         }
597         if (random_fec && rand()%30==0)
598         {
599            opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(rand()%4==0));
600         }
601         if (decode_only)
602         {
603             unsigned char ch[4];
604             err = fread(ch, 1, 4, fin);
605             if (feof(fin))
606                 break;
607             len[toggle] = char_to_int(ch);
608             if (len[toggle]>max_payload_bytes || len[toggle]<0)
609             {
610                 fprintf(stderr, "Invalid payload length: %d\n",len[toggle]);
611                 break;
612             }
613             err = fread(ch, 1, 4, fin);
614             enc_final_range[toggle] = char_to_int(ch);
615             err = fread(data[toggle], 1, len[toggle], fin);
616             if (err<len[toggle])
617             {
618                 fprintf(stderr, "Ran out of input, "
619                                 "expecting %d bytes got %d\n",
620                                 len[toggle],err);
621                 break;
622             }
623         } else {
624             int i;
625             if (mode_list!=NULL)
626             {
627                 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(mode_list[curr_mode][1]));
628                 opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(mode_list[curr_mode][0]));
629                 opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(mode_list[curr_mode][3]));
630                 frame_size = mode_list[curr_mode][2];
631             }
632             err = fread(fbytes, sizeof(short)*channels, frame_size-remaining, fin);
633             curr_read = err;
634             tot_in += curr_read;
635             for(i=0;i<curr_read*channels;i++)
636             {
637                 opus_int32 s;
638                 s=fbytes[2*i+1]<<8|fbytes[2*i];
639                 s=((s&0xFFFF)^0x8000)-0x8000;
640                 in[i+remaining*channels]=s;
641             }
642             if (curr_read+remaining < frame_size)
643             {
644                 for (i=(curr_read+remaining)*channels;i<frame_size*channels;i++)
645                    in[i] = 0;
646                 if (encode_only || decode_only)
647                    stop = 1;
648             }
649             len[toggle] = opus_encode(enc, in, frame_size, data[toggle], max_payload_bytes);
650             nb_encoded = opus_packet_get_samples_per_frame(data[toggle], sampling_rate)*opus_packet_get_nb_frames(data[toggle], len[toggle]);
651             remaining = frame_size-nb_encoded;
652             for(i=0;i<remaining*channels;i++)
653                in[i] = in[nb_encoded*channels+i];
654             if (sweep_bps!=0)
655             {
656                bitrate_bps += sweep_bps;
657                if (sweep_max)
658                {
659                   if (bitrate_bps > sweep_max)
660                      sweep_bps = -sweep_bps;
661                   else if (bitrate_bps < sweep_min)
662                      sweep_bps = -sweep_bps;
663                }
664                /* safety */
665                if (bitrate_bps<1000)
666                   bitrate_bps = 1000;
667                opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
668             }
669             opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range[toggle]));
670             if (len[toggle] < 0)
671             {
672                 fprintf (stderr, "opus_encode() returned %d\n", len[toggle]);
673                 fclose(fin);
674                 fclose(fout);
675                 return EXIT_FAILURE;
676             }
677             curr_mode_count += frame_size;
678             if (curr_mode_count > mode_switch_time && curr_mode < nb_modes_in_list-1)
679             {
680                curr_mode++;
681                curr_mode_count = 0;
682             }
683         }
684
685         if (encode_only)
686         {
687             unsigned char int_field[4];
688             int_to_char(len[toggle], int_field);
689             if (fwrite(int_field, 1, 4, fout) != 4) {
690                fprintf(stderr, "Error writing.\n");
691                return EXIT_FAILURE;
692             }
693             int_to_char(enc_final_range[toggle], int_field);
694             if (fwrite(int_field, 1, 4, fout) != 4) {
695                fprintf(stderr, "Error writing.\n");
696                return EXIT_FAILURE;
697             }
698             if (fwrite(data[toggle], 1, len[toggle], fout) != (unsigned)len[toggle]) {
699                fprintf(stderr, "Error writing.\n");
700                return EXIT_FAILURE;
701             }
702             tot_samples += nb_encoded;
703         } else {
704             int output_samples;
705             lost = len[toggle]==0 || (packet_loss_perc>0 && rand()%100 < packet_loss_perc);
706             if (lost)
707                opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));
708             else
709                output_samples = max_frame_size;
710             if( count >= use_inbandfec ) {
711                 /* delay by one packet when using in-band FEC */
712                 if( use_inbandfec  ) {
713                     if( lost_prev ) {
714                         /* attempt to decode with in-band FEC from next packet */
715                         output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 1);
716                     } else {
717                         /* regular decode */
718                         output_samples = opus_decode(dec, data[1-toggle], len[1-toggle], out, output_samples, 0);
719                     }
720                 } else {
721                     output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 0);
722                 }
723                 if (output_samples>0)
724                 {
725                     if (!decode_only && tot_out + output_samples > tot_in)
726                     {
727                        stop=1;
728                        output_samples  = tot_in-tot_out;
729                     }
730                     if (output_samples>skip) {
731                        int i;
732                        for(i=0;i<(output_samples-skip)*channels;i++)
733                        {
734                           short s;
735                           s=out[i+(skip*channels)];
736                           fbytes[2*i]=s&0xFF;
737                           fbytes[2*i+1]=(s>>8)&0xFF;
738                        }
739                        if (fwrite(fbytes, sizeof(short)*channels, output_samples-skip, fout) != (unsigned)(output_samples-skip)){
740                           fprintf(stderr, "Error writing.\n");
741                           return EXIT_FAILURE;
742                        }
743                        tot_out += output_samples-skip;
744                     }
745                     if (output_samples<skip) skip -= output_samples;
746                     else skip = 0;
747                 } else {
748                    fprintf(stderr, "error decoding frame: %s\n",
749                                    opus_strerror(output_samples));
750                 }
751                 tot_samples += output_samples;
752             }
753         }
754
755         if (!encode_only)
756            opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range));
757         /* compare final range encoder rng values of encoder and decoder */
758         if( enc_final_range[toggle^use_inbandfec]!=0  && !encode_only
759          && !lost && !lost_prev
760          && dec_final_range != enc_final_range[toggle^use_inbandfec] ) {
761             fprintf (stderr, "Error: Range coder state mismatch "
762                              "between encoder and decoder "
763                              "in frame %ld: 0x%8lx vs 0x%8lx\n",
764                          (long)count,
765                          (unsigned long)enc_final_range[toggle^use_inbandfec],
766                          (unsigned long)dec_final_range);
767             fclose(fin);
768             fclose(fout);
769             return EXIT_FAILURE;
770         }
771
772         lost_prev = lost;
773
774         /* count bits */
775         bits += len[toggle]*8;
776         bits_max = ( len[toggle]*8 > bits_max ) ? len[toggle]*8 : bits_max;
777         if( count >= use_inbandfec ) {
778             nrg = 0.0;
779             if (!decode_only)
780             {
781                 for ( k = 0; k < frame_size * channels; k++ ) {
782                     nrg += in[ k ] * (double)in[ k ];
783                 }
784             }
785             if ( ( nrg / ( frame_size * channels ) ) > 1e5 ) {
786                 bits_act += len[toggle]*8;
787                 count_act++;
788             }
789             /* Variance */
790             bits2 += len[toggle]*len[toggle]*64;
791         }
792         count++;
793         toggle = (toggle + use_inbandfec) & 1;
794     }
795     fprintf (stderr, "average bitrate:             %7.3f kb/s\n",
796                      1e-3*bits*sampling_rate/tot_samples);
797     fprintf (stderr, "maximum bitrate:             %7.3f kb/s\n",
798                      1e-3*bits_max*sampling_rate/frame_size);
799     if (!decode_only)
800        fprintf (stderr, "active bitrate:              %7.3f kb/s\n",
801                1e-3*bits_act*sampling_rate/(frame_size*(double)count_act));
802     fprintf (stderr, "bitrate standard deviation:  %7.3f kb/s\n",
803             1e-3*sqrt(bits2/count - bits*bits/(count*(double)count))*sampling_rate/frame_size);
804     /* Close any files to which intermediate results were stored */
805     SILK_DEBUG_STORE_CLOSE_FILES
806     silk_TimerSave("opus_timing.txt");
807     opus_encoder_destroy(enc);
808     opus_decoder_destroy(dec);
809     free(data[0]);
810     if (use_inbandfec)
811         free(data[1]);
812     fclose(fin);
813     fclose(fout);
814     free(in);
815     free(out);
816     free(fbytes);
817     return EXIT_SUCCESS;
818 }