Last updates for draft -11
[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 FOUNDATION OR
20    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, "-bandwidth <NB|MB|WB|SWB|FB> : audio bandwidth (from narrowband to fullband); default: sampling rate\n" );
57     fprintf(stderr, "-framesize <2.5|5|10|20|40|60> : frame size in ms; default: 20 \n" );
58     fprintf(stderr, "-max_payload <bytes> : maximum payload size in bytes, default: 1024\n" );
59     fprintf(stderr, "-complexity <comp>   : complexity, 0 (lowest) ... 10 (highest); default: 10\n" );
60     fprintf(stderr, "-inbandfec           : enable SILK inband FEC\n" );
61     fprintf(stderr, "-forcemono           : force mono encoding, even for stereo input\n" );
62     fprintf(stderr, "-dtx                 : enable SILK DTX\n" );
63     fprintf(stderr, "-loss <perc>         : simulate packet loss, in percent (0-100); default: 0\n" );
64 }
65
66 #ifdef _WIN32
67 #   define STR_CASEINSENSITIVE_COMPARE(x, y) _stricmp(x, y)
68 #else
69 #   include <strings.h>
70 #   define STR_CASEINSENSITIVE_COMPARE(x, y) strcasecmp(x, y)
71 #endif
72
73 static void int_to_char(opus_uint32 i, unsigned char ch[4])
74 {
75     ch[0] = i>>24;
76     ch[1] = (i>>16)&0xFF;
77     ch[2] = (i>>8)&0xFF;
78     ch[3] = i&0xFF;
79 }
80
81 static opus_uint32 char_to_int(unsigned char ch[4])
82 {
83     return ((opus_uint32)ch[0]<<24) | ((opus_uint32)ch[1]<<16)
84          | ((opus_uint32)ch[2]<< 8) |  (opus_uint32)ch[3];
85 }
86
87 static void check_decoder_option(int encode_only, const char *opt)
88 {
89    if (encode_only)
90    {
91       fprintf(stderr, "option %s is only for decoding\n", opt);
92       exit(EXIT_FAILURE);
93    }
94 }
95
96 static void check_encoder_option(int decode_only, const char *opt)
97 {
98    if (decode_only)
99    {
100       fprintf(stderr, "option %s is only for encoding\n", opt);
101       exit(EXIT_FAILURE);
102    }
103 }
104
105 int silk8_test[][4] = {
106       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 1},
107       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 1},
108       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960,   1},
109       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480,   1},
110       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 2},
111       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 2},
112       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960,   2},
113       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480,   2}
114 };
115
116 int silk12_test[][4] = {
117       {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 1},
118       {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 1},
119       {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960,   1},
120       {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480,   1},
121       {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 2},
122       {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 2},
123       {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960,   2},
124       {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480,   2}
125 };
126
127 int silk16_test[][4] = {
128       {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 1},
129       {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 1},
130       {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960,   1},
131       {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480,   1},
132       {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 2},
133       {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 2},
134       {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960,   2},
135       {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480,   2}
136 };
137
138 int hybrid24_test[][4] = {
139       {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1},
140       {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1},
141       {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2},
142       {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2}
143 };
144
145 int hybrid48_test[][4] = {
146       {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 1},
147       {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 1},
148       {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2},
149       {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2}
150 };
151
152 int celt_test[][4] = {
153       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      960, 1},
154       {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1},
155       {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      960, 1},
156       {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    960, 1},
157
158       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      480, 1},
159       {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1},
160       {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      480, 1},
161       {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    480, 1},
162
163       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      240, 1},
164       {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 240, 1},
165       {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      240, 1},
166       {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    240, 1},
167
168       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      120, 1},
169       {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 120, 1},
170       {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      120, 1},
171       {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    120, 1},
172
173       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      960, 2},
174       {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2},
175       {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      960, 2},
176       {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    960, 2},
177
178       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      480, 2},
179       {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2},
180       {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      480, 2},
181       {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    480, 2},
182
183       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      240, 2},
184       {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 240, 2},
185       {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      240, 2},
186       {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    240, 2},
187
188       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      120, 2},
189       {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 120, 2},
190       {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      120, 2},
191       {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    120, 2},
192
193 };
194
195 int celt_hq_test[][4] = {
196       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      960, 2},
197       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      480, 2},
198       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      240, 2},
199       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      120, 2},
200 };
201
202 int main(int argc, char *argv[])
203 {
204     int err;
205     char *inFile, *outFile;
206     FILE *fin, *fout;
207     OpusEncoder *enc=NULL;
208     OpusDecoder *dec=NULL;
209     int args;
210     int len[2];
211     int frame_size, channels;
212     opus_int32 bitrate_bps=0;
213     unsigned char *data[2];
214     opus_int32 sampling_rate;
215     int use_vbr;
216     int max_payload_bytes;
217     int complexity;
218     int use_inbandfec;
219     int use_dtx;
220     int forcechannels;
221     int cvbr = 0;
222     int packet_loss_perc;
223     opus_int32 count=0, count_act=0;
224     int k;
225     int skip=0;
226     int stop=0;
227     short *in, *out;
228     int application=OPUS_APPLICATION_AUDIO;
229     double bits=0.0, bits_max=0.0, bits_act=0.0, bits2=0.0, nrg;
230     int bandwidth=-1;
231     const char *bandwidth_string;
232     int lost = 0, lost_prev = 1;
233     int toggle = 0;
234     opus_uint32 enc_final_range[2];
235     opus_uint32 dec_final_range;
236     int encode_only=0, decode_only=0;
237     int max_frame_size = 960*6;
238     int curr_read=0;
239     int sweep_bps = 0;
240     int random_framesize=0, newsize=0, delayed_celt=0;
241     int sweep_max=0, sweep_min=0;
242     int random_fec=0;
243     int (*mode_list)[4]=NULL;
244     int nb_modes_in_list=0;
245     int curr_mode=0;
246     int curr_mode_count=0;
247     int mode_switch_time = 48000;
248
249     if (argc < 5 )
250     {
251        print_usage( argv );
252        return EXIT_FAILURE;
253     }
254
255     fprintf(stderr, "%s\n", opus_get_version_string());
256
257     args = 1;
258     if (strcmp(argv[args], "-e")==0)
259     {
260         encode_only = 1;
261         args++;
262     } else if (strcmp(argv[args], "-d")==0)
263     {
264         decode_only = 1;
265         args++;
266     }
267     if (!decode_only && argc < 7 )
268     {
269        print_usage( argv );
270        return EXIT_FAILURE;
271     }
272
273     if (!decode_only)
274     {
275        if (strcmp(argv[args], "voip")==0)
276           application = OPUS_APPLICATION_VOIP;
277        else if (strcmp(argv[args], "restricted-lowdelay")==0)
278           application = OPUS_APPLICATION_RESTRICTED_LOWDELAY;
279        else if (strcmp(argv[args], "audio")!=0) {
280           fprintf(stderr, "unknown application: %s\n", argv[args]);
281           print_usage(argv);
282           return EXIT_FAILURE;
283        }
284        args++;
285     }
286     sampling_rate = (opus_int32)atol(argv[args]);
287     args++;
288     channels = atoi(argv[args]);
289     args++;
290     if (!decode_only)
291     {
292        bitrate_bps = (opus_int32)atol(argv[args]);
293        args++;
294     }
295
296     if (sampling_rate != 8000 && sampling_rate != 12000
297      && sampling_rate != 16000 && sampling_rate != 24000
298      && sampling_rate != 48000)
299     {
300         fprintf(stderr, "Supported sampling rates are 8000, 12000, "
301                 "16000, 24000 and 48000.\n");
302         return EXIT_FAILURE;
303     }
304     frame_size = sampling_rate/50;
305
306     /* defaults: */
307     use_vbr = 1;
308     bandwidth = OPUS_AUTO;
309     max_payload_bytes = MAX_PACKET;
310     complexity = 10;
311     use_inbandfec = 0;
312     forcechannels = OPUS_AUTO;
313     use_dtx = 0;
314     packet_loss_perc = 0;
315     max_frame_size = 960*6;
316     curr_read=0;
317
318     while( args < argc - 2 ) {
319         /* process command line options */
320         if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-cbr" ) == 0 ) {
321             check_encoder_option(decode_only, "-cbr");
322             use_vbr = 0;
323             args++;
324         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-bandwidth" ) == 0 ) {
325             check_encoder_option(decode_only, "-bandwidth");
326             if (strcmp(argv[ args + 1 ], "NB")==0)
327                 bandwidth = OPUS_BANDWIDTH_NARROWBAND;
328             else if (strcmp(argv[ args + 1 ], "MB")==0)
329                 bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
330             else if (strcmp(argv[ args + 1 ], "WB")==0)
331                 bandwidth = OPUS_BANDWIDTH_WIDEBAND;
332             else if (strcmp(argv[ args + 1 ], "SWB")==0)
333                 bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
334             else if (strcmp(argv[ args + 1 ], "FB")==0)
335                 bandwidth = OPUS_BANDWIDTH_FULLBAND;
336             else {
337                 fprintf(stderr, "Unknown bandwidth %s. "
338                                 "Supported are NB, MB, WB, SWB, FB.\n",
339                                 argv[ args + 1 ]);
340                 return EXIT_FAILURE;
341             }
342             args += 2;
343         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-framesize" ) == 0 ) {
344             check_encoder_option(decode_only, "-framesize");
345             if (strcmp(argv[ args + 1 ], "2.5")==0)
346                 frame_size = sampling_rate/400;
347             else if (strcmp(argv[ args + 1 ], "5")==0)
348                 frame_size = sampling_rate/200;
349             else if (strcmp(argv[ args + 1 ], "10")==0)
350                 frame_size = sampling_rate/100;
351             else if (strcmp(argv[ args + 1 ], "20")==0)
352                 frame_size = sampling_rate/50;
353             else if (strcmp(argv[ args + 1 ], "40")==0)
354                 frame_size = sampling_rate/25;
355             else if (strcmp(argv[ args + 1 ], "60")==0)
356                 frame_size = 3*sampling_rate/50;
357             else {
358                 fprintf(stderr, "Unsupported frame size: %s ms. "
359                                 "Supported are 2.5, 5, 10, 20, 40, 60.\n",
360                                 argv[ args + 1 ]);
361                 return EXIT_FAILURE;
362             }
363             args += 2;
364         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-max_payload" ) == 0 ) {
365             check_encoder_option(decode_only, "-max_payload");
366             max_payload_bytes = atoi( argv[ args + 1 ] );
367             args += 2;
368         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-complexity" ) == 0 ) {
369             check_encoder_option(decode_only, "-complexity");
370             complexity = atoi( argv[ args + 1 ] );
371             args += 2;
372         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-inbandfec" ) == 0 ) {
373             use_inbandfec = 1;
374             args++;
375         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-forcemono" ) == 0 ) {
376             check_encoder_option(decode_only, "-forcemono");
377             forcechannels = 1;
378             args++;
379         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-cvbr" ) == 0 ) {
380             check_encoder_option(decode_only, "-cvbr");
381             cvbr = 1;
382             args++;
383         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-dtx") == 0 ) {
384             check_encoder_option(decode_only, "-dtx");
385             use_dtx = 1;
386             args++;
387         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-loss" ) == 0 ) {
388             check_decoder_option(encode_only, "-loss");
389             packet_loss_perc = atoi( argv[ args + 1 ] );
390             args += 2;
391         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-sweep" ) == 0 ) {
392             check_encoder_option(decode_only, "-sweep");
393             sweep_bps = atoi( argv[ args + 1 ] );
394             args += 2;
395         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-random_framesize" ) == 0 ) {
396             check_encoder_option(decode_only, "-random_framesize");
397             random_framesize = 1;
398             args++;
399         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-sweep_max" ) == 0 ) {
400             check_encoder_option(decode_only, "-sweep_max");
401             sweep_max = atoi( argv[ args + 1 ] );
402             args += 2;
403         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-random_fec" ) == 0 ) {
404             check_encoder_option(decode_only, "-random_fec");
405             random_fec = 1;
406             args++;
407         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-silk8k_test" ) == 0 ) {
408             check_encoder_option(decode_only, "-silk8k_test");
409             mode_list = silk8_test;
410             nb_modes_in_list = 8;
411             args++;
412         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-silk12k_test" ) == 0 ) {
413             check_encoder_option(decode_only, "-silk12k_test");
414             mode_list = silk12_test;
415             nb_modes_in_list = 8;
416             args++;
417         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-silk16k_test" ) == 0 ) {
418             check_encoder_option(decode_only, "-silk16k_test");
419             mode_list = silk16_test;
420             nb_modes_in_list = 8;
421             args++;
422         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-hybrid24k_test" ) == 0 ) {
423             check_encoder_option(decode_only, "-hybrid24k_test");
424             mode_list = hybrid24_test;
425             nb_modes_in_list = 4;
426             args++;
427         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-hybrid48k_test" ) == 0 ) {
428             check_encoder_option(decode_only, "-hybrid48k_test");
429             mode_list = hybrid48_test;
430             nb_modes_in_list = 4;
431             args++;
432         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-celt_test" ) == 0 ) {
433             check_encoder_option(decode_only, "-celt_test");
434             mode_list = celt_test;
435             nb_modes_in_list = 32;
436             args++;
437         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-celt_hq_test" ) == 0 ) {
438             check_encoder_option(decode_only, "-celt_hq_test");
439             mode_list = celt_hq_test;
440             nb_modes_in_list = 4;
441             args++;
442         } else {
443             printf( "Error: unrecognized setting: %s\n\n", argv[ args ] );
444             print_usage( argv );
445             return EXIT_FAILURE;
446         }
447     }
448
449     if (sweep_max)
450        sweep_min = bitrate_bps;
451
452     if (max_payload_bytes < 0 || max_payload_bytes > MAX_PACKET)
453     {
454         fprintf (stderr, "max_payload_bytes must be between 0 and %d\n",
455                           MAX_PACKET);
456         return EXIT_FAILURE;
457     }
458
459     inFile = argv[argc-2];
460     fin = fopen(inFile, "rb");
461     if (!fin)
462     {
463         fprintf (stderr, "Could not open input file %s\n", argv[argc-2]);
464         return EXIT_FAILURE;
465     }
466     if (mode_list)
467     {
468        int size;
469        fseek(fin, 0, SEEK_END);
470        size = ftell(fin);
471        fprintf(stderr, "File size is %d bytes\n", size);
472        fseek(fin, 0, SEEK_SET);
473        mode_switch_time = size/sizeof(short)/channels/nb_modes_in_list;
474        fprintf(stderr, "Switching mode every %d samples\n", mode_switch_time);
475     }
476
477     outFile = argv[argc-1];
478     fout = fopen(outFile, "wb+");
479     if (!fout)
480     {
481         fprintf (stderr, "Could not open output file %s\n", argv[argc-1]);
482         fclose(fin);
483         return EXIT_FAILURE;
484     }
485
486     if (!decode_only)
487     {
488        enc = opus_encoder_create(sampling_rate, channels, application, &err);
489        if (err != OPUS_OK)
490        {
491           fprintf(stderr, "Cannot create encoder: %s\n", opus_strerror(err));
492           fclose(fin);
493           fclose(fout);
494           return EXIT_FAILURE;
495        }
496        opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
497        opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bandwidth));
498        opus_encoder_ctl(enc, OPUS_SET_VBR(use_vbr));
499        opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(cvbr));
500        opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity));
501        opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(use_inbandfec));
502        opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(forcechannels));
503        opus_encoder_ctl(enc, OPUS_SET_DTX(use_dtx));
504        opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packet_loss_perc));
505
506        opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&skip));
507     }
508     if (!encode_only)
509     {
510        dec = opus_decoder_create(sampling_rate, channels, &err);
511        if (err != OPUS_OK)
512        {
513           fprintf(stderr, "Cannot create decoder: %s\n", opus_strerror(err));
514           fclose(fin);
515           fclose(fout);
516           return EXIT_FAILURE;
517        }
518     }
519
520
521     switch(bandwidth)
522     {
523     case OPUS_BANDWIDTH_NARROWBAND:
524          bandwidth_string = "narrowband";
525          break;
526     case OPUS_BANDWIDTH_MEDIUMBAND:
527          bandwidth_string = "mediumband";
528          break;
529     case OPUS_BANDWIDTH_WIDEBAND:
530          bandwidth_string = "wideband";
531          break;
532     case OPUS_BANDWIDTH_SUPERWIDEBAND:
533          bandwidth_string = "superwideband";
534          break;
535     case OPUS_BANDWIDTH_FULLBAND:
536          bandwidth_string = "fullband";
537          break;
538     case OPUS_AUTO:
539          bandwidth_string = "auto";
540          break;
541     default:
542          bandwidth_string = "unknown";
543          break;
544     }
545
546     if (decode_only)
547        fprintf(stderr, "Decoding with %ld Hz output (%d channels)\n",
548                        (long)sampling_rate, channels);
549     else
550        fprintf(stderr, "Encoding %ld Hz input at %.3f kb/s "
551                        "in %s mode with %d-sample frames.\n",
552                        (long)sampling_rate, bitrate_bps*0.001,
553                        bandwidth_string, frame_size);
554
555     in = (short*)malloc(max_frame_size*channels*sizeof(short));
556     out = (short*)malloc(max_frame_size*channels*sizeof(short));
557     data[0] = (unsigned char*)calloc(max_payload_bytes,sizeof(char));
558     if ( use_inbandfec ) {
559         data[1] = (unsigned char*)calloc(max_payload_bytes,sizeof(char));
560     }
561     while (!stop)
562     {
563         if (delayed_celt)
564         {
565             frame_size = newsize;
566             delayed_celt = 0;
567         } else if (random_framesize && rand()%20==0)
568         {
569             newsize = rand()%6;
570             switch(newsize)
571             {
572             case 0: newsize=sampling_rate/400; break;
573             case 1: newsize=sampling_rate/200; break;
574             case 2: newsize=sampling_rate/100; break;
575             case 3: newsize=sampling_rate/50; break;
576             case 4: newsize=sampling_rate/25; break;
577             case 5: newsize=3*sampling_rate/50; break;
578             }
579             while (newsize < sampling_rate/25 && bitrate_bps-fabs(sweep_bps) <= 3*12*sampling_rate/newsize)
580                newsize*=2;
581             if (newsize < sampling_rate/100 && frame_size >= sampling_rate/100)
582             {
583                 opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
584                 delayed_celt=1;
585             } else {
586                 frame_size = newsize;
587             }
588         }
589         if (random_fec && rand()%30==0)
590         {
591            opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(rand()%4==0));
592         }
593         if (decode_only)
594         {
595             unsigned char ch[4];
596             err = fread(ch, 1, 4, fin);
597             if (feof(fin))
598                 break;
599             len[toggle] = char_to_int(ch);
600             if (len[toggle]>max_payload_bytes || len[toggle]<0)
601             {
602                 fprintf(stderr, "Invalid payload length: %d\n",len[toggle]);
603                 break;
604             }
605             err = fread(ch, 1, 4, fin);
606             enc_final_range[toggle] = char_to_int(ch);
607             err = fread(data[toggle], 1, len[toggle], fin);
608             if (err<len[toggle])
609             {
610                 fprintf(stderr, "Ran out of input, "
611                                 "expecting %d bytes got %d\n",
612                                 len[toggle],err);
613                 break;
614             }
615         } else {
616             if (mode_list!=NULL)
617             {
618                 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(mode_list[curr_mode][1]));
619                 opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(mode_list[curr_mode][0]));
620                 opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(mode_list[curr_mode][3]));
621                 frame_size = mode_list[curr_mode][2];
622             }
623             err = fread(in, sizeof(short)*channels, frame_size, fin);
624             curr_read = err;
625             if (curr_read < frame_size)
626             {
627                 int i;
628                 for (i=curr_read*channels;i<frame_size*channels;i++)
629                    in[i] = 0;
630                 stop = 1;
631             }
632             len[toggle] = opus_encode(enc, in, frame_size, data[toggle], max_payload_bytes);
633             if (sweep_bps!=0)
634             {
635                bitrate_bps += sweep_bps;
636                if (sweep_max)
637                {
638                   if (bitrate_bps > sweep_max)
639                      sweep_bps = -sweep_bps;
640                   else if (bitrate_bps < sweep_min)
641                      sweep_bps = -sweep_bps;
642                }
643                /* safety */
644                if (bitrate_bps<1000)
645                   bitrate_bps = 1000;
646                opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
647             }
648             opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range[toggle]));
649             if (len[toggle] < 0)
650             {
651                 fprintf (stderr, "opus_encode() returned %d\n", len[toggle]);
652                 fclose(fin);
653                 fclose(fout);
654                 return EXIT_FAILURE;
655             }
656             curr_mode_count += frame_size;
657             if (curr_mode_count > mode_switch_time && curr_mode < nb_modes_in_list-1)
658             {
659                curr_mode++;
660                curr_mode_count = 0;
661             }
662         }
663
664         if (encode_only)
665         {
666             unsigned char int_field[4];
667             int_to_char(len[toggle], int_field);
668             fwrite(int_field, 1, 4, fout);
669             int_to_char(enc_final_range[toggle], int_field);
670             fwrite(int_field, 1, 4, fout);
671             fwrite(data[toggle], 1, len[toggle], fout);
672         } else {
673             int output_samples;
674             lost = len[toggle]==0 || (packet_loss_perc>0 && rand()%100 < packet_loss_perc);
675             if( count >= use_inbandfec ) {
676                 /* delay by one packet when using in-band FEC */
677                 if( use_inbandfec  ) {
678                     if( lost_prev ) {
679                         /* attempt to decode with in-band FEC from next packet */
680                         output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, max_frame_size, 1);
681                     } else {
682                         /* regular decode */
683                         output_samples = opus_decode(dec, data[1-toggle], len[1-toggle], out, max_frame_size, 0);
684                     }
685                 } else {
686                     output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, max_frame_size, 0);
687                 }
688                 if (output_samples>0)
689                 {
690                     fwrite(out+skip*channels, sizeof(short)*channels, output_samples-skip, fout);
691                     skip = 0;
692                 } else {
693                    fprintf(stderr, "error decoding frame: %s\n",
694                                    opus_strerror(output_samples));
695                 }
696             }
697         }
698
699         if (!encode_only)
700            opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range));
701         /* compare final range encoder rng values of encoder and decoder */
702         if( enc_final_range[toggle^use_inbandfec]!=0  && !encode_only
703          && !lost && !lost_prev
704          && dec_final_range != enc_final_range[toggle^use_inbandfec] ) {
705             fprintf (stderr, "Error: Range coder state mismatch "
706                              "between encoder and decoder "
707                              "in frame %ld: 0x%8lx vs 0x%8lx\n",
708                          (long)count,
709                          (unsigned long)enc_final_range[toggle^use_inbandfec],
710                          (unsigned long)dec_final_range);
711             fclose(fin);
712             fclose(fout);
713             return EXIT_FAILURE;
714         }
715
716         lost_prev = lost;
717
718         /* count bits */
719         bits += len[toggle]*8;
720         bits_max = ( len[toggle]*8 > bits_max ) ? len[toggle]*8 : bits_max;
721         if( count >= use_inbandfec ) {
722             nrg = 0.0;
723             if (!decode_only)
724             {
725                 for ( k = 0; k < frame_size * channels; k++ ) {
726                     nrg += in[ k ] * (double)in[ k ];
727                 }
728             }
729             if ( ( nrg / ( frame_size * channels ) ) > 1e5 ) {
730                 bits_act += len[toggle]*8;
731                 count_act++;
732             }
733             /* Variance */
734             bits2 += len[toggle]*len[toggle]*64;
735         }
736         count++;
737         toggle = (toggle + use_inbandfec) & 1;
738     }
739     fprintf (stderr, "average bitrate:             %7.3f kb/s\n",
740                      1e-3*bits*sampling_rate/(frame_size*(double)count));
741     fprintf (stderr, "maximum bitrate:             %7.3f bkp/s\n",
742                      1e-3*bits_max*sampling_rate/frame_size);
743     if (!decode_only)
744        fprintf (stderr, "active bitrate:              %7.3f kb/s\n",
745                1e-3*bits_act*sampling_rate/(frame_size*(double)count_act));
746     fprintf (stderr, "bitrate standard deviation:  %7.3f kb/s\n",
747             1e-3*sqrt(bits2/count - bits*bits/(count*(double)count))*sampling_rate/frame_size);
748     /* Close any files to which intermediate results were stored */
749     SILK_DEBUG_STORE_CLOSE_FILES
750     silk_TimerSave("opus_timing.txt");
751     opus_encoder_destroy(enc);
752     opus_decoder_destroy(dec);
753     free(data[0]);
754     if (use_inbandfec)
755         free(data[1]);
756     fclose(fin);
757     fclose(fout);
758     free(in);
759     free(out);
760     return EXIT_SUCCESS;
761 }