1e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner/* Copyright (c) 2007-2008 CSIRO
22cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   Copyright (c) 2007-2009 Xiph.Org Foundation
32cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   Written by Jean-Marc Valin */
42cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/*
52cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   Redistribution and use in source and binary forms, with or without
62cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   modification, are permitted provided that the following conditions
72cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   are met:
82cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
92cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   - Redistributions of source code must retain the above copyright
102cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   notice, this list of conditions and the following disclaimer.
112cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
122cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   - Redistributions in binary form must reproduce the above copyright
132cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   notice, this list of conditions and the following disclaimer in the
142cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   documentation and/or other materials provided with the distribution.
15e7785040107266d01ebdcc066365f70b7ace371fDouglas Gregor
161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
200b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
212cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2377f4603c8b142e642300959a601ecec2b7c8e288Sebastian Redl   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
247c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
256a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
267c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2783d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff*/
2814f79002e58556798e86168c63e48d533287eda5Douglas Gregor
293251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor#ifdef HAVE_CONFIG_H
3014f79002e58556798e86168c63e48d533287eda5Douglas Gregor#include "config.h"
31bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor#endif
322bec0410d268779f601bd509e0302a500af7ac6aDouglas Gregor
33ab41e63821dc60ad144d0684df8d79a9eef86b75Douglas Gregor#include <stdio.h>
3417fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor#include <stdlib.h>
3517fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor#include <math.h>
362596e429a61602312bdd149786045b8a90cd2d10Daniel Dunbar#include <string.h>
372cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "opus.h"
3814f79002e58556798e86168c63e48d533287eda5Douglas Gregor#include "debug.h"
39b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor#include "opus_types.h"
403c304bd9ec2b4611572d4cbae9e1727bbecb5dc9Chris Lattner#include "opus_private.h"
412cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "opus_multistream.h"
422cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
432cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#define MAX_PACKET 1500
442cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
452cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid print_usage( char* argv[] )
4612b1c7615d4f9a2edc544be499f895f16ac100edChris Lattner{
472cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    fprintf(stderr, "Usage: %s [-e] <application> <sampling rate (Hz)> <channels (1/2)> "
48bd21828179a61bd0954b082825cfb8a93345f602Benjamin Kramer        "<bits per second>  [options] <input> <output>\n", argv[0]);
492cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    fprintf(stderr, "       %s -d <sampling rate (Hz)> <channels (1/2)> "
502cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor        "[options] <input> <output>\n\n", argv[0]);
512cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    fprintf(stderr, "mode: voip | audio | restricted-lowdelay\n" );
522cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    fprintf(stderr, "options:\n" );
532cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    fprintf(stderr, "-e                   : only runs the encoder (output the bit-stream)\n" );
542cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    fprintf(stderr, "-d                   : only runs the decoder (reads the bit-stream as input)\n" );
552cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    fprintf(stderr, "-cbr                 : enable constant bitrate; default: variable bitrate\n" );
561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    fprintf(stderr, "-cvbr                : enable constrained variable bitrate; default: unconstrained\n" );
574fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor    fprintf(stderr, "-variable-duration   : enable frames of variable duration (experts only); default: disabled\n" );
582cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    fprintf(stderr, "-bandwidth <NB|MB|WB|SWB|FB> : audio bandwidth (from narrowband to fullband); default: sampling rate\n" );
592cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    fprintf(stderr, "-framesize <2.5|5|10|20|40|60> : frame size in ms; default: 20 \n" );
602cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    fprintf(stderr, "-max_payload <bytes> : maximum payload size in bytes, default: 1024\n" );
612cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    fprintf(stderr, "-complexity <comp>   : complexity, 0 (lowest) ... 10 (highest); default: 10\n" );
622cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    fprintf(stderr, "-inbandfec           : enable SILK inband FEC\n" );
632cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    fprintf(stderr, "-forcemono           : force mono encoding, even for stereo input\n" );
642cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    fprintf(stderr, "-dtx                 : enable SILK DTX\n" );
652cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    fprintf(stderr, "-loss <perc>         : simulate packet loss, in percent (0-100); default: 0\n" );
662cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor}
672cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
682cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorstatic void int_to_char(opus_uint32 i, unsigned char ch[4])
692cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor{
702cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    ch[0] = i>>24;
712cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    ch[1] = (i>>16)&0xFF;
722cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    ch[2] = (i>>8)&0xFF;
732cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    ch[3] = i&0xFF;
742cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor}
752cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
762cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorstatic opus_uint32 char_to_int(unsigned char ch[4])
772cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor{
782cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    return ((opus_uint32)ch[0]<<24) | ((opus_uint32)ch[1]<<16)
792cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor         | ((opus_uint32)ch[2]<< 8) |  (opus_uint32)ch[3];
802cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor}
812cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
822cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorstatic void check_encoder_option(int decode_only, const char *opt)
832cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor{
841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   if (decode_only)
852cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   {
862cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      fprintf(stderr, "option %s is only for encoding\n", opt);
872cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      exit(EXIT_FAILURE);
882cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   }
892cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor}
902cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
912cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorstatic const int silk8_test[][4] = {
922cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 1},
932cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 1},
942cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960,   1},
952cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480,   1},
962cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 2},
972cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 2},
982cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960,   2},
991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480,   2}
1001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump};
1012cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1022cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorstatic const int silk12_test[][4] = {
1032cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 1},
1042cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 1},
1052cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960,   1},
1062cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480,   1},
1070953e767ff7817f97b3ab20896b229891eeff45bJohn McCall      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 2},
1082cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 2},
1092cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960,   2},
1102cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480,   2}
1112cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor};
1122cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1132cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorstatic const int silk16_test[][4] = {
1142cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 1},
1152cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 1},
1162cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960,   1},
1172cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480,   1},
1182cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 2},
1192cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 2},
1202cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960,   2},
1212cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480,   2}
1222cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor};
1237e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor
1247e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregorstatic const int hybrid24_test[][4] = {
125c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1},
1262cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1},
1272cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2},
1282cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2}
1292cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor};
1302cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1312cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorstatic const int hybrid48_test[][4] = {
132788b0fd67e1992f23555454efcdb16a19dfefac3Chris Lattner      {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 1},
1332cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 1},
1342cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2},
1352cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2}
1362cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor};
1372cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1382cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorstatic const int celt_test[][4] = {
1392cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      960, 1},
1402cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1},
1412cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      960, 1},
1422cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    960, 1},
143264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola
144264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      480, 1},
145425ef72306d4ff6b3698b744353e5f0e56b4b884Rafael Espindola      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1},
146ab8bbf4ebd3e3e6eab913cb044772a62b7581941Douglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      480, 1},
147264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    480, 1},
1482cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1492cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      240, 1},
1502cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 240, 1},
1512cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      240, 1},
1522cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    240, 1},
1532cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1542cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      120, 1},
1552cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 120, 1},
1562cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      120, 1},
1572cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    120, 1},
1582cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1592cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      960, 2},
1602cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2},
1612cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      960, 2},
162465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    960, 2},
163465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl
164465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      480, 2},
165465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2},
166465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      480, 2},
1672cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    480, 2},
1682cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1692cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      240, 2},
170ed97649e9574b9d854fa4d6109c9333ae0993554John McCall      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 240, 2},
171ed97649e9574b9d854fa4d6109c9333ae0993554John McCall      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      240, 2},
172ed97649e9574b9d854fa4d6109c9333ae0993554John McCall      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    240, 2},
173ed97649e9574b9d854fa4d6109c9333ae0993554John McCall
174ed97649e9574b9d854fa4d6109c9333ae0993554John McCall      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      120, 2},
1752cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 120, 2},
1762cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      120, 2},
1779763e221e16026ddf487d2564ed349d2c874a1a1Argyrios Kyrtzidis      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    120, 2},
1789763e221e16026ddf487d2564ed349d2c874a1a1Argyrios Kyrtzidis
1792cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor};
1802cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1812cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorstatic const int celt_hq_test[][4] = {
1822cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      960, 2},
183c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      480, 2},
1842cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      240, 2},
1852cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      120, 2},
1862cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor};
1872cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1882cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#if 0 /* This is a hack that replaces the normal encoder/decoder with the multistream version */
1892cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#define OpusEncoder OpusMSEncoder
1902cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#define OpusDecoder OpusMSDecoder
1912cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#define opus_encode opus_multistream_encode
192395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson#define opus_decode opus_multistream_decode
193395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson#define opus_encoder_ctl opus_multistream_encoder_ctl
194395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson#define opus_decoder_ctl opus_multistream_decoder_ctl
195395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson#define opus_encoder_create ms_opus_encoder_create
196395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson#define opus_decoder_create ms_opus_decoder_create
1972cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#define opus_encoder_destroy opus_multistream_encoder_destroy
198be191100e034b23a3e13053757a57b7f5068c24aArgyrios Kyrtzidis#define opus_decoder_destroy opus_multistream_decoder_destroy
1992cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic OpusEncoder *ms_opus_encoder_create(opus_int32 Fs, int channels, int application, int *error)
2012cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor{
2022cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   int streams, coupled_streams;
2032cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   unsigned char mapping[256];
2042cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   return (OpusEncoder *)opus_multistream_surround_encoder_create(Fs, channels, 1, &streams, &coupled_streams, mapping, application, error);
2052cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor}
2062cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorstatic OpusDecoder *ms_opus_decoder_create(opus_int32 Fs, int channels, int *error)
2072cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor{
2082cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   int streams;
2092cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   int coupled_streams;
2102cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   unsigned char mapping[256]={0,1};
2112cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   streams = 1;
2122cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   coupled_streams = channels==2;
2132cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   return (OpusDecoder *)opus_multistream_decoder_create(Fs, channels, streams, coupled_streams, mapping, error);
2141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
21549a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall#endif
21649a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall
21749a832bd499d6f61c23655f1fac99f0dd229756eJohn McCallint main(int argc, char *argv[])
21849a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall{
21949a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall    int err;
22049a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall    char *inFile, *outFile;
22149a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall    FILE *fin, *fout;
22249a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall    OpusEncoder *enc=NULL;
2232cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    OpusDecoder *dec=NULL;
2242cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    int args;
225be191100e034b23a3e13053757a57b7f5068c24aArgyrios Kyrtzidis    int len[2];
22690b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    int frame_size, channels;
22790b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    opus_int32 bitrate_bps=0;
22890b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    unsigned char *data[2];
22990b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    unsigned char *fbytes;
23090b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    opus_int32 sampling_rate;
2319763e221e16026ddf487d2564ed349d2c874a1a1Argyrios Kyrtzidis    int use_vbr;
2329763e221e16026ddf487d2564ed349d2c874a1a1Argyrios Kyrtzidis    int max_payload_bytes;
2339763e221e16026ddf487d2564ed349d2c874a1a1Argyrios Kyrtzidis    int complexity;
23490b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    int use_inbandfec;
23590b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    int use_dtx;
23690b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    int forcechannels;
23790b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    int cvbr = 0;
23890b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    int packet_loss_perc;
239ae8b17f1d5d303af53db5a4f4a375ea6b9356566Argyrios Kyrtzidis    opus_int32 count=0, count_act=0;
240ae8b17f1d5d303af53db5a4f4a375ea6b9356566Argyrios Kyrtzidis    int k;
241ae8b17f1d5d303af53db5a4f4a375ea6b9356566Argyrios Kyrtzidis    opus_int32 skip=0;
242ae8b17f1d5d303af53db5a4f4a375ea6b9356566Argyrios Kyrtzidis    int stop=0;
24390b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    short *in, *out;
24490b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    int application=OPUS_APPLICATION_AUDIO;
24590b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    double bits=0.0, bits_max=0.0, bits_act=0.0, bits2=0.0, nrg;
24690b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    double tot_samples=0;
24790b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    opus_uint64 tot_in, tot_out;
24890b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    int bandwidth=-1;
24990b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    const char *bandwidth_string;
25090b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    int lost = 0, lost_prev = 1;
25190b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    int toggle = 0;
25290b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    opus_uint32 enc_final_range[2];
25390b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    opus_uint32 dec_final_range;
25490b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    int encode_only=0, decode_only=0;
25590b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    int max_frame_size = 960*6;
25690b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    int curr_read=0;
25790b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    int sweep_bps = 0;
25890b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    int random_framesize=0, newsize=0, delayed_celt=0;
25990b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    int sweep_max=0, sweep_min=0;
26090b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    int random_fec=0;
26190b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    const int (*mode_list)[4]=NULL;
26290b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    int nb_modes_in_list=0;
2638dfbd8b252ba4e6cf4b7a3422f6ef0ca21312dfeArgyrios Kyrtzidis    int curr_mode=0;
2648dfbd8b252ba4e6cf4b7a3422f6ef0ca21312dfeArgyrios Kyrtzidis    int curr_mode_count=0;
2658dfbd8b252ba4e6cf4b7a3422f6ef0ca21312dfeArgyrios Kyrtzidis    int mode_switch_time = 48000;
266f48d45e3e36c132bdee3373beec4e8b19ae3f9c4Argyrios Kyrtzidis    int nb_encoded=0;
267f48d45e3e36c132bdee3373beec4e8b19ae3f9c4Argyrios Kyrtzidis    int remaining=0;
268f48d45e3e36c132bdee3373beec4e8b19ae3f9c4Argyrios Kyrtzidis    int variable_duration=OPUS_FRAMESIZE_ARG;
2698dfbd8b252ba4e6cf4b7a3422f6ef0ca21312dfeArgyrios Kyrtzidis    int delayed_decision=0;
27090b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis
27190b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    if (argc < 5 )
27290b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis    {
27390b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis       print_usage( argv );
27490b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis       return EXIT_FAILURE;
2753acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis    }
2763acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis
2773acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis    tot_in=tot_out=0;
2783acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis    fprintf(stderr, "%s\n", opus_get_version_string());
2793acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis
2803acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis    args = 1;
2813acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis    if (strcmp(argv[args], "-e")==0)
2823acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis    {
2832cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor        encode_only = 1;
2842cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor        args++;
285465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara    } else if (strcmp(argv[args], "-d")==0)
286465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara    {
2873acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis        decode_only = 1;
2883acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis        args++;
289465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara    }
2902cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    if (!decode_only && argc < 7 )
2912cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    {
2923cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall       print_usage( argv );
2933cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall       return EXIT_FAILURE;
29431f17ecbef57b5679c017c375db330546b7b5145John McCall    }
2953cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall
2963cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall    if (!decode_only)
2973cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall    {
2982cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor       if (strcmp(argv[args], "voip")==0)
2992cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor          application = OPUS_APPLICATION_VOIP;
300c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall       else if (strcmp(argv[args], "restricted-lowdelay")==0)
301c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall          application = OPUS_APPLICATION_RESTRICTED_LOWDELAY;
302c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall       else if (strcmp(argv[args], "audio")!=0) {
303c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall          fprintf(stderr, "unknown application: %s\n", argv[args]);
304c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall          print_usage(argv);
3052cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor          return EXIT_FAILURE;
306c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall       }
307446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroff       args++;
308446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroff    }
309c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall    sampling_rate = (opus_int32)atol(argv[args]);
3102cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    args++;
3112cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
312d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    if (sampling_rate != 8000 && sampling_rate != 12000
313d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff     && sampling_rate != 16000 && sampling_rate != 24000
3141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump     && sampling_rate != 48000)
315d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    {
3162cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor        fprintf(stderr, "Supported sampling rates are 8000, 12000, "
3172cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor                "16000, 24000 and 48000.\n");
318a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall        return EXIT_FAILURE;
319a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall    }
320a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall    frame_size = sampling_rate/50;
321a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall
322a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall    channels = atoi(argv[args]);
323a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall    args++;
324a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall
325a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall    if (channels < 1 || channels > 2)
326a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall    {
327a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall        fprintf(stderr, "Opus_demo supports only 1 or 2 channels.\n");
32851bd803fbdade51d674598ed45da3d54190a656cJohn McCall        return EXIT_FAILURE;
329a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall    }
33051bd803fbdade51d674598ed45da3d54190a656cJohn McCall
331a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall    if (!decode_only)
332a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall    {
33351bd803fbdade51d674598ed45da3d54190a656cJohn McCall       bitrate_bps = (opus_int32)atol(argv[args]);
33451bd803fbdade51d674598ed45da3d54190a656cJohn McCall       args++;
335a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall    }
336a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall
337a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall    /* defaults: */
338a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall    use_vbr = 1;
33951bd803fbdade51d674598ed45da3d54190a656cJohn McCall    bandwidth = OPUS_AUTO;
34051bd803fbdade51d674598ed45da3d54190a656cJohn McCall    max_payload_bytes = MAX_PACKET;
34151bd803fbdade51d674598ed45da3d54190a656cJohn McCall    complexity = 10;
34251bd803fbdade51d674598ed45da3d54190a656cJohn McCall    use_inbandfec = 0;
343ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    forcechannels = OPUS_AUTO;
344ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    use_dtx = 0;
345ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    packet_loss_perc = 0;
346ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    max_frame_size = 2*48000;
347ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    curr_read=0;
348ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor
349ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    while( args < argc - 2 ) {
35051bd803fbdade51d674598ed45da3d54190a656cJohn McCall        /* process command line options */
35151bd803fbdade51d674598ed45da3d54190a656cJohn McCall        if( strcmp( argv[ args ], "-cbr" ) == 0 ) {
35251bd803fbdade51d674598ed45da3d54190a656cJohn McCall            check_encoder_option(decode_only, "-cbr");
35351bd803fbdade51d674598ed45da3d54190a656cJohn McCall            use_vbr = 0;
35451bd803fbdade51d674598ed45da3d54190a656cJohn McCall            args++;
35551bd803fbdade51d674598ed45da3d54190a656cJohn McCall        } else if( strcmp( argv[ args ], "-bandwidth" ) == 0 ) {
35651bd803fbdade51d674598ed45da3d54190a656cJohn McCall            check_encoder_option(decode_only, "-bandwidth");
35751bd803fbdade51d674598ed45da3d54190a656cJohn McCall            if (strcmp(argv[ args + 1 ], "NB")==0)
35851bd803fbdade51d674598ed45da3d54190a656cJohn McCall                bandwidth = OPUS_BANDWIDTH_NARROWBAND;
35951bd803fbdade51d674598ed45da3d54190a656cJohn McCall            else if (strcmp(argv[ args + 1 ], "MB")==0)
36051bd803fbdade51d674598ed45da3d54190a656cJohn McCall                bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
36151bd803fbdade51d674598ed45da3d54190a656cJohn McCall            else if (strcmp(argv[ args + 1 ], "WB")==0)
36251bd803fbdade51d674598ed45da3d54190a656cJohn McCall                bandwidth = OPUS_BANDWIDTH_WIDEBAND;
36351bd803fbdade51d674598ed45da3d54190a656cJohn McCall            else if (strcmp(argv[ args + 1 ], "SWB")==0)
36451bd803fbdade51d674598ed45da3d54190a656cJohn McCall                bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
36551bd803fbdade51d674598ed45da3d54190a656cJohn McCall            else if (strcmp(argv[ args + 1 ], "FB")==0)
36651bd803fbdade51d674598ed45da3d54190a656cJohn McCall                bandwidth = OPUS_BANDWIDTH_FULLBAND;
36751bd803fbdade51d674598ed45da3d54190a656cJohn McCall            else {
36851bd803fbdade51d674598ed45da3d54190a656cJohn McCall                fprintf(stderr, "Unknown bandwidth %s. "
36951bd803fbdade51d674598ed45da3d54190a656cJohn McCall                                "Supported are NB, MB, WB, SWB, FB.\n",
37051bd803fbdade51d674598ed45da3d54190a656cJohn McCall                                argv[ args + 1 ]);
37151bd803fbdade51d674598ed45da3d54190a656cJohn McCall                return EXIT_FAILURE;
37251bd803fbdade51d674598ed45da3d54190a656cJohn McCall            }
37351bd803fbdade51d674598ed45da3d54190a656cJohn McCall            args += 2;
37451bd803fbdade51d674598ed45da3d54190a656cJohn McCall        } else if( strcmp( argv[ args ], "-framesize" ) == 0 ) {
37551bd803fbdade51d674598ed45da3d54190a656cJohn McCall            check_encoder_option(decode_only, "-framesize");
37651bd803fbdade51d674598ed45da3d54190a656cJohn McCall            if (strcmp(argv[ args + 1 ], "2.5")==0)
37751bd803fbdade51d674598ed45da3d54190a656cJohn McCall                frame_size = sampling_rate/400;
37851bd803fbdade51d674598ed45da3d54190a656cJohn McCall            else if (strcmp(argv[ args + 1 ], "5")==0)
37951bd803fbdade51d674598ed45da3d54190a656cJohn McCall                frame_size = sampling_rate/200;
38051bd803fbdade51d674598ed45da3d54190a656cJohn McCall            else if (strcmp(argv[ args + 1 ], "10")==0)
38151bd803fbdade51d674598ed45da3d54190a656cJohn McCall                frame_size = sampling_rate/100;
38251bd803fbdade51d674598ed45da3d54190a656cJohn McCall            else if (strcmp(argv[ args + 1 ], "20")==0)
38351bd803fbdade51d674598ed45da3d54190a656cJohn McCall                frame_size = sampling_rate/50;
38451bd803fbdade51d674598ed45da3d54190a656cJohn McCall            else if (strcmp(argv[ args + 1 ], "40")==0)
38551bd803fbdade51d674598ed45da3d54190a656cJohn McCall                frame_size = sampling_rate/25;
38651bd803fbdade51d674598ed45da3d54190a656cJohn McCall            else if (strcmp(argv[ args + 1 ], "60")==0)
38751bd803fbdade51d674598ed45da3d54190a656cJohn McCall                frame_size = 3*sampling_rate/50;
38851bd803fbdade51d674598ed45da3d54190a656cJohn McCall            else {
38951bd803fbdade51d674598ed45da3d54190a656cJohn McCall                fprintf(stderr, "Unsupported frame size: %s ms. "
39051bd803fbdade51d674598ed45da3d54190a656cJohn McCall                                "Supported are 2.5, 5, 10, 20, 40, 60.\n",
39151bd803fbdade51d674598ed45da3d54190a656cJohn McCall                                argv[ args + 1 ]);
39251bd803fbdade51d674598ed45da3d54190a656cJohn McCall                return EXIT_FAILURE;
39351bd803fbdade51d674598ed45da3d54190a656cJohn McCall            }
39451bd803fbdade51d674598ed45da3d54190a656cJohn McCall            args += 2;
39551bd803fbdade51d674598ed45da3d54190a656cJohn McCall        } else if( strcmp( argv[ args ], "-max_payload" ) == 0 ) {
39651bd803fbdade51d674598ed45da3d54190a656cJohn McCall            check_encoder_option(decode_only, "-max_payload");
39751bd803fbdade51d674598ed45da3d54190a656cJohn McCall            max_payload_bytes = atoi( argv[ args + 1 ] );
39851bd803fbdade51d674598ed45da3d54190a656cJohn McCall            args += 2;
39951bd803fbdade51d674598ed45da3d54190a656cJohn McCall        } else if( strcmp( argv[ args ], "-complexity" ) == 0 ) {
40051bd803fbdade51d674598ed45da3d54190a656cJohn McCall            check_encoder_option(decode_only, "-complexity");
40151bd803fbdade51d674598ed45da3d54190a656cJohn McCall            complexity = atoi( argv[ args + 1 ] );
40251bd803fbdade51d674598ed45da3d54190a656cJohn McCall            args += 2;
40351bd803fbdade51d674598ed45da3d54190a656cJohn McCall        } else if( strcmp( argv[ args ], "-inbandfec" ) == 0 ) {
40451bd803fbdade51d674598ed45da3d54190a656cJohn McCall            use_inbandfec = 1;
40551bd803fbdade51d674598ed45da3d54190a656cJohn McCall            args++;
40651bd803fbdade51d674598ed45da3d54190a656cJohn McCall        } else if( strcmp( argv[ args ], "-forcemono" ) == 0 ) {
40751bd803fbdade51d674598ed45da3d54190a656cJohn McCall            check_encoder_option(decode_only, "-forcemono");
40851bd803fbdade51d674598ed45da3d54190a656cJohn McCall            forcechannels = 1;
40951bd803fbdade51d674598ed45da3d54190a656cJohn McCall            args++;
41051bd803fbdade51d674598ed45da3d54190a656cJohn McCall        } else if( strcmp( argv[ args ], "-cvbr" ) == 0 ) {
411ed97649e9574b9d854fa4d6109c9333ae0993554John McCall            check_encoder_option(decode_only, "-cvbr");
412ed97649e9574b9d854fa4d6109c9333ae0993554John McCall            cvbr = 1;
413ed97649e9574b9d854fa4d6109c9333ae0993554John McCall            args++;
41451bd803fbdade51d674598ed45da3d54190a656cJohn McCall        } else if( strcmp( argv[ args ], "-variable-duration" ) == 0 ) {
41551bd803fbdade51d674598ed45da3d54190a656cJohn McCall            check_encoder_option(decode_only, "-variable-duration");
41651bd803fbdade51d674598ed45da3d54190a656cJohn McCall            variable_duration = OPUS_FRAMESIZE_VARIABLE;
41751bd803fbdade51d674598ed45da3d54190a656cJohn McCall            args++;
418cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall        } else if( strcmp( argv[ args ], "-delayed-decision" ) == 0 ) {
419cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall            check_encoder_option(decode_only, "-delayed-decision");
420cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall            delayed_decision = 1;
42151bd803fbdade51d674598ed45da3d54190a656cJohn McCall            args++;
42251bd803fbdade51d674598ed45da3d54190a656cJohn McCall        } else if( strcmp( argv[ args ], "-dtx") == 0 ) {
423cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall            check_encoder_option(decode_only, "-dtx");
424cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall            use_dtx = 1;
425cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall            args++;
426cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall        } else if( strcmp( argv[ args ], "-loss" ) == 0 ) {
42751bd803fbdade51d674598ed45da3d54190a656cJohn McCall            packet_loss_perc = atoi( argv[ args + 1 ] );
42851bd803fbdade51d674598ed45da3d54190a656cJohn McCall            args += 2;
42951bd803fbdade51d674598ed45da3d54190a656cJohn McCall        } else if( strcmp( argv[ args ], "-sweep" ) == 0 ) {
430a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall            check_encoder_option(decode_only, "-sweep");
43151bd803fbdade51d674598ed45da3d54190a656cJohn McCall            sweep_bps = atoi( argv[ args + 1 ] );
43251bd803fbdade51d674598ed45da3d54190a656cJohn McCall            args += 2;
433a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall        } else if( strcmp( argv[ args ], "-random_framesize" ) == 0 ) {
43451bd803fbdade51d674598ed45da3d54190a656cJohn McCall            check_encoder_option(decode_only, "-random_framesize");
43551bd803fbdade51d674598ed45da3d54190a656cJohn McCall            random_framesize = 1;
436a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall            args++;
43751bd803fbdade51d674598ed45da3d54190a656cJohn McCall        } else if( strcmp( argv[ args ], "-sweep_max" ) == 0 ) {
43851bd803fbdade51d674598ed45da3d54190a656cJohn McCall            check_encoder_option(decode_only, "-sweep_max");
439a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall            sweep_max = atoi( argv[ args + 1 ] );
44049a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall            args += 2;
44149a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall        } else if( strcmp( argv[ args ], "-random_fec" ) == 0 ) {
44249a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall            check_encoder_option(decode_only, "-random_fec");
44349a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall            random_fec = 1;
44451bd803fbdade51d674598ed45da3d54190a656cJohn McCall            args++;
44551bd803fbdade51d674598ed45da3d54190a656cJohn McCall        } else if( strcmp( argv[ args ], "-silk8k_test" ) == 0 ) {
446833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall            check_encoder_option(decode_only, "-silk8k_test");
447833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall            mode_list = silk8_test;
448833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall            nb_modes_in_list = 8;
449833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall            args++;
45044f8c37e378f716e8cbb600e3800f437cf58f9e5Argyrios Kyrtzidis        } else if( strcmp( argv[ args ], "-silk12k_test" ) == 0 ) {
45144f8c37e378f716e8cbb600e3800f437cf58f9e5Argyrios Kyrtzidis            check_encoder_option(decode_only, "-silk12k_test");
452a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall            mode_list = silk12_test;
453465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara            nb_modes_in_list = 8;
454e4da7a034a2fcf4b14d0bcc28d05de0878159061Abramo Bagnara            args++;
455e4da7a034a2fcf4b14d0bcc28d05de0878159061Abramo Bagnara        } else if( strcmp( argv[ args ], "-silk16k_test" ) == 0 ) {
456a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall            check_encoder_option(decode_only, "-silk16k_test");
4573cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall            mode_list = silk16_test;
4583cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall            nb_modes_in_list = 8;
4593cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall            args++;
4604714c12a1ab759156b78be8f109ea4c12213af57Douglas Gregor        } else if( strcmp( argv[ args ], "-hybrid24k_test" ) == 0 ) {
461e4da7a034a2fcf4b14d0bcc28d05de0878159061Abramo Bagnara            check_encoder_option(decode_only, "-hybrid24k_test");
462e4da7a034a2fcf4b14d0bcc28d05de0878159061Abramo Bagnara            mode_list = hybrid24_test;
46351bd803fbdade51d674598ed45da3d54190a656cJohn McCall            nb_modes_in_list = 4;
464a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall            args++;
46533500955d731c73717af52088b7fc0e7a85681e7John McCall        } else if( strcmp( argv[ args ], "-hybrid48k_test" ) == 0 ) {
46633500955d731c73717af52088b7fc0e7a85681e7John McCall            check_encoder_option(decode_only, "-hybrid48k_test");
46733500955d731c73717af52088b7fc0e7a85681e7John McCall            mode_list = hybrid48_test;
46833500955d731c73717af52088b7fc0e7a85681e7John McCall            nb_modes_in_list = 4;
46933500955d731c73717af52088b7fc0e7a85681e7John McCall            args++;
47033500955d731c73717af52088b7fc0e7a85681e7John McCall        } else if( strcmp( argv[ args ], "-celt_test" ) == 0 ) {
47133500955d731c73717af52088b7fc0e7a85681e7John McCall            check_encoder_option(decode_only, "-celt_test");
47233500955d731c73717af52088b7fc0e7a85681e7John McCall            mode_list = celt_test;
47344f8c37e378f716e8cbb600e3800f437cf58f9e5Argyrios Kyrtzidis            nb_modes_in_list = 32;
47444f8c37e378f716e8cbb600e3800f437cf58f9e5Argyrios Kyrtzidis            args++;
47533500955d731c73717af52088b7fc0e7a85681e7John McCall        } else if( strcmp( argv[ args ], "-celt_hq_test" ) == 0 ) {
47651bd803fbdade51d674598ed45da3d54190a656cJohn McCall            check_encoder_option(decode_only, "-celt_hq_test");
47751bd803fbdade51d674598ed45da3d54190a656cJohn McCall            mode_list = celt_hq_test;
478c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall            nb_modes_in_list = 4;
479c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall            args++;
480c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall        } else {
48154e14c4db764c0636160d26c5bbf491637c83a76John McCall            printf( "Error: unrecognized setting: %s\n\n", argv[ args ] );
48254e14c4db764c0636160d26c5bbf491637c83a76John McCall            print_usage( argv );
48354e14c4db764c0636160d26c5bbf491637c83a76John McCall            return EXIT_FAILURE;
48454e14c4db764c0636160d26c5bbf491637c83a76John McCall        }
485a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall    }
48651bd803fbdade51d674598ed45da3d54190a656cJohn McCall
48751bd803fbdade51d674598ed45da3d54190a656cJohn McCall    if (sweep_max)
488a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall       sweep_min = bitrate_bps;
489a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall
4904dcf151a555ff51e4d643e8e6eeb80f121d11d1bChris Lattner    if (max_payload_bytes < 0 || max_payload_bytes > MAX_PACKET)
4912cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    {
4922cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor        fprintf (stderr, "max_payload_bytes must be between 0 and %d\n",
4932cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor                          MAX_PACKET);
494b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner        return EXIT_FAILURE;
495b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    }
496b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner
497b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    inFile = argv[argc-2];
498b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    fin = fopen(inFile, "rb");
499b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    if (!fin)
500b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    {
501b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner        fprintf (stderr, "Could not open input file %s\n", argv[argc-2]);
502b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner        return EXIT_FAILURE;
503b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    }
504b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    if (mode_list)
505b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    {
506b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner       int size;
507b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner       fseek(fin, 0, SEEK_END);
508b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner       size = ftell(fin);
509b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner       fprintf(stderr, "File size is %d bytes\n", size);
510b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner       fseek(fin, 0, SEEK_SET);
511b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner       mode_switch_time = size/sizeof(short)/channels/nb_modes_in_list;
512b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner       fprintf(stderr, "Switching mode every %d samples\n", mode_switch_time);
513b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    }
514b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner
515b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    outFile = argv[argc-1];
516b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    fout = fopen(outFile, "wb+");
5170558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    if (!fout)
5180558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    {
5190558df2da807646e65d4fa290f4e92114af1a746Chris Lattner        fprintf (stderr, "Could not open output file %s\n", argv[argc-1]);
5200558df2da807646e65d4fa290f4e92114af1a746Chris Lattner        fclose(fin);
5210558df2da807646e65d4fa290f4e92114af1a746Chris Lattner        return EXIT_FAILURE;
5220558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    }
5230558df2da807646e65d4fa290f4e92114af1a746Chris Lattner
5240558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    if (!decode_only)
5250558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    {
5260558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       enc = opus_encoder_create(sampling_rate, channels, application, &err);
5270558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       if (err != OPUS_OK)
5280558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       {
5290558df2da807646e65d4fa290f4e92114af1a746Chris Lattner          fprintf(stderr, "Cannot create encoder: %s\n", opus_strerror(err));
5300558df2da807646e65d4fa290f4e92114af1a746Chris Lattner          fclose(fin);
5310558df2da807646e65d4fa290f4e92114af1a746Chris Lattner          fclose(fout);
5320558df2da807646e65d4fa290f4e92114af1a746Chris Lattner          return EXIT_FAILURE;
5330558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       }
5340558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
5350558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bandwidth));
5360558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       opus_encoder_ctl(enc, OPUS_SET_VBR(use_vbr));
5370558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(cvbr));
5380558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity));
5390558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(use_inbandfec));
5400558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(forcechannels));
5410558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       opus_encoder_ctl(enc, OPUS_SET_DTX(use_dtx));
5420558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packet_loss_perc));
5430558df2da807646e65d4fa290f4e92114af1a746Chris Lattner
5440558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&skip));
5450558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       opus_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(16));
5460558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration));
5470558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    }
5480558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    if (!encode_only)
5490558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    {
5500558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       dec = opus_decoder_create(sampling_rate, channels, &err);
5510558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       if (err != OPUS_OK)
5520558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       {
5530558df2da807646e65d4fa290f4e92114af1a746Chris Lattner          fprintf(stderr, "Cannot create decoder: %s\n", opus_strerror(err));
5540558df2da807646e65d4fa290f4e92114af1a746Chris Lattner          fclose(fin);
5550558df2da807646e65d4fa290f4e92114af1a746Chris Lattner          fclose(fout);
5560558df2da807646e65d4fa290f4e92114af1a746Chris Lattner          return EXIT_FAILURE;
5570558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       }
5580558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    }
5590558df2da807646e65d4fa290f4e92114af1a746Chris Lattner
5600558df2da807646e65d4fa290f4e92114af1a746Chris Lattner
5610558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    switch(bandwidth)
5620558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    {
5630558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    case OPUS_BANDWIDTH_NARROWBAND:
5640558df2da807646e65d4fa290f4e92114af1a746Chris Lattner         bandwidth_string = "narrowband";
5650558df2da807646e65d4fa290f4e92114af1a746Chris Lattner         break;
5660558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    case OPUS_BANDWIDTH_MEDIUMBAND:
5670558df2da807646e65d4fa290f4e92114af1a746Chris Lattner         bandwidth_string = "mediumband";
5680558df2da807646e65d4fa290f4e92114af1a746Chris Lattner         break;
5690558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    case OPUS_BANDWIDTH_WIDEBAND:
5700558df2da807646e65d4fa290f4e92114af1a746Chris Lattner         bandwidth_string = "wideband";
5710558df2da807646e65d4fa290f4e92114af1a746Chris Lattner         break;
5720558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    case OPUS_BANDWIDTH_SUPERWIDEBAND:
5730558df2da807646e65d4fa290f4e92114af1a746Chris Lattner         bandwidth_string = "superwideband";
5740558df2da807646e65d4fa290f4e92114af1a746Chris Lattner         break;
5750558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    case OPUS_BANDWIDTH_FULLBAND:
5760558df2da807646e65d4fa290f4e92114af1a746Chris Lattner         bandwidth_string = "fullband";
5770558df2da807646e65d4fa290f4e92114af1a746Chris Lattner         break;
5780558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    case OPUS_AUTO:
5790558df2da807646e65d4fa290f4e92114af1a746Chris Lattner         bandwidth_string = "auto";
5800558df2da807646e65d4fa290f4e92114af1a746Chris Lattner         break;
5810558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    default:
5820558df2da807646e65d4fa290f4e92114af1a746Chris Lattner         bandwidth_string = "unknown";
5830558df2da807646e65d4fa290f4e92114af1a746Chris Lattner         break;
5840558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    }
5850558df2da807646e65d4fa290f4e92114af1a746Chris Lattner
5860558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    if (decode_only)
5870558df2da807646e65d4fa290f4e92114af1a746Chris Lattner       fprintf(stderr, "Decoding with %ld Hz output (%d channels)\n",
588eb7f96141f754150a92433286fa385910a22f494Sam Weinig                       (long)sampling_rate, channels);
589eb7f96141f754150a92433286fa385910a22f494Sam Weinig    else
590eb7f96141f754150a92433286fa385910a22f494Sam Weinig       fprintf(stderr, "Encoding %ld Hz input at %.3f kb/s "
591eb7f96141f754150a92433286fa385910a22f494Sam Weinig                       "in %s mode with %d-sample frames.\n",
592eb7f96141f754150a92433286fa385910a22f494Sam Weinig                       (long)sampling_rate, bitrate_bps*0.001,
593eb7f96141f754150a92433286fa385910a22f494Sam Weinig                       bandwidth_string, frame_size);
594eb7f96141f754150a92433286fa385910a22f494Sam Weinig
595eb7f96141f754150a92433286fa385910a22f494Sam Weinig    in = (short*)malloc(max_frame_size*channels*sizeof(short));
596eb7f96141f754150a92433286fa385910a22f494Sam Weinig    out = (short*)malloc(max_frame_size*channels*sizeof(short));
5970558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    fbytes = (unsigned char*)malloc(max_frame_size*channels*sizeof(short));
598b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    data[0] = (unsigned char*)calloc(max_payload_bytes,sizeof(char));
5991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if ( use_inbandfec ) {
600b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner        data[1] = (unsigned char*)calloc(max_payload_bytes,sizeof(char));
601b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    }
602b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    if(delayed_decision)
6031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    {
6042f4efd10c805cb779618c1a22a35eb07b5043c4eChris Lattner       if (variable_duration!=OPUS_FRAMESIZE_VARIABLE)
605b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner       {
6061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          if (frame_size==sampling_rate/400)
607b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner             variable_duration = OPUS_FRAMESIZE_2_5_MS;
6082f4efd10c805cb779618c1a22a35eb07b5043c4eChris Lattner          else if (frame_size==sampling_rate/200)
60951e774d42269e3b22d746184c0b9076fc13b32e6Zhongxing Xu             variable_duration = OPUS_FRAMESIZE_5_MS;
610b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner          else if (frame_size==sampling_rate/100)
611b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner             variable_duration = OPUS_FRAMESIZE_10_MS;
612b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner          else if (frame_size==sampling_rate/50)
613ab41e63821dc60ad144d0684df8d79a9eef86b75Douglas Gregor             variable_duration = OPUS_FRAMESIZE_20_MS;
614b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner          else if (frame_size==sampling_rate/25)
615b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner             variable_duration = OPUS_FRAMESIZE_40_MS;
616b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner          else
617b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner             variable_duration = OPUS_FRAMESIZE_60_MS;
618b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner          opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration));
619b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner       }
620e6bbc01d1c4ec5241df36042e0a4a12a6711934bTanya Lattner       frame_size = 2*48000;
621b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    }
622b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    while (!stop)
623b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    {
624b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner        if (delayed_celt)
6257f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor        {
6267f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor            frame_size = newsize;
6274fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor            delayed_celt = 0;
628b81c17092039f39be60e9656a37cffbdf2e2c783Douglas Gregor        } else if (random_framesize && rand()%20==0)
6295b4ec636637c9d876102240127cc0dca9280e83aTed Kremenek        {
6306a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor            newsize = rand()%6;
6316a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor            switch(newsize)
632a93e3b5bde9f0a7b59215f19f176f7d69881b81cSebastian Redl            {
633320198303df7c16950d83ae79c3f702b84badcf7Fariborz Jahanian            case 0: newsize=sampling_rate/400; break;
6346a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor            case 1: newsize=sampling_rate/200; break;
635b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            case 2: newsize=sampling_rate/100; break;
6362f4efd10c805cb779618c1a22a35eb07b5043c4eChris Lattner            case 3: newsize=sampling_rate/50; break;
637b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            case 4: newsize=sampling_rate/25; break;
638b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            case 5: newsize=3*sampling_rate/50; break;
639b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            }
640b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            while (newsize < sampling_rate/25 && bitrate_bps-fabs(sweep_bps) <= 3*12*sampling_rate/newsize)
641b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner               newsize*=2;
6421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            if (newsize < sampling_rate/100 && frame_size >= sampling_rate/100)
643b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            {
6442f4efd10c805cb779618c1a22a35eb07b5043c4eChris Lattner                opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
645b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner                delayed_celt=1;
646b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            } else {
647b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner                frame_size = newsize;
6486a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor            }
6496a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor        }
6506a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor        if (random_fec && rand()%30==0)
65161d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor        {
65261d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor           opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(rand()%4==0));
653b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner        }
654b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner        if (decode_only)
655b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner        {
656b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            unsigned char ch[4];
657b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            err = fread(ch, 1, 4, fin);
658b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            if (feof(fin))
659b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner                break;
660b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            len[toggle] = char_to_int(ch);
661b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            if (len[toggle]>max_payload_bytes || len[toggle]<0)
662b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            {
663b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner                fprintf(stderr, "Invalid payload length: %d\n",len[toggle]);
664b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner                break;
665b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            }
666b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            err = fread(ch, 1, 4, fin);
667b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            enc_final_range[toggle] = char_to_int(ch);
668b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            err = fread(data[toggle], 1, len[toggle], fin);
669b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            if (err<len[toggle])
670b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            {
671b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner                fprintf(stderr, "Ran out of input, "
672b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner                                "expecting %d bytes got %d\n",
673a53d2cbe37e4be0d95b9d3e09f74eafae31fc940John McCall                                len[toggle],err);
674d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff                break;
6750ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner            }
6760ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner        } else {
6770ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner            int i;
6780ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner            if (mode_list!=NULL)
6790ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner            {
6800ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner                opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(mode_list[curr_mode][1]));
6810ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner                opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(mode_list[curr_mode][0]));
6820ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner                opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(mode_list[curr_mode][3]));
6830ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner                frame_size = mode_list[curr_mode][2];
6840ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner            }
6850ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner            err = fread(fbytes, sizeof(short)*channels, frame_size-remaining, fin);
6860ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner            curr_read = err;
6870ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner            tot_in += curr_read;
6880ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner            for(i=0;i<curr_read*channels;i++)
6890ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner            {
6900ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner                opus_int32 s;
6910ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner                s=fbytes[2*i+1]<<8|fbytes[2*i];
6920ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner                s=((s&0xFFFF)^0x8000)-0x8000;
6930ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner                in[i+remaining*channels]=s;
6940ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner            }
695b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            if (curr_read+remaining < frame_size)
696b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            {
6970ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner                for (i=(curr_read+remaining)*channels;i<frame_size*channels;i++)
698b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner                   in[i] = 0;
6990ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner                if (encode_only || decode_only)
7000ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner                   stop = 1;
7010ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner            }
7020ff8cda4442cff571aba1be91dd16f64a0bf16aaChris Lattner            len[toggle] = opus_encode(enc, in, frame_size, data[toggle], max_payload_bytes);
70361d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor            nb_encoded = opus_packet_get_samples_per_frame(data[toggle], sampling_rate)*opus_packet_get_nb_frames(data[toggle], len[toggle]);
7040558df2da807646e65d4fa290f4e92114af1a746Chris Lattner            remaining = frame_size-nb_encoded;
705b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            for(i=0;i<remaining*channels;i++)
706b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner               in[i] = in[nb_encoded*channels+i];
707b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            if (sweep_bps!=0)
708b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner            {
709b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner               bitrate_bps += sweep_bps;
710e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor               if (sweep_max)
711e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor               {
7121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                  if (bitrate_bps > sweep_max)
713e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor                     sweep_bps = -sweep_bps;
714e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor                  else if (bitrate_bps < sweep_min)
715e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor                     sweep_bps = -sweep_bps;
716e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor               }
717e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor               /* safety */
718e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor               if (bitrate_bps<1000)
719e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor                  bitrate_bps = 1000;
7201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump               opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
721e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor            }
722e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor            opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range[toggle]));
7231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            if (len[toggle] < 0)
724e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor            {
725e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor                fprintf (stderr, "opus_encode() returned %d\n", len[toggle]);
7261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                fclose(fin);
727e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor                fclose(fout);
728e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor                return EXIT_FAILURE;
729e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor            }
730e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor            curr_mode_count += frame_size;
731e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor            if (curr_mode_count > mode_switch_time && curr_mode < nb_modes_in_list-1)
7321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            {
733e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor               curr_mode++;
734e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor               curr_mode_count = 0;
735e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor            }
7361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        }
737e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor
738e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor#if 0 /* This is for testing the padding code, do not enable by default */
739e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor        if (len[toggle]<1275)
740e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor        {
741e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor           int new_len = len[toggle]+rand()%(max_payload_bytes-len[toggle]);
7421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump           if ((err = opus_packet_pad(data[toggle], len[toggle], new_len)) != OPUS_OK)
743e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor           {
744e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor              fprintf(stderr, "padding failed: %s\n", opus_strerror(err));
745b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner              return EXIT_FAILURE;
746ab41e63821dc60ad144d0684df8d79a9eef86b75Douglas Gregor           }
74730c514c225342844700ed4640ec6d90ddf0e12b2Sebastian Redl           len[toggle] = new_len;
7482bec0410d268779f601bd509e0302a500af7ac6aDouglas Gregor        }
749b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor#endif
750e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor        if (encode_only)
751e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor        {
752e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor            unsigned char int_field[4];
75377f4603c8b142e642300959a601ecec2b7c8e288Sebastian Redl            int_to_char(len[toggle], int_field);
75477f4603c8b142e642300959a601ecec2b7c8e288Sebastian Redl            if (fwrite(int_field, 1, 4, fout) != 4) {
755e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor               fprintf(stderr, "Error writing.\n");
756e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor               return EXIT_FAILURE;
757e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor            }
758e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor            int_to_char(enc_final_range[toggle], int_field);
759e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor            if (fwrite(int_field, 1, 4, fout) != 4) {
76077f4603c8b142e642300959a601ecec2b7c8e288Sebastian Redl               fprintf(stderr, "Error writing.\n");
76177f4603c8b142e642300959a601ecec2b7c8e288Sebastian Redl               return EXIT_FAILURE;
762e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor            }
7631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            if (fwrite(data[toggle], 1, len[toggle], fout) != (unsigned)len[toggle]) {
764e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor               fprintf(stderr, "Error writing.\n");
76577f4603c8b142e642300959a601ecec2b7c8e288Sebastian Redl               return EXIT_FAILURE;
766e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor            }
767e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor            tot_samples += nb_encoded;
768e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor        } else {
769e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor            int output_samples;
770e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor            lost = len[toggle]==0 || (packet_loss_perc>0 && rand()%100 < packet_loss_perc);
77177f4603c8b142e642300959a601ecec2b7c8e288Sebastian Redl            if (lost)
77277f4603c8b142e642300959a601ecec2b7c8e288Sebastian Redl               opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));
77377f4603c8b142e642300959a601ecec2b7c8e288Sebastian Redl            else
7741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump               output_samples = max_frame_size;
775b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor            if( count >= use_inbandfec ) {
776b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor                /* delay by one packet when using in-band FEC */
777b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor                if( use_inbandfec  ) {
778b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor                    if( lost_prev ) {
779b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor                        /* attempt to decode with in-band FEC from next packet */
780b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor                        opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));
781b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor                        output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 1);
782b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor                    } else {
783b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor                        /* regular decode */
7841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                        output_samples = max_frame_size;
78511a18f115e8974ef24e8d5bb549ed3289871efa4Kovarththanan Rajaratnam                        output_samples = opus_decode(dec, data[1-toggle], len[1-toggle], out, output_samples, 0);
786b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor                    }
787aba54a95e9d5e4dc9056abec6bb70ea777c4a7bcKovarththanan Rajaratnam                } else {
7881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 0);
789e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor                }
790b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor                if (output_samples>0)
791b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor                {
792ec312a1f0557b1d27f3eb6cf49acbf7e72696422Daniel Dunbar                    if (!decode_only && tot_out + output_samples > tot_in)
793b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor                    {
79411a18f115e8974ef24e8d5bb549ed3289871efa4Kovarththanan Rajaratnam                       stop=1;
795f7a96a39958b3f919f26764777eec948b43d74bcTed Kremenek                       output_samples  = tot_in-tot_out;
796f7a96a39958b3f919f26764777eec948b43d74bcTed Kremenek                    }
797f7a96a39958b3f919f26764777eec948b43d74bcTed Kremenek                    if (output_samples>skip) {
798f7a96a39958b3f919f26764777eec948b43d74bcTed Kremenek                       int i;
799f7a96a39958b3f919f26764777eec948b43d74bcTed Kremenek                       for(i=0;i<(output_samples-skip)*channels;i++)
800445e23e9b909ec8e21303c7dd82c90b72fc09ac4Douglas Gregor                       {
8015b4ec636637c9d876102240127cc0dca9280e83aTed Kremenek                          short s;
802f7a96a39958b3f919f26764777eec948b43d74bcTed Kremenek                          s=out[i+(skip*channels)];
803f7a96a39958b3f919f26764777eec948b43d74bcTed Kremenek                          fbytes[2*i]=s&0xFF;
8042bec0410d268779f601bd509e0302a500af7ac6aDouglas Gregor                          fbytes[2*i+1]=(s>>8)&0xFF;
8052bec0410d268779f601bd509e0302a500af7ac6aDouglas Gregor                       }
8062bec0410d268779f601bd509e0302a500af7ac6aDouglas Gregor                       if (fwrite(fbytes, sizeof(short)*channels, output_samples-skip, fout) != (unsigned)(output_samples-skip)){
8070a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor                          fprintf(stderr, "Error writing.\n");
8080a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor                          return EXIT_FAILURE;
8090a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor                       }
8100a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor                       tot_out += output_samples-skip;
8110a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor                    }
8120a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor                    if (output_samples<skip) skip -= output_samples;
8130a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor                    else skip = 0;
814eb5d7b752651283de5abfcc2f91df7227582a08dChandler Carruth                } else {
8150a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor                   fprintf(stderr, "error decoding frame: %s\n",
8160a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor                                   opus_strerror(output_samples));
8170a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor                }
8180a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor                tot_samples += output_samples;
8190a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor            }
8200a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor        }
8210a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor
8220a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor        if (!encode_only)
8231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump           opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range));
8240a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor        /* compare final range encoder rng values of encoder and decoder */
8250a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor        if( enc_final_range[toggle^use_inbandfec]!=0  && !encode_only
82611a18f115e8974ef24e8d5bb549ed3289871efa4Kovarththanan Rajaratnam         && !lost && !lost_prev
827412e798941ca64e2e6b084323915fa9aa5f6bdf3Fariborz Jahanian         && dec_final_range != enc_final_range[toggle^use_inbandfec] ) {
82811a18f115e8974ef24e8d5bb549ed3289871efa4Kovarththanan Rajaratnam            fprintf (stderr, "Error: Range coder state mismatch "
829412e798941ca64e2e6b084323915fa9aa5f6bdf3Fariborz Jahanian                             "between encoder and decoder "
8304c9d8d0eca5ca635d9a30222f690db9140e98325Fariborz Jahanian                             "in frame %ld: 0x%8lx vs 0x%8lx\n",
8311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                         (long)count,
8320a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor                         (unsigned long)enc_final_range[toggle^use_inbandfec],
8330a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor                         (unsigned long)dec_final_range);
8340a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor            fclose(fin);
835b9e7e63ae2098bc02e79c032df0a3124d09a4b4eNate Begeman            fclose(fout);
8360a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor            return EXIT_FAILURE;
83773482884560be041d86eccbd7dd5a6918677393bDaniel Dunbar        }
8380a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor
8390a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor        lost_prev = lost;
8400a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor
8410a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor        /* count bits */
8420a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor        bits += len[toggle]*8;
843ea5ce4705df0743093925585d8edc80e0d8fe3ffChris Lattner        bits_max = ( len[toggle]*8 > bits_max ) ? len[toggle]*8 : bits_max;
844ea5ce4705df0743093925585d8edc80e0d8fe3ffChris Lattner        if( count >= use_inbandfec ) {
845972d954bd216c86a961bb7f81c53af85de17c2f0Douglas Gregor            nrg = 0.0;
8460a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor            if (!decode_only)
8470a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor            {
8480a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor                for ( k = 0; k < frame_size * channels; k++ ) {
8490a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor                    nrg += in[ k ] * (double)in[ k ];
8500a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor                }
8510a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor            }
852a4d71455f0d418e16cc0c5c5aa55a3bad3494aeeChris Lattner            if ( ( nrg / ( frame_size * channels ) ) > 1e5 ) {
853a4d71455f0d418e16cc0c5c5aa55a3bad3494aeeChris Lattner                bits_act += len[toggle]*8;
8540a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor                count_act++;
8550a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor            }
8561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            /* Variance */
8570a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor            bits2 += len[toggle]*len[toggle]*64;
8580a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor        }
8590a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor        count++;
8600a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor        toggle = (toggle + use_inbandfec) & 1;
8610a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor    }
8620a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor    fprintf (stderr, "average bitrate:             %7.3f kb/s\n",
8630a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor                     1e-3*bits*sampling_rate/tot_samples);
8640a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor    fprintf (stderr, "maximum bitrate:             %7.3f kb/s\n",
865a33d9b4ebf732a5da6d56fd7319ff6c020789b1cAnders Carlsson                     1e-3*bits_max*sampling_rate/frame_size);
866a33d9b4ebf732a5da6d56fd7319ff6c020789b1cAnders Carlsson    if (!decode_only)
86715b91764d08e886391c865c4a444d7b51141c284Eli Friedman       fprintf (stderr, "active bitrate:              %7.3f kb/s\n",
86815b91764d08e886391c865c4a444d7b51141c284Eli Friedman               1e-3*bits_act*sampling_rate/(frame_size*(double)count_act));
869a6fda124bf380479529d6a80b84b62cacd3cb707John Thompson    fprintf (stderr, "bitrate standard deviation:  %7.3f kb/s\n",
8700a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor            1e-3*sqrt(bits2/count - bits*bits/(count*(double)count))*sampling_rate/frame_size);
8710a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor    /* Close any files to which intermediate results were stored */
872ab8e281b32a3d3b9b18257d26844362bf806ecdcDaniel Dunbar    SILK_DEBUG_STORE_CLOSE_FILES
8730a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor    silk_TimerSave("opus_timing.txt");
874b9e7e63ae2098bc02e79c032df0a3124d09a4b4eNate Begeman    opus_encoder_destroy(enc);
8759c276ae0f24d4cee8f7954069d4b8eae45d0447dMike Stump    opus_decoder_destroy(dec);
87692f5822df6a0d7571df44b5d279ed4f017fbb0e6Anders Carlsson    free(data[0]);
877a0068fc64351db9c47916566e3b85ab733cd8d6dDouglas Gregor    if (use_inbandfec)
878c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor        free(data[1]);
8790a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor    fclose(fin);
8800a0428e96c6f1e8bef7a481a9eb69a6f6df38951Douglas Gregor    fclose(fout);
88114f79002e58556798e86168c63e48d533287eda5Douglas Gregor    free(in);
8824fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor    free(out);
8834fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor    free(fbytes);
8844fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor    return EXIT_SUCCESS;
8854fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor}
8864fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor