Newly introduced check_encoder_option failed unconditionally instead of only when...
[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
41 #define MAX_PACKET 1500
42
43 void print_usage( char* argv[] )
44 {
45     fprintf(stderr, "Usage: %s [-e] <application> <sampling rate (Hz)> <channels (1/2)> "
46         "<bits per second>  [options] <input> <output>\n", argv[0]);
47     fprintf(stderr, "       %s -d <sampling rate (Hz)> <channels (1/2)> "
48         "[options] <input> <output>\n\n", argv[0]);
49     fprintf(stderr, "mode: voip | audio | restricted-lowdelay\n" );
50     fprintf(stderr, "options:\n" );
51     fprintf(stderr, "-e                   : only runs the encoder (output the bit-stream)\n" );
52     fprintf(stderr, "-d                   : only runs the decoder (reads the bit-stream as input)\n" );
53     fprintf(stderr, "-cbr                 : enable constant bitrate; default: variable bitrate\n" );
54     fprintf(stderr, "-cvbr                : enable constrained variable bitrate; default: unconstrained\n" );
55     fprintf(stderr, "-bandwidth <NB|MB|WB|SWB|FB> : audio bandwidth (from narrowband to fullband); default: sampling rate\n" );
56     fprintf(stderr, "-framesize <2.5|5|10|20|40|60> : frame size in ms; default: 20 \n" );
57     fprintf(stderr, "-max_payload <bytes> : maximum payload size in bytes, default: 1024\n" );
58     fprintf(stderr, "-complexity <comp>   : complexity, 0 (lowest) ... 10 (highest); default: 10\n" );
59     fprintf(stderr, "-inbandfec           : enable SILK inband FEC\n" );
60     fprintf(stderr, "-forcemono           : force mono encoding, even for stereo input\n" );
61     fprintf(stderr, "-dtx                 : enable SILK DTX\n" );
62     fprintf(stderr, "-loss <perc>         : simulate packet loss, in percent (0-100); default: 0\n" );
63 }
64
65 #ifdef _WIN32
66 #   define STR_CASEINSENSITIVE_COMPARE(x, y) _stricmp(x, y)
67 #else
68 #   include <strings.h>
69 #   define STR_CASEINSENSITIVE_COMPARE(x, y) strcasecmp(x, y)
70 #endif
71
72 static void int_to_char(opus_uint32 i, unsigned char ch[4])
73 {
74     ch[0] = i>>24;
75     ch[1] = (i>>16)&0xFF;
76     ch[2] = (i>>8)&0xFF;
77     ch[3] = i&0xFF;
78 }
79
80 static opus_uint32 char_to_int(unsigned char ch[4])
81 {
82     return ((opus_uint32)ch[0]<<24) | ((opus_uint32)ch[1]<<16)
83          | ((opus_uint32)ch[2]<< 8) |  (opus_uint32)ch[3];
84 }
85
86 static void check_decoder_option(int encode_only, const char *opt)
87 {
88    if (encode_only)
89    {
90       fprintf(stderr, "option %s is only for decoding\n", opt);
91       exit(EXIT_FAILURE);
92    }
93 }
94
95 static void check_encoder_option(int decode_only, const char *opt)
96 {
97    if (decode_only)
98    {
99       fprintf(stderr, "option %s is only for encoding\n", opt);
100       exit(EXIT_FAILURE);
101    }
102 }
103
104 int main(int argc, char *argv[])
105 {
106     int err;
107     char *inFile, *outFile;
108     FILE *fin, *fout;
109     OpusEncoder *enc=NULL;
110     OpusDecoder *dec=NULL;
111     int args;
112     int len[2];
113     int frame_size, channels;
114     opus_int32 bitrate_bps=0;
115     unsigned char *data[2];
116     opus_int32 sampling_rate;
117     int use_vbr;
118     int max_payload_bytes;
119     int complexity;
120     int use_inbandfec;
121     int use_dtx;
122     int forcechannels;
123     int cvbr = 0;
124     int packet_loss_perc;
125     opus_int32 count=0, count_act=0;
126     int k;
127     int skip=0;
128     int stop=0;
129     short *in, *out;
130     int application=OPUS_APPLICATION_AUDIO;
131     double bits=0.0, bits_max=0.0, bits_act=0.0, bits2=0.0, nrg;
132     int bandwidth=-1;
133     const char *bandwidth_string;
134     int lost = 0, lost_prev = 1;
135     int toggle = 0;
136     opus_uint32 enc_final_range[2];
137     opus_uint32 dec_final_range;
138     int encode_only=0, decode_only=0;
139     int max_frame_size = 960*6;
140     int curr_read=0;
141     int sweep_bps = 0;
142
143     if (argc < 5 )
144     {
145        print_usage( argv );
146        return EXIT_FAILURE;
147     }
148
149     fprintf(stderr, "%s\n", opus_get_version_string());
150
151     args = 1;
152     if (strcmp(argv[args], "-e")==0)
153     {
154         encode_only = 1;
155         args++;
156     } else if (strcmp(argv[args], "-d")==0)
157     {
158         decode_only = 1;
159         args++;
160     }
161     if (!decode_only && argc < 7 )
162     {
163        print_usage( argv );
164        return EXIT_FAILURE;
165     }
166
167     if (!decode_only)
168     {
169        if (strcmp(argv[args], "voip")==0)
170           application = OPUS_APPLICATION_VOIP;
171        else if (strcmp(argv[args], "restricted-lowdelay")==0)
172           application = OPUS_APPLICATION_RESTRICTED_LOWDELAY;
173        else if (strcmp(argv[args], "audio")!=0) {
174           fprintf(stderr, "unknown application: %s\n", argv[args]);
175           print_usage(argv);
176           return EXIT_FAILURE;
177        }
178        args++;
179     }
180     sampling_rate = (opus_int32)atol(argv[args]);
181     args++;
182     channels = atoi(argv[args]);
183     args++;
184     if (!decode_only)
185     {
186        bitrate_bps = (opus_int32)atol(argv[args]);
187        args++;
188     }
189
190     if (sampling_rate != 8000 && sampling_rate != 12000
191      && sampling_rate != 16000 && sampling_rate != 24000
192      && sampling_rate != 48000)
193     {
194         fprintf(stderr, "Supported sampling rates are 8000, 12000, "
195                 "16000, 24000 and 48000.\n");
196         return EXIT_FAILURE;
197     }
198     frame_size = sampling_rate/50;
199
200     /* defaults: */
201     use_vbr = 1;
202     bandwidth = OPUS_AUTO;
203     max_payload_bytes = MAX_PACKET;
204     complexity = 10;
205     use_inbandfec = 0;
206     forcechannels = OPUS_AUTO;
207     use_dtx = 0;
208     packet_loss_perc = 0;
209     max_frame_size = 960*6;
210     curr_read=0;
211
212     while( args < argc - 2 ) {
213         /* process command line options */
214         if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-cbr" ) == 0 ) {
215             check_encoder_option(decode_only, "-cbr");
216             use_vbr = 0;
217             args++;
218         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-bandwidth" ) == 0 ) {
219             check_encoder_option(decode_only, "-bandwidth");
220             if (strcmp(argv[ args + 1 ], "NB")==0)
221                 bandwidth = OPUS_BANDWIDTH_NARROWBAND;
222             else if (strcmp(argv[ args + 1 ], "MB")==0)
223                 bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
224             else if (strcmp(argv[ args + 1 ], "WB")==0)
225                 bandwidth = OPUS_BANDWIDTH_WIDEBAND;
226             else if (strcmp(argv[ args + 1 ], "SWB")==0)
227                 bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
228             else if (strcmp(argv[ args + 1 ], "FB")==0)
229                 bandwidth = OPUS_BANDWIDTH_FULLBAND;
230             else {
231                 fprintf(stderr, "Unknown bandwidth %s. "
232                                 "Supported are NB, MB, WB, SWB, FB.\n",
233                                 argv[ args + 1 ]);
234                 return EXIT_FAILURE;
235             }
236             args += 2;
237         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-framesize" ) == 0 ) {
238             check_encoder_option(decode_only, "-framesize");
239             if (strcmp(argv[ args + 1 ], "2.5")==0)
240                 frame_size = sampling_rate/400;
241             else if (strcmp(argv[ args + 1 ], "5")==0)
242                 frame_size = sampling_rate/200;
243             else if (strcmp(argv[ args + 1 ], "10")==0)
244                 frame_size = sampling_rate/100;
245             else if (strcmp(argv[ args + 1 ], "20")==0)
246                 frame_size = sampling_rate/50;
247             else if (strcmp(argv[ args + 1 ], "40")==0)
248                 frame_size = sampling_rate/25;
249             else if (strcmp(argv[ args + 1 ], "60")==0)
250                 frame_size = 3*sampling_rate/50;
251             else {
252                 fprintf(stderr, "Unsupported frame size: %s ms. "
253                                 "Supported are 2.5, 5, 10, 20, 40, 60.\n",
254                                 argv[ args + 1 ]);
255                 return EXIT_FAILURE;
256             }
257             args += 2;
258         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-max_payload" ) == 0 ) {
259             check_encoder_option(decode_only, "-max_payload");
260             max_payload_bytes = atoi( argv[ args + 1 ] );
261             args += 2;
262         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-complexity" ) == 0 ) {
263             check_encoder_option(decode_only, "-complexity");
264             complexity = atoi( argv[ args + 1 ] );
265             args += 2;
266         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-inbandfec" ) == 0 ) {
267             use_inbandfec = 1;
268             args++;
269         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-forcemono" ) == 0 ) {
270             check_encoder_option(decode_only, "-forcemono");
271             forcechannels = 1;
272             args++;
273         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-cvbr" ) == 0 ) {
274             check_encoder_option(decode_only, "-cvbr");
275             cvbr = 1;
276             args++;
277         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-dtx") == 0 ) {
278             check_encoder_option(decode_only, "-dtx");
279             use_dtx = 1;
280             args++;
281         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-loss" ) == 0 ) {
282             check_decoder_option(encode_only, "-loss");
283             packet_loss_perc = atoi( argv[ args + 1 ] );
284             args += 2;
285         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-sweep" ) == 0 ) {
286             check_encoder_option(decode_only, "-sweep");
287             sweep_bps = atoi( argv[ args + 1 ] );
288             args += 2;
289         } else {
290             printf( "Error: unrecognized setting: %s\n\n", argv[ args ] );
291             print_usage( argv );
292             return EXIT_FAILURE;
293         }
294     }
295
296     if (max_payload_bytes < 0 || max_payload_bytes > MAX_PACKET)
297     {
298         fprintf (stderr, "max_payload_bytes must be between 0 and %d\n",
299                           MAX_PACKET);
300         return EXIT_FAILURE;
301     }
302
303     inFile = argv[argc-2];
304     fin = fopen(inFile, "rb");
305     if (!fin)
306     {
307         fprintf (stderr, "Could not open input file %s\n", argv[argc-2]);
308         return EXIT_FAILURE;
309     }
310     outFile = argv[argc-1];
311     fout = fopen(outFile, "wb+");
312     if (!fout)
313     {
314         fprintf (stderr, "Could not open output file %s\n", argv[argc-1]);
315         return EXIT_FAILURE;
316     }
317
318     if (!decode_only)
319     {
320        enc = opus_encoder_create(sampling_rate, channels, application, &err);
321        if (err != OPUS_OK)
322        {
323           fprintf(stderr, "Cannot create encoder: %s\n", opus_strerror(err));
324           return EXIT_FAILURE;
325        }
326        opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
327        opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bandwidth));
328        opus_encoder_ctl(enc, OPUS_SET_VBR(use_vbr));
329        opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(cvbr));
330        opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity));
331        opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(use_inbandfec));
332        opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(forcechannels));
333        opus_encoder_ctl(enc, OPUS_SET_DTX(use_dtx));
334        opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packet_loss_perc));
335
336        opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&skip));
337     }
338     if (!encode_only)
339     {
340        dec = opus_decoder_create(sampling_rate, channels, &err);
341        if (err != OPUS_OK)
342        {
343           fprintf(stderr, "Cannot create decoder: %s\n", opus_strerror(err));
344           return EXIT_FAILURE;
345        }
346     }
347
348
349     switch(bandwidth)
350     {
351     case OPUS_BANDWIDTH_NARROWBAND:
352          bandwidth_string = "narrowband";
353          break;
354     case OPUS_BANDWIDTH_MEDIUMBAND:
355          bandwidth_string = "mediumband";
356          break;
357     case OPUS_BANDWIDTH_WIDEBAND:
358          bandwidth_string = "wideband";
359          break;
360     case OPUS_BANDWIDTH_SUPERWIDEBAND:
361          bandwidth_string = "superwideband";
362          break;
363     case OPUS_BANDWIDTH_FULLBAND:
364          bandwidth_string = "fullband";
365          break;
366     case OPUS_AUTO:
367          bandwidth_string = "auto";
368          break;
369     default:
370          bandwidth_string = "unknown";
371          break;
372     }
373
374     if (decode_only)
375        fprintf(stderr, "Decoding with %ld Hz output (%d channels)\n",
376                        (long)sampling_rate, channels);
377     else
378        fprintf(stderr, "Encoding %ld Hz input at %.3f kb/s "
379                        "in %s mode with %d-sample frames.\n",
380                        (long)sampling_rate, bitrate_bps*0.001,
381                        bandwidth_string, frame_size);
382
383     in = (short*)malloc(frame_size*channels*sizeof(short));
384     out = (short*)malloc(max_frame_size*channels*sizeof(short));
385     data[0] = (unsigned char*)calloc(max_payload_bytes,sizeof(char));
386     if ( use_inbandfec ) {
387         data[1] = (unsigned char*)calloc(max_payload_bytes,sizeof(char));
388     }
389     while (!stop)
390     {
391         if (decode_only)
392         {
393             unsigned char ch[4];
394             err = fread(ch, 1, 4, fin);
395             if (feof(fin))
396                 break;
397             len[toggle] = char_to_int(ch);
398             if (len[toggle]>max_payload_bytes || len[toggle]<0)
399             {
400                 fprintf(stderr, "Invalid payload length: %d\n",len[toggle]);
401                 break;
402             }
403             err = fread(ch, 1, 4, fin);
404             enc_final_range[toggle] = char_to_int(ch);
405             err = fread(data[toggle], 1, len[toggle], fin);
406             if (err<len[toggle])
407             {
408                 fprintf(stderr, "Ran out of input, "
409                                 "expecting %d bytes got %d\n",
410                                 len[toggle],err);
411                 break;
412             }
413         } else {
414             err = fread(in, sizeof(short)*channels, frame_size, fin);
415             curr_read = err;
416             if (curr_read < frame_size)
417             {
418                 int i;
419                 for (i=curr_read*channels;i<frame_size*channels;i++)
420                    in[i] = 0;
421                 stop = 1;
422             }
423
424             len[toggle] = opus_encode(enc, in, frame_size, data[toggle], max_payload_bytes);
425             if (sweep_bps!=0)
426             {
427                bitrate_bps += sweep_bps;
428                /* safety */
429                if (bitrate_bps<1000)
430                   bitrate_bps = 1000;
431                opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
432             }
433             opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range[toggle]));
434             if (len[toggle] < 0)
435             {
436                 fprintf (stderr, "opus_encode() returned %d\n", len[toggle]);
437                 return EXIT_FAILURE;
438             }
439         }
440
441         if (encode_only)
442         {
443             unsigned char int_field[4];
444             int_to_char(len[toggle], int_field);
445             fwrite(int_field, 1, 4, fout);
446             int_to_char(enc_final_range[toggle], int_field);
447             fwrite(int_field, 1, 4, fout);
448             fwrite(data[toggle], 1, len[toggle], fout);
449         } else {
450             int output_samples;
451             lost = len[toggle]==0 || (packet_loss_perc>0 && rand()%100 < packet_loss_perc);
452             if( count >= use_inbandfec ) {
453                 /* delay by one packet when using in-band FEC */
454                 if( use_inbandfec  ) {
455                     if( lost_prev ) {
456                         /* attempt to decode with in-band FEC from next packet */
457                         output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, max_frame_size, 1);
458                     } else {
459                         /* regular decode */
460                         output_samples = opus_decode(dec, data[1-toggle], len[1-toggle], out, max_frame_size, 0);
461                     }
462                 } else {
463                     output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, max_frame_size, 0);
464                 }
465                 if (output_samples>0)
466                 {
467                     fwrite(out+skip*channels, sizeof(short)*channels, output_samples-skip, fout);
468                     skip = 0;
469                 } else {
470                    fprintf(stderr, "error decoding frame: %s\n",
471                                    opus_strerror(output_samples));
472                 }
473             }
474         }
475
476         if (!encode_only)
477            opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range));
478         /* compare final range encoder rng values of encoder and decoder */
479         if( enc_final_range[toggle^use_inbandfec]!=0  && !encode_only
480          && !lost && !lost_prev
481          && dec_final_range != enc_final_range[toggle^use_inbandfec] ) {
482             fprintf (stderr, "Error: Range coder state mismatch "
483                              "between encoder and decoder "
484                              "in frame %ld: 0x%8lx vs 0x%8lx\n",
485                          (long)count,
486                          (unsigned long)enc_final_range[toggle^use_inbandfec],
487                          (unsigned long)dec_final_range);
488             return EXIT_FAILURE;
489         }
490
491         lost_prev = lost;
492
493         /* count bits */
494         bits += len[toggle]*8;
495         bits_max = ( len[toggle]*8 > bits_max ) ? len[toggle]*8 : bits_max;
496         if( count >= use_inbandfec ) {
497             nrg = 0.0;
498             if (!decode_only)
499             {
500                 for ( k = 0; k < frame_size * channels; k++ ) {
501                     nrg += in[ k ] * (double)in[ k ];
502                 }
503             }
504             if ( ( nrg / ( frame_size * channels ) ) > 1e5 ) {
505                 bits_act += len[toggle]*8;
506                 count_act++;
507             }
508             /* Variance */
509             bits2 += len[toggle]*len[toggle]*64;
510         }
511         count++;
512         toggle = (toggle + use_inbandfec) & 1;
513     }
514     fprintf (stderr, "average bitrate:             %7.3f kb/s\n",
515                      1e-3*bits*sampling_rate/(frame_size*(double)count));
516     fprintf (stderr, "maximum bitrate:             %7.3f bkp/s\n",
517                      1e-3*bits_max*sampling_rate/frame_size);
518     if (!decode_only)
519        fprintf (stderr, "active bitrate:              %7.3f kb/s\n",
520                1e-3*bits_act*sampling_rate/(frame_size*(double)count_act));
521     fprintf (stderr, "bitrate standard deviation:  %7.3f kb/s\n",
522             1e-3*sqrt(bits2/count - bits*bits/(count*(double)count))*sampling_rate/frame_size);
523     /* Close any files to which intermediate results were stored */
524     SILK_DEBUG_STORE_CLOSE_FILES
525     silk_TimerSave("opus_timing.txt");
526     opus_encoder_destroy(enc);
527     opus_decoder_destroy(dec);
528     free(data[0]);
529     if (use_inbandfec)
530         free(data[1]);
531     fclose(fin);
532     fclose(fout);
533     free(in);
534     free(out);
535     return EXIT_SUCCESS;
536 }