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