123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892 |
- /* Copyright (c) 2007-2008 CSIRO
- Copyright (c) 2007-2009 Xiph.Org Foundation
- Written by Jean-Marc Valin */
- /*
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <string.h>
- #include "opus.h"
- #include "debug.h"
- #include "opus_types.h"
- #include "opus_private.h"
- #include "opus_multistream.h"
- #define MAX_PACKET 1500
- void print_usage( char* argv[] )
- {
- fprintf(stderr, "Usage: %s [-e] <application> <sampling rate (Hz)> <channels (1/2)> "
- "<bits per second> [options] <input> <output>\n", argv[0]);
- fprintf(stderr, " %s -d <sampling rate (Hz)> <channels (1/2)> "
- "[options] <input> <output>\n\n", argv[0]);
- fprintf(stderr, "application: voip | audio | restricted-lowdelay\n" );
- fprintf(stderr, "options:\n" );
- fprintf(stderr, "-e : only runs the encoder (output the bit-stream)\n" );
- fprintf(stderr, "-d : only runs the decoder (reads the bit-stream as input)\n" );
- fprintf(stderr, "-cbr : enable constant bitrate; default: variable bitrate\n" );
- fprintf(stderr, "-cvbr : enable constrained variable bitrate; default: unconstrained\n" );
- fprintf(stderr, "-delayed-decision : use look-ahead for speech/music detection (experts only); default: disabled\n" );
- fprintf(stderr, "-bandwidth <NB|MB|WB|SWB|FB> : audio bandwidth (from narrowband to fullband); default: sampling rate\n" );
- fprintf(stderr, "-framesize <2.5|5|10|20|40|60|80|100|120> : frame size in ms; default: 20 \n" );
- fprintf(stderr, "-max_payload <bytes> : maximum payload size in bytes, default: 1024\n" );
- fprintf(stderr, "-complexity <comp> : complexity, 0 (lowest) ... 10 (highest); default: 10\n" );
- fprintf(stderr, "-inbandfec : enable SILK inband FEC\n" );
- fprintf(stderr, "-forcemono : force mono encoding, even for stereo input\n" );
- fprintf(stderr, "-dtx : enable SILK DTX\n" );
- fprintf(stderr, "-loss <perc> : simulate packet loss, in percent (0-100); default: 0\n" );
- }
- static void int_to_char(opus_uint32 i, unsigned char ch[4])
- {
- ch[0] = i>>24;
- ch[1] = (i>>16)&0xFF;
- ch[2] = (i>>8)&0xFF;
- ch[3] = i&0xFF;
- }
- static opus_uint32 char_to_int(unsigned char ch[4])
- {
- return ((opus_uint32)ch[0]<<24) | ((opus_uint32)ch[1]<<16)
- | ((opus_uint32)ch[2]<< 8) | (opus_uint32)ch[3];
- }
- #define check_encoder_option(decode_only, opt) do {if (decode_only) {fprintf(stderr, "option %s is only for encoding\n", opt); goto failure;}} while(0)
- static const int silk8_test[][4] = {
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 1},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 1},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 1},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 1},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 2},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 2},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 2},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 2}
- };
- static const int silk12_test[][4] = {
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 1},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 1},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960, 1},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480, 1},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 2},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 2},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960, 2},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480, 2}
- };
- static const int silk16_test[][4] = {
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 1},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 1},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 1},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 1},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 2},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 2},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 2},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 2}
- };
- static const int hybrid24_test[][4] = {
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2}
- };
- static const int hybrid48_test[][4] = {
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 1},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 1},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2},
- {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2}
- };
- static const int celt_test[][4] = {
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 1},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 1},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 1},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 1},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 1},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 1},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 240, 1},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 240, 1},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 240, 1},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 240, 1},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 120, 1},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 120, 1},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 120, 1},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 120, 1},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 2},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 2},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 2},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 2},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 240, 2},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 240, 2},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 240, 2},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 240, 2},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 120, 2},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 120, 2},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 120, 2},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 120, 2},
- };
- static const int celt_hq_test[][4] = {
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 240, 2},
- {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 120, 2},
- };
- #if 0 /* This is a hack that replaces the normal encoder/decoder with the multistream version */
- #define OpusEncoder OpusMSEncoder
- #define OpusDecoder OpusMSDecoder
- #define opus_encode opus_multistream_encode
- #define opus_decode opus_multistream_decode
- #define opus_encoder_ctl opus_multistream_encoder_ctl
- #define opus_decoder_ctl opus_multistream_decoder_ctl
- #define opus_encoder_create ms_opus_encoder_create
- #define opus_decoder_create ms_opus_decoder_create
- #define opus_encoder_destroy opus_multistream_encoder_destroy
- #define opus_decoder_destroy opus_multistream_decoder_destroy
- static OpusEncoder *ms_opus_encoder_create(opus_int32 Fs, int channels, int application, int *error)
- {
- int streams, coupled_streams;
- unsigned char mapping[256];
- return (OpusEncoder *)opus_multistream_surround_encoder_create(Fs, channels, 1, &streams, &coupled_streams, mapping, application, error);
- }
- static OpusDecoder *ms_opus_decoder_create(opus_int32 Fs, int channels, int *error)
- {
- int streams;
- int coupled_streams;
- unsigned char mapping[256]={0,1};
- streams = 1;
- coupled_streams = channels==2;
- return (OpusDecoder *)opus_multistream_decoder_create(Fs, channels, streams, coupled_streams, mapping, error);
- }
- #endif
- int main(int argc, char *argv[])
- {
- int err;
- char *inFile, *outFile;
- FILE *fin=NULL;
- FILE *fout=NULL;
- OpusEncoder *enc=NULL;
- OpusDecoder *dec=NULL;
- int args;
- int len[2];
- int frame_size, channels;
- opus_int32 bitrate_bps=0;
- unsigned char *data[2] = {NULL, NULL};
- unsigned char *fbytes=NULL;
- opus_int32 sampling_rate;
- int use_vbr;
- int max_payload_bytes;
- int complexity;
- int use_inbandfec;
- int use_dtx;
- int forcechannels;
- int cvbr = 0;
- int packet_loss_perc;
- opus_int32 count=0, count_act=0;
- int k;
- opus_int32 skip=0;
- int stop=0;
- short *in=NULL;
- short *out=NULL;
- int application=OPUS_APPLICATION_AUDIO;
- double bits=0.0, bits_max=0.0, bits_act=0.0, bits2=0.0, nrg;
- double tot_samples=0;
- opus_uint64 tot_in, tot_out;
- int bandwidth=OPUS_AUTO;
- const char *bandwidth_string;
- int lost = 0, lost_prev = 1;
- int toggle = 0;
- opus_uint32 enc_final_range[2];
- opus_uint32 dec_final_range;
- int encode_only=0, decode_only=0;
- int max_frame_size = 48000*2;
- size_t num_read;
- int curr_read=0;
- int sweep_bps = 0;
- int random_framesize=0, newsize=0, delayed_celt=0;
- int sweep_max=0, sweep_min=0;
- int random_fec=0;
- const int (*mode_list)[4]=NULL;
- int nb_modes_in_list=0;
- int curr_mode=0;
- int curr_mode_count=0;
- int mode_switch_time = 48000;
- int nb_encoded=0;
- int remaining=0;
- int variable_duration=OPUS_FRAMESIZE_ARG;
- int delayed_decision=0;
- int ret = EXIT_FAILURE;
- if (argc < 5 )
- {
- print_usage( argv );
- goto failure;
- }
- tot_in=tot_out=0;
- fprintf(stderr, "%s\n", opus_get_version_string());
- args = 1;
- if (strcmp(argv[args], "-e")==0)
- {
- encode_only = 1;
- args++;
- } else if (strcmp(argv[args], "-d")==0)
- {
- decode_only = 1;
- args++;
- }
- if (!decode_only && argc < 7 )
- {
- print_usage( argv );
- goto failure;
- }
- if (!decode_only)
- {
- if (strcmp(argv[args], "voip")==0)
- application = OPUS_APPLICATION_VOIP;
- else if (strcmp(argv[args], "restricted-lowdelay")==0)
- application = OPUS_APPLICATION_RESTRICTED_LOWDELAY;
- else if (strcmp(argv[args], "audio")!=0) {
- fprintf(stderr, "unknown application: %s\n", argv[args]);
- print_usage(argv);
- goto failure;
- }
- args++;
- }
- sampling_rate = (opus_int32)atol(argv[args]);
- args++;
- if (sampling_rate != 8000 && sampling_rate != 12000
- && sampling_rate != 16000 && sampling_rate != 24000
- && sampling_rate != 48000)
- {
- fprintf(stderr, "Supported sampling rates are 8000, 12000, "
- "16000, 24000 and 48000.\n");
- goto failure;
- }
- frame_size = sampling_rate/50;
- channels = atoi(argv[args]);
- args++;
- if (channels < 1 || channels > 2)
- {
- fprintf(stderr, "Opus_demo supports only 1 or 2 channels.\n");
- goto failure;
- }
- if (!decode_only)
- {
- bitrate_bps = (opus_int32)atol(argv[args]);
- args++;
- }
- /* defaults: */
- use_vbr = 1;
- max_payload_bytes = MAX_PACKET;
- complexity = 10;
- use_inbandfec = 0;
- forcechannels = OPUS_AUTO;
- use_dtx = 0;
- packet_loss_perc = 0;
- while( args < argc - 2 ) {
- /* process command line options */
- if( strcmp( argv[ args ], "-cbr" ) == 0 ) {
- check_encoder_option(decode_only, "-cbr");
- use_vbr = 0;
- args++;
- } else if( strcmp( argv[ args ], "-bandwidth" ) == 0 ) {
- check_encoder_option(decode_only, "-bandwidth");
- if (strcmp(argv[ args + 1 ], "NB")==0)
- bandwidth = OPUS_BANDWIDTH_NARROWBAND;
- else if (strcmp(argv[ args + 1 ], "MB")==0)
- bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
- else if (strcmp(argv[ args + 1 ], "WB")==0)
- bandwidth = OPUS_BANDWIDTH_WIDEBAND;
- else if (strcmp(argv[ args + 1 ], "SWB")==0)
- bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
- else if (strcmp(argv[ args + 1 ], "FB")==0)
- bandwidth = OPUS_BANDWIDTH_FULLBAND;
- else {
- fprintf(stderr, "Unknown bandwidth %s. "
- "Supported are NB, MB, WB, SWB, FB.\n",
- argv[ args + 1 ]);
- goto failure;
- }
- args += 2;
- } else if( strcmp( argv[ args ], "-framesize" ) == 0 ) {
- check_encoder_option(decode_only, "-framesize");
- if (strcmp(argv[ args + 1 ], "2.5")==0)
- frame_size = sampling_rate/400;
- else if (strcmp(argv[ args + 1 ], "5")==0)
- frame_size = sampling_rate/200;
- else if (strcmp(argv[ args + 1 ], "10")==0)
- frame_size = sampling_rate/100;
- else if (strcmp(argv[ args + 1 ], "20")==0)
- frame_size = sampling_rate/50;
- else if (strcmp(argv[ args + 1 ], "40")==0)
- frame_size = sampling_rate/25;
- else if (strcmp(argv[ args + 1 ], "60")==0)
- frame_size = 3*sampling_rate/50;
- else if (strcmp(argv[ args + 1 ], "80")==0)
- frame_size = 4*sampling_rate/50;
- else if (strcmp(argv[ args + 1 ], "100")==0)
- frame_size = 5*sampling_rate/50;
- else if (strcmp(argv[ args + 1 ], "120")==0)
- frame_size = 6*sampling_rate/50;
- else {
- fprintf(stderr, "Unsupported frame size: %s ms. "
- "Supported are 2.5, 5, 10, 20, 40, 60, 80, 100, 120.\n",
- argv[ args + 1 ]);
- goto failure;
- }
- args += 2;
- } else if( strcmp( argv[ args ], "-max_payload" ) == 0 ) {
- check_encoder_option(decode_only, "-max_payload");
- max_payload_bytes = atoi( argv[ args + 1 ] );
- args += 2;
- } else if( strcmp( argv[ args ], "-complexity" ) == 0 ) {
- check_encoder_option(decode_only, "-complexity");
- complexity = atoi( argv[ args + 1 ] );
- args += 2;
- } else if( strcmp( argv[ args ], "-inbandfec" ) == 0 ) {
- use_inbandfec = 1;
- args++;
- } else if( strcmp( argv[ args ], "-forcemono" ) == 0 ) {
- check_encoder_option(decode_only, "-forcemono");
- forcechannels = 1;
- args++;
- } else if( strcmp( argv[ args ], "-cvbr" ) == 0 ) {
- check_encoder_option(decode_only, "-cvbr");
- cvbr = 1;
- args++;
- } else if( strcmp( argv[ args ], "-delayed-decision" ) == 0 ) {
- check_encoder_option(decode_only, "-delayed-decision");
- delayed_decision = 1;
- args++;
- } else if( strcmp( argv[ args ], "-dtx") == 0 ) {
- check_encoder_option(decode_only, "-dtx");
- use_dtx = 1;
- args++;
- } else if( strcmp( argv[ args ], "-loss" ) == 0 ) {
- packet_loss_perc = atoi( argv[ args + 1 ] );
- args += 2;
- } else if( strcmp( argv[ args ], "-sweep" ) == 0 ) {
- check_encoder_option(decode_only, "-sweep");
- sweep_bps = atoi( argv[ args + 1 ] );
- args += 2;
- } else if( strcmp( argv[ args ], "-random_framesize" ) == 0 ) {
- check_encoder_option(decode_only, "-random_framesize");
- random_framesize = 1;
- args++;
- } else if( strcmp( argv[ args ], "-sweep_max" ) == 0 ) {
- check_encoder_option(decode_only, "-sweep_max");
- sweep_max = atoi( argv[ args + 1 ] );
- args += 2;
- } else if( strcmp( argv[ args ], "-random_fec" ) == 0 ) {
- check_encoder_option(decode_only, "-random_fec");
- random_fec = 1;
- args++;
- } else if( strcmp( argv[ args ], "-silk8k_test" ) == 0 ) {
- check_encoder_option(decode_only, "-silk8k_test");
- mode_list = silk8_test;
- nb_modes_in_list = 8;
- args++;
- } else if( strcmp( argv[ args ], "-silk12k_test" ) == 0 ) {
- check_encoder_option(decode_only, "-silk12k_test");
- mode_list = silk12_test;
- nb_modes_in_list = 8;
- args++;
- } else if( strcmp( argv[ args ], "-silk16k_test" ) == 0 ) {
- check_encoder_option(decode_only, "-silk16k_test");
- mode_list = silk16_test;
- nb_modes_in_list = 8;
- args++;
- } else if( strcmp( argv[ args ], "-hybrid24k_test" ) == 0 ) {
- check_encoder_option(decode_only, "-hybrid24k_test");
- mode_list = hybrid24_test;
- nb_modes_in_list = 4;
- args++;
- } else if( strcmp( argv[ args ], "-hybrid48k_test" ) == 0 ) {
- check_encoder_option(decode_only, "-hybrid48k_test");
- mode_list = hybrid48_test;
- nb_modes_in_list = 4;
- args++;
- } else if( strcmp( argv[ args ], "-celt_test" ) == 0 ) {
- check_encoder_option(decode_only, "-celt_test");
- mode_list = celt_test;
- nb_modes_in_list = 32;
- args++;
- } else if( strcmp( argv[ args ], "-celt_hq_test" ) == 0 ) {
- check_encoder_option(decode_only, "-celt_hq_test");
- mode_list = celt_hq_test;
- nb_modes_in_list = 4;
- args++;
- } else {
- printf( "Error: unrecognized setting: %s\n\n", argv[ args ] );
- print_usage( argv );
- goto failure;
- }
- }
- if (sweep_max)
- sweep_min = bitrate_bps;
- if (max_payload_bytes < 0 || max_payload_bytes > MAX_PACKET)
- {
- fprintf (stderr, "max_payload_bytes must be between 0 and %d\n",
- MAX_PACKET);
- goto failure;
- }
- inFile = argv[argc-2];
- fin = fopen(inFile, "rb");
- if (!fin)
- {
- fprintf (stderr, "Could not open input file %s\n", argv[argc-2]);
- goto failure;
- }
- if (mode_list)
- {
- int size;
- fseek(fin, 0, SEEK_END);
- size = ftell(fin);
- fprintf(stderr, "File size is %d bytes\n", size);
- fseek(fin, 0, SEEK_SET);
- mode_switch_time = size/sizeof(short)/channels/nb_modes_in_list;
- fprintf(stderr, "Switching mode every %d samples\n", mode_switch_time);
- }
- outFile = argv[argc-1];
- fout = fopen(outFile, "wb+");
- if (!fout)
- {
- fprintf (stderr, "Could not open output file %s\n", argv[argc-1]);
- goto failure;
- }
- if (!decode_only)
- {
- enc = opus_encoder_create(sampling_rate, channels, application, &err);
- if (err != OPUS_OK)
- {
- fprintf(stderr, "Cannot create encoder: %s\n", opus_strerror(err));
- goto failure;
- }
- opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
- opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bandwidth));
- opus_encoder_ctl(enc, OPUS_SET_VBR(use_vbr));
- opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(cvbr));
- opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity));
- opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(use_inbandfec));
- opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(forcechannels));
- opus_encoder_ctl(enc, OPUS_SET_DTX(use_dtx));
- opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packet_loss_perc));
- opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&skip));
- opus_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(16));
- opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration));
- }
- if (!encode_only)
- {
- dec = opus_decoder_create(sampling_rate, channels, &err);
- if (err != OPUS_OK)
- {
- fprintf(stderr, "Cannot create decoder: %s\n", opus_strerror(err));
- goto failure;
- }
- }
- switch(bandwidth)
- {
- case OPUS_BANDWIDTH_NARROWBAND:
- bandwidth_string = "narrowband";
- break;
- case OPUS_BANDWIDTH_MEDIUMBAND:
- bandwidth_string = "mediumband";
- break;
- case OPUS_BANDWIDTH_WIDEBAND:
- bandwidth_string = "wideband";
- break;
- case OPUS_BANDWIDTH_SUPERWIDEBAND:
- bandwidth_string = "superwideband";
- break;
- case OPUS_BANDWIDTH_FULLBAND:
- bandwidth_string = "fullband";
- break;
- case OPUS_AUTO:
- bandwidth_string = "auto bandwidth";
- break;
- default:
- bandwidth_string = "unknown";
- break;
- }
- if (decode_only)
- fprintf(stderr, "Decoding with %ld Hz output (%d channels)\n",
- (long)sampling_rate, channels);
- else
- fprintf(stderr, "Encoding %ld Hz input at %.3f kb/s "
- "in %s with %d-sample frames.\n",
- (long)sampling_rate, bitrate_bps*0.001,
- bandwidth_string, frame_size);
- in = (short*)malloc(max_frame_size*channels*sizeof(short));
- out = (short*)malloc(max_frame_size*channels*sizeof(short));
- /* We need to allocate for 16-bit PCM data, but we store it as unsigned char. */
- fbytes = (unsigned char*)malloc(max_frame_size*channels*sizeof(short));
- data[0] = (unsigned char*)calloc(max_payload_bytes,sizeof(unsigned char));
- if ( use_inbandfec ) {
- data[1] = (unsigned char*)calloc(max_payload_bytes,sizeof(unsigned char));
- }
- if(delayed_decision)
- {
- if (frame_size==sampling_rate/400)
- variable_duration = OPUS_FRAMESIZE_2_5_MS;
- else if (frame_size==sampling_rate/200)
- variable_duration = OPUS_FRAMESIZE_5_MS;
- else if (frame_size==sampling_rate/100)
- variable_duration = OPUS_FRAMESIZE_10_MS;
- else if (frame_size==sampling_rate/50)
- variable_duration = OPUS_FRAMESIZE_20_MS;
- else if (frame_size==sampling_rate/25)
- variable_duration = OPUS_FRAMESIZE_40_MS;
- else if (frame_size==3*sampling_rate/50)
- variable_duration = OPUS_FRAMESIZE_60_MS;
- else if (frame_size==4*sampling_rate/50)
- variable_duration = OPUS_FRAMESIZE_80_MS;
- else if (frame_size==5*sampling_rate/50)
- variable_duration = OPUS_FRAMESIZE_100_MS;
- else
- variable_duration = OPUS_FRAMESIZE_120_MS;
- opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration));
- frame_size = 2*48000;
- }
- while (!stop)
- {
- if (delayed_celt)
- {
- frame_size = newsize;
- delayed_celt = 0;
- } else if (random_framesize && rand()%20==0)
- {
- newsize = rand()%6;
- switch(newsize)
- {
- case 0: newsize=sampling_rate/400; break;
- case 1: newsize=sampling_rate/200; break;
- case 2: newsize=sampling_rate/100; break;
- case 3: newsize=sampling_rate/50; break;
- case 4: newsize=sampling_rate/25; break;
- case 5: newsize=3*sampling_rate/50; break;
- }
- while (newsize < sampling_rate/25 && bitrate_bps-abs(sweep_bps) <= 3*12*sampling_rate/newsize)
- newsize*=2;
- if (newsize < sampling_rate/100 && frame_size >= sampling_rate/100)
- {
- opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
- delayed_celt=1;
- } else {
- frame_size = newsize;
- }
- }
- if (random_fec && rand()%30==0)
- {
- opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(rand()%4==0));
- }
- if (decode_only)
- {
- unsigned char ch[4];
- num_read = fread(ch, 1, 4, fin);
- if (num_read!=4)
- break;
- len[toggle] = char_to_int(ch);
- if (len[toggle]>max_payload_bytes || len[toggle]<0)
- {
- fprintf(stderr, "Invalid payload length: %d\n",len[toggle]);
- break;
- }
- num_read = fread(ch, 1, 4, fin);
- if (num_read!=4)
- break;
- enc_final_range[toggle] = char_to_int(ch);
- num_read = fread(data[toggle], 1, len[toggle], fin);
- if (num_read!=(size_t)len[toggle])
- {
- fprintf(stderr, "Ran out of input, "
- "expecting %d bytes got %d\n",
- len[toggle],(int)num_read);
- break;
- }
- } else {
- int i;
- if (mode_list!=NULL)
- {
- opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(mode_list[curr_mode][1]));
- opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(mode_list[curr_mode][0]));
- opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(mode_list[curr_mode][3]));
- frame_size = mode_list[curr_mode][2];
- }
- num_read = fread(fbytes, sizeof(short)*channels, frame_size-remaining, fin);
- curr_read = (int)num_read;
- tot_in += curr_read;
- for(i=0;i<curr_read*channels;i++)
- {
- opus_int32 s;
- s=fbytes[2*i+1]<<8|fbytes[2*i];
- s=((s&0xFFFF)^0x8000)-0x8000;
- in[i+remaining*channels]=s;
- }
- if (curr_read+remaining < frame_size)
- {
- for (i=(curr_read+remaining)*channels;i<frame_size*channels;i++)
- in[i] = 0;
- if (encode_only || decode_only)
- stop = 1;
- }
- len[toggle] = opus_encode(enc, in, frame_size, data[toggle], max_payload_bytes);
- nb_encoded = opus_packet_get_samples_per_frame(data[toggle], sampling_rate)*opus_packet_get_nb_frames(data[toggle], len[toggle]);
- remaining = frame_size-nb_encoded;
- for(i=0;i<remaining*channels;i++)
- in[i] = in[nb_encoded*channels+i];
- if (sweep_bps!=0)
- {
- bitrate_bps += sweep_bps;
- if (sweep_max)
- {
- if (bitrate_bps > sweep_max)
- sweep_bps = -sweep_bps;
- else if (bitrate_bps < sweep_min)
- sweep_bps = -sweep_bps;
- }
- /* safety */
- if (bitrate_bps<1000)
- bitrate_bps = 1000;
- opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
- }
- opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range[toggle]));
- if (len[toggle] < 0)
- {
- fprintf (stderr, "opus_encode() returned %d\n", len[toggle]);
- goto failure;
- }
- curr_mode_count += frame_size;
- if (curr_mode_count > mode_switch_time && curr_mode < nb_modes_in_list-1)
- {
- curr_mode++;
- curr_mode_count = 0;
- }
- }
- #if 0 /* This is for testing the padding code, do not enable by default */
- if (len[toggle]<1275)
- {
- int new_len = len[toggle]+rand()%(max_payload_bytes-len[toggle]);
- if ((err = opus_packet_pad(data[toggle], len[toggle], new_len)) != OPUS_OK)
- {
- fprintf(stderr, "padding failed: %s\n", opus_strerror(err));
- goto failure;
- }
- len[toggle] = new_len;
- }
- #endif
- if (encode_only)
- {
- unsigned char int_field[4];
- int_to_char(len[toggle], int_field);
- if (fwrite(int_field, 1, 4, fout) != 4) {
- fprintf(stderr, "Error writing.\n");
- goto failure;
- }
- int_to_char(enc_final_range[toggle], int_field);
- if (fwrite(int_field, 1, 4, fout) != 4) {
- fprintf(stderr, "Error writing.\n");
- goto failure;
- }
- if (fwrite(data[toggle], 1, len[toggle], fout) != (unsigned)len[toggle]) {
- fprintf(stderr, "Error writing.\n");
- goto failure;
- }
- tot_samples += nb_encoded;
- } else {
- opus_int32 output_samples;
- lost = len[toggle]==0 || (packet_loss_perc>0 && rand()%100 < packet_loss_perc);
- if (lost)
- opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));
- else
- output_samples = max_frame_size;
- if( count >= use_inbandfec ) {
- /* delay by one packet when using in-band FEC */
- if( use_inbandfec ) {
- if( lost_prev ) {
- /* attempt to decode with in-band FEC from next packet */
- opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));
- output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 1);
- } else {
- /* regular decode */
- output_samples = max_frame_size;
- output_samples = opus_decode(dec, data[1-toggle], len[1-toggle], out, output_samples, 0);
- }
- } else {
- output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 0);
- }
- if (output_samples>0)
- {
- if (!decode_only && tot_out + output_samples > tot_in)
- {
- stop=1;
- output_samples = (opus_int32)(tot_in - tot_out);
- }
- if (output_samples>skip) {
- int i;
- for(i=0;i<(output_samples-skip)*channels;i++)
- {
- short s;
- s=out[i+(skip*channels)];
- fbytes[2*i]=s&0xFF;
- fbytes[2*i+1]=(s>>8)&0xFF;
- }
- if (fwrite(fbytes, sizeof(short)*channels, output_samples-skip, fout) != (unsigned)(output_samples-skip)){
- fprintf(stderr, "Error writing.\n");
- goto failure;
- }
- tot_out += output_samples-skip;
- }
- if (output_samples<skip) skip -= output_samples;
- else skip = 0;
- } else {
- fprintf(stderr, "error decoding frame: %s\n",
- opus_strerror(output_samples));
- }
- tot_samples += output_samples;
- }
- }
- if (!encode_only)
- opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range));
- /* compare final range encoder rng values of encoder and decoder */
- if( enc_final_range[toggle^use_inbandfec]!=0 && !encode_only
- && !lost && !lost_prev
- && dec_final_range != enc_final_range[toggle^use_inbandfec] ) {
- 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);
- goto failure;
- }
- lost_prev = lost;
- if( count >= use_inbandfec ) {
- /* count bits */
- bits += len[toggle]*8;
- bits_max = ( len[toggle]*8 > bits_max ) ? len[toggle]*8 : bits_max;
- bits2 += len[toggle]*len[toggle]*64;
- if (!decode_only)
- {
- nrg = 0.0;
- for ( k = 0; k < frame_size * channels; k++ ) {
- nrg += in[ k ] * (double)in[ k ];
- }
- nrg /= frame_size * channels;
- if( nrg > 1e5 ) {
- bits_act += len[toggle]*8;
- count_act++;
- }
- }
- }
- count++;
- toggle = (toggle + use_inbandfec) & 1;
- }
- if(decode_only && count > 0)
- frame_size = (int)(tot_samples / count);
- count -= use_inbandfec;
- if (tot_samples >= 1 && count > 0 && frame_size)
- {
- /* Print out bitrate statistics */
- double var;
- fprintf (stderr, "average bitrate: %7.3f kb/s\n",
- 1e-3*bits*sampling_rate/tot_samples);
- fprintf (stderr, "maximum bitrate: %7.3f kb/s\n",
- 1e-3*bits_max*sampling_rate/frame_size);
- if (!decode_only)
- fprintf (stderr, "active bitrate: %7.3f kb/s\n",
- 1e-3*bits_act*sampling_rate/(1e-15+frame_size*(double)count_act));
- var = bits2/count - bits*bits/(count*(double)count);
- if (var < 0)
- var = 0;
- fprintf (stderr, "bitrate standard deviation: %7.3f kb/s\n",
- 1e-3*sqrt(var)*sampling_rate/frame_size);
- } else {
- fprintf(stderr, "bitrate statistics are undefined\n");
- }
- silk_TimerSave("opus_timing.txt");
- ret = EXIT_SUCCESS;
- failure:
- opus_encoder_destroy(enc);
- opus_decoder_destroy(dec);
- free(data[0]);
- free(data[1]);
- if (fin)
- fclose(fin);
- if (fout)
- fclose(fout);
- free(in);
- free(out);
- free(fbytes);
- return ret;
- }
|