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