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