1885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Copyright (c) 2007-2008 CSIRO
2885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   Copyright (c) 2007-2009 Xiph.Org Foundation
3885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   Written by Jean-Marc Valin */
4885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*
5885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   Redistribution and use in source and binary forms, with or without
6885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   modification, are permitted provided that the following conditions
7885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   are met:
8885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
9885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   - Redistributions of source code must retain the above copyright
10885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   notice, this list of conditions and the following disclaimer.
11885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
12885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   - Redistributions in binary form must reproduce the above copyright
13885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   notice, this list of conditions and the following disclaimer in the
14885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   documentation and/or other materials provided with the distribution.
15885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
16885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org*/
28885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
29885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef HAVE_CONFIG_H
30885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "config.h"
31885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
32885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
33885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include <stdio.h>
34885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include <stdlib.h>
35885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include <math.h>
36885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include <string.h>
37885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "opus.h"
38885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "debug.h"
39885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "opus_types.h"
40885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "opus_private.h"
41e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "opus_multistream.h"
42885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
43885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define MAX_PACKET 1500
44885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
45885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid print_usage( char* argv[] )
46885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
47885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr, "Usage: %s [-e] <application> <sampling rate (Hz)> <channels (1/2)> "
48885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        "<bits per second>  [options] <input> <output>\n", argv[0]);
49885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr, "       %s -d <sampling rate (Hz)> <channels (1/2)> "
50885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        "[options] <input> <output>\n\n", argv[0]);
51885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr, "mode: voip | audio | restricted-lowdelay\n" );
52885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr, "options:\n" );
53885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr, "-e                   : only runs the encoder (output the bit-stream)\n" );
54885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr, "-d                   : only runs the decoder (reads the bit-stream as input)\n" );
55885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr, "-cbr                 : enable constant bitrate; default: variable bitrate\n" );
56885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr, "-cvbr                : enable constrained variable bitrate; default: unconstrained\n" );
57e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org    fprintf(stderr, "-variable-duration   : enable frames of variable duration (experts only); default: disabled\n" );
58885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr, "-bandwidth <NB|MB|WB|SWB|FB> : audio bandwidth (from narrowband to fullband); default: sampling rate\n" );
59885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr, "-framesize <2.5|5|10|20|40|60> : frame size in ms; default: 20 \n" );
60885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr, "-max_payload <bytes> : maximum payload size in bytes, default: 1024\n" );
61885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr, "-complexity <comp>   : complexity, 0 (lowest) ... 10 (highest); default: 10\n" );
62885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr, "-inbandfec           : enable SILK inband FEC\n" );
63885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr, "-forcemono           : force mono encoding, even for stereo input\n" );
64885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr, "-dtx                 : enable SILK DTX\n" );
65885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr, "-loss <perc>         : simulate packet loss, in percent (0-100); default: 0\n" );
66885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
67885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
68885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void int_to_char(opus_uint32 i, unsigned char ch[4])
69885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
70885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ch[0] = i>>24;
71885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ch[1] = (i>>16)&0xFF;
72885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ch[2] = (i>>8)&0xFF;
73885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ch[3] = i&0xFF;
74885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
75885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
76885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic opus_uint32 char_to_int(unsigned char ch[4])
77885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
78885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    return ((opus_uint32)ch[0]<<24) | ((opus_uint32)ch[1]<<16)
79885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         | ((opus_uint32)ch[2]<< 8) |  (opus_uint32)ch[3];
80885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
81885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
82885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void check_encoder_option(int decode_only, const char *opt)
83885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
84885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (decode_only)
85885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
86885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      fprintf(stderr, "option %s is only for encoding\n", opt);
87885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      exit(EXIT_FAILURE);
88885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
89885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
90885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
916b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.orgstatic const int silk8_test[][4] = {
92885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 1},
93885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 1},
94885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960,   1},
95885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480,   1},
96885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 2},
97885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 2},
98885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960,   2},
99885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480,   2}
100885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org};
101885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1026b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.orgstatic const int silk12_test[][4] = {
103885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 1},
104885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 1},
105885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960,   1},
106885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480,   1},
107885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 2},
108885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 2},
109885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960,   2},
110885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480,   2}
111885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org};
112885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1136b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.orgstatic const int silk16_test[][4] = {
114885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 1},
115885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 1},
116885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960,   1},
117885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480,   1},
118885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 2},
119885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 2},
120885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960,   2},
121885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480,   2}
122885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org};
123885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1246b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.orgstatic const int hybrid24_test[][4] = {
125885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1},
126885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1},
127885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2},
128885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2}
129885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org};
130885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1316b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.orgstatic const int hybrid48_test[][4] = {
132885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 1},
133885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 1},
134885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2},
135885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2}
136885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org};
137885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1386b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.orgstatic const int celt_test[][4] = {
139885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      960, 1},
140885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1},
141885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      960, 1},
142885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    960, 1},
143885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
144885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      480, 1},
145885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1},
146885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      480, 1},
147885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    480, 1},
148885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
149885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      240, 1},
150885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 240, 1},
151885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      240, 1},
152885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    240, 1},
153885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
154885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      120, 1},
155885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 120, 1},
156885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      120, 1},
157885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    120, 1},
158885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
159885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      960, 2},
160885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2},
161885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      960, 2},
162885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    960, 2},
163885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
164885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      480, 2},
165885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2},
166885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      480, 2},
167885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    480, 2},
168885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
169885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      240, 2},
170885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 240, 2},
171885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      240, 2},
172885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    240, 2},
173885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
174885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      120, 2},
175885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 120, 2},
176885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      120, 2},
177885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND,    120, 2},
178885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
179885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org};
180885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1816b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.orgstatic const int celt_hq_test[][4] = {
182885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      960, 2},
183885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      480, 2},
184885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      240, 2},
185885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      120, 2},
186885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org};
187885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
188e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#if 0 /* This is a hack that replaces the normal encoder/decoder with the multistream version */
189e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#define OpusEncoder OpusMSEncoder
190e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#define OpusDecoder OpusMSDecoder
191e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#define opus_encode opus_multistream_encode
192e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#define opus_decode opus_multistream_decode
193e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#define opus_encoder_ctl opus_multistream_encoder_ctl
194e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#define opus_decoder_ctl opus_multistream_decoder_ctl
195e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#define opus_encoder_create ms_opus_encoder_create
196e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#define opus_decoder_create ms_opus_decoder_create
197e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#define opus_encoder_destroy opus_multistream_encoder_destroy
198e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#define opus_decoder_destroy opus_multistream_decoder_destroy
199e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
200e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic OpusEncoder *ms_opus_encoder_create(opus_int32 Fs, int channels, int application, int *error)
201e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{
202e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int streams, coupled_streams;
203e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   unsigned char mapping[256];
204e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   return (OpusEncoder *)opus_multistream_surround_encoder_create(Fs, channels, 1, &streams, &coupled_streams, mapping, application, error);
205e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org}
206e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic OpusDecoder *ms_opus_decoder_create(opus_int32 Fs, int channels, int *error)
207e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{
208e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int streams;
209e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int coupled_streams;
210e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   unsigned char mapping[256]={0,1};
211e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   streams = 1;
212e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   coupled_streams = channels==2;
213e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   return (OpusDecoder *)opus_multistream_decoder_create(Fs, channels, streams, coupled_streams, mapping, error);
214e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org}
215e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif
216e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
217885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgint main(int argc, char *argv[])
218885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
219885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int err;
220885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    char *inFile, *outFile;
221885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    FILE *fin, *fout;
222885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    OpusEncoder *enc=NULL;
223885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    OpusDecoder *dec=NULL;
224885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int args;
225885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int len[2];
226885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int frame_size, channels;
227885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_int32 bitrate_bps=0;
228885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    unsigned char *data[2];
229885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    unsigned char *fbytes;
230885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_int32 sampling_rate;
231885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int use_vbr;
232885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int max_payload_bytes;
233885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int complexity;
234885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int use_inbandfec;
235885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int use_dtx;
236885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int forcechannels;
237885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int cvbr = 0;
238885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int packet_loss_perc;
239885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_int32 count=0, count_act=0;
240885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int k;
241885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_int32 skip=0;
242885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int stop=0;
243885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    short *in, *out;
244885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int application=OPUS_APPLICATION_AUDIO;
245885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    double bits=0.0, bits_max=0.0, bits_act=0.0, bits2=0.0, nrg;
246e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org    double tot_samples=0;
247e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org    opus_uint64 tot_in, tot_out;
248885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int bandwidth=-1;
249885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    const char *bandwidth_string;
250885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int lost = 0, lost_prev = 1;
251885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int toggle = 0;
252885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_uint32 enc_final_range[2];
253885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_uint32 dec_final_range;
254885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int encode_only=0, decode_only=0;
255885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int max_frame_size = 960*6;
256885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int curr_read=0;
257885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int sweep_bps = 0;
258885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int random_framesize=0, newsize=0, delayed_celt=0;
259885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int sweep_max=0, sweep_min=0;
260885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int random_fec=0;
2616b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org    const int (*mode_list)[4]=NULL;
262885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int nb_modes_in_list=0;
263885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int curr_mode=0;
264885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int curr_mode_count=0;
265885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int mode_switch_time = 48000;
266e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org    int nb_encoded=0;
267e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org    int remaining=0;
268e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org    int variable_duration=OPUS_FRAMESIZE_ARG;
269e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org    int delayed_decision=0;
270885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
271885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if (argc < 5 )
272885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    {
273885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       print_usage( argv );
274885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       return EXIT_FAILURE;
275885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
276885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
277e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org    tot_in=tot_out=0;
278885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr, "%s\n", opus_get_version_string());
279885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
280885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    args = 1;
281885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if (strcmp(argv[args], "-e")==0)
282885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    {
283885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        encode_only = 1;
284885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        args++;
285885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    } else if (strcmp(argv[args], "-d")==0)
286885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    {
287885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        decode_only = 1;
288885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        args++;
289885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
290885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if (!decode_only && argc < 7 )
291885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    {
292885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       print_usage( argv );
293885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       return EXIT_FAILURE;
294885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
295885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
296885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if (!decode_only)
297885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    {
298885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       if (strcmp(argv[args], "voip")==0)
299885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          application = OPUS_APPLICATION_VOIP;
300885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       else if (strcmp(argv[args], "restricted-lowdelay")==0)
301885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          application = OPUS_APPLICATION_RESTRICTED_LOWDELAY;
302885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       else if (strcmp(argv[args], "audio")!=0) {
303885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          fprintf(stderr, "unknown application: %s\n", argv[args]);
304885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          print_usage(argv);
305885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          return EXIT_FAILURE;
306885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       }
307885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       args++;
308885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
309885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    sampling_rate = (opus_int32)atol(argv[args]);
310885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    args++;
311885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
312885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if (sampling_rate != 8000 && sampling_rate != 12000
313885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org     && sampling_rate != 16000 && sampling_rate != 24000
314885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org     && sampling_rate != 48000)
315885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    {
316885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        fprintf(stderr, "Supported sampling rates are 8000, 12000, "
317885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                "16000, 24000 and 48000.\n");
318885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        return EXIT_FAILURE;
319885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
320885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    frame_size = sampling_rate/50;
321885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
3223c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com    channels = atoi(argv[args]);
3233c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com    args++;
3243c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com
3253c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com    if (channels < 1 || channels > 2)
3263c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com    {
3273c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com        fprintf(stderr, "Opus_demo supports only 1 or 2 channels.\n");
3283c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com        return EXIT_FAILURE;
3293c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com    }
3303c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com
3313c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com    if (!decode_only)
3323c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com    {
3333c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com       bitrate_bps = (opus_int32)atol(argv[args]);
3343c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com       args++;
3353c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com    }
3363c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com
337885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    /* defaults: */
338885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    use_vbr = 1;
339885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    bandwidth = OPUS_AUTO;
340885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    max_payload_bytes = MAX_PACKET;
341885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    complexity = 10;
342885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    use_inbandfec = 0;
343885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    forcechannels = OPUS_AUTO;
344885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    use_dtx = 0;
345885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    packet_loss_perc = 0;
346e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org    max_frame_size = 2*48000;
347885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    curr_read=0;
348885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
349885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    while( args < argc - 2 ) {
350885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        /* process command line options */
351885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if( strcmp( argv[ args ], "-cbr" ) == 0 ) {
352885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            check_encoder_option(decode_only, "-cbr");
353885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            use_vbr = 0;
354885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args++;
355885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( strcmp( argv[ args ], "-bandwidth" ) == 0 ) {
356885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            check_encoder_option(decode_only, "-bandwidth");
357885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (strcmp(argv[ args + 1 ], "NB")==0)
358885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                bandwidth = OPUS_BANDWIDTH_NARROWBAND;
359885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            else if (strcmp(argv[ args + 1 ], "MB")==0)
360885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
361885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            else if (strcmp(argv[ args + 1 ], "WB")==0)
362885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                bandwidth = OPUS_BANDWIDTH_WIDEBAND;
363885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            else if (strcmp(argv[ args + 1 ], "SWB")==0)
364885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
365885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            else if (strcmp(argv[ args + 1 ], "FB")==0)
366885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                bandwidth = OPUS_BANDWIDTH_FULLBAND;
367885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            else {
368885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                fprintf(stderr, "Unknown bandwidth %s. "
369885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                                "Supported are NB, MB, WB, SWB, FB.\n",
370885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                                argv[ args + 1 ]);
371885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                return EXIT_FAILURE;
372885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
373885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args += 2;
374885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( strcmp( argv[ args ], "-framesize" ) == 0 ) {
375885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            check_encoder_option(decode_only, "-framesize");
376885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (strcmp(argv[ args + 1 ], "2.5")==0)
377885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                frame_size = sampling_rate/400;
378885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            else if (strcmp(argv[ args + 1 ], "5")==0)
379885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                frame_size = sampling_rate/200;
380885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            else if (strcmp(argv[ args + 1 ], "10")==0)
381885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                frame_size = sampling_rate/100;
382885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            else if (strcmp(argv[ args + 1 ], "20")==0)
383885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                frame_size = sampling_rate/50;
384885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            else if (strcmp(argv[ args + 1 ], "40")==0)
385885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                frame_size = sampling_rate/25;
386885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            else if (strcmp(argv[ args + 1 ], "60")==0)
387885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                frame_size = 3*sampling_rate/50;
388885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            else {
389885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                fprintf(stderr, "Unsupported frame size: %s ms. "
390885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                                "Supported are 2.5, 5, 10, 20, 40, 60.\n",
391885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                                argv[ args + 1 ]);
392885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                return EXIT_FAILURE;
393885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
394885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args += 2;
395885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( strcmp( argv[ args ], "-max_payload" ) == 0 ) {
396885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            check_encoder_option(decode_only, "-max_payload");
397885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            max_payload_bytes = atoi( argv[ args + 1 ] );
398885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args += 2;
399885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( strcmp( argv[ args ], "-complexity" ) == 0 ) {
400885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            check_encoder_option(decode_only, "-complexity");
401885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            complexity = atoi( argv[ args + 1 ] );
402885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args += 2;
403885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( strcmp( argv[ args ], "-inbandfec" ) == 0 ) {
404885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            use_inbandfec = 1;
405885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args++;
406885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( strcmp( argv[ args ], "-forcemono" ) == 0 ) {
407885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            check_encoder_option(decode_only, "-forcemono");
408885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            forcechannels = 1;
409885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args++;
410885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( strcmp( argv[ args ], "-cvbr" ) == 0 ) {
411885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            check_encoder_option(decode_only, "-cvbr");
412885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            cvbr = 1;
413885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args++;
414e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org        } else if( strcmp( argv[ args ], "-variable-duration" ) == 0 ) {
415e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            check_encoder_option(decode_only, "-variable-duration");
416e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            variable_duration = OPUS_FRAMESIZE_VARIABLE;
417e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            args++;
418e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org        } else if( strcmp( argv[ args ], "-delayed-decision" ) == 0 ) {
419e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            check_encoder_option(decode_only, "-delayed-decision");
420e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            delayed_decision = 1;
421e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            args++;
422885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( strcmp( argv[ args ], "-dtx") == 0 ) {
423885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            check_encoder_option(decode_only, "-dtx");
424885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            use_dtx = 1;
425885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args++;
426885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( strcmp( argv[ args ], "-loss" ) == 0 ) {
427885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            packet_loss_perc = atoi( argv[ args + 1 ] );
428885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args += 2;
429885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( strcmp( argv[ args ], "-sweep" ) == 0 ) {
430885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            check_encoder_option(decode_only, "-sweep");
431885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            sweep_bps = atoi( argv[ args + 1 ] );
432885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args += 2;
433885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( strcmp( argv[ args ], "-random_framesize" ) == 0 ) {
434885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            check_encoder_option(decode_only, "-random_framesize");
435885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            random_framesize = 1;
436885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args++;
437885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( strcmp( argv[ args ], "-sweep_max" ) == 0 ) {
438885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            check_encoder_option(decode_only, "-sweep_max");
439885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            sweep_max = atoi( argv[ args + 1 ] );
440885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args += 2;
441885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( strcmp( argv[ args ], "-random_fec" ) == 0 ) {
442885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            check_encoder_option(decode_only, "-random_fec");
443885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            random_fec = 1;
444885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args++;
445885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( strcmp( argv[ args ], "-silk8k_test" ) == 0 ) {
446885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            check_encoder_option(decode_only, "-silk8k_test");
447885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            mode_list = silk8_test;
448885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            nb_modes_in_list = 8;
449885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args++;
450885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( strcmp( argv[ args ], "-silk12k_test" ) == 0 ) {
451885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            check_encoder_option(decode_only, "-silk12k_test");
452885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            mode_list = silk12_test;
453885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            nb_modes_in_list = 8;
454885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args++;
455885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( strcmp( argv[ args ], "-silk16k_test" ) == 0 ) {
456885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            check_encoder_option(decode_only, "-silk16k_test");
457885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            mode_list = silk16_test;
458885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            nb_modes_in_list = 8;
459885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args++;
460885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( strcmp( argv[ args ], "-hybrid24k_test" ) == 0 ) {
461885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            check_encoder_option(decode_only, "-hybrid24k_test");
462885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            mode_list = hybrid24_test;
463885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            nb_modes_in_list = 4;
464885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args++;
465885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( strcmp( argv[ args ], "-hybrid48k_test" ) == 0 ) {
466885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            check_encoder_option(decode_only, "-hybrid48k_test");
467885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            mode_list = hybrid48_test;
468885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            nb_modes_in_list = 4;
469885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args++;
470885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( strcmp( argv[ args ], "-celt_test" ) == 0 ) {
471885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            check_encoder_option(decode_only, "-celt_test");
472885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            mode_list = celt_test;
473885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            nb_modes_in_list = 32;
474885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args++;
475885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( strcmp( argv[ args ], "-celt_hq_test" ) == 0 ) {
476885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            check_encoder_option(decode_only, "-celt_hq_test");
477885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            mode_list = celt_hq_test;
478885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            nb_modes_in_list = 4;
479885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            args++;
480885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else {
481885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            printf( "Error: unrecognized setting: %s\n\n", argv[ args ] );
482885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            print_usage( argv );
483885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            return EXIT_FAILURE;
484885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
485885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
486885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
487885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if (sweep_max)
488885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       sweep_min = bitrate_bps;
489885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
490885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if (max_payload_bytes < 0 || max_payload_bytes > MAX_PACKET)
491885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    {
492885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        fprintf (stderr, "max_payload_bytes must be between 0 and %d\n",
493885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                          MAX_PACKET);
494885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        return EXIT_FAILURE;
495885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
496885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
497885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    inFile = argv[argc-2];
498885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fin = fopen(inFile, "rb");
499885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if (!fin)
500885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    {
501885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        fprintf (stderr, "Could not open input file %s\n", argv[argc-2]);
502885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        return EXIT_FAILURE;
503885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
504885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if (mode_list)
505885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    {
506885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       int size;
507885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       fseek(fin, 0, SEEK_END);
508885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       size = ftell(fin);
509885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       fprintf(stderr, "File size is %d bytes\n", size);
510885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       fseek(fin, 0, SEEK_SET);
511885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       mode_switch_time = size/sizeof(short)/channels/nb_modes_in_list;
512885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       fprintf(stderr, "Switching mode every %d samples\n", mode_switch_time);
513885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
514885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
515885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    outFile = argv[argc-1];
516885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fout = fopen(outFile, "wb+");
517885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if (!fout)
518885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    {
519885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        fprintf (stderr, "Could not open output file %s\n", argv[argc-1]);
520885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        fclose(fin);
521885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        return EXIT_FAILURE;
522885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
523885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
524885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if (!decode_only)
525885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    {
526885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       enc = opus_encoder_create(sampling_rate, channels, application, &err);
527885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       if (err != OPUS_OK)
528885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       {
529885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          fprintf(stderr, "Cannot create encoder: %s\n", opus_strerror(err));
530885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          fclose(fin);
531885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          fclose(fout);
532885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          return EXIT_FAILURE;
533885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       }
534885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
535885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bandwidth));
536885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       opus_encoder_ctl(enc, OPUS_SET_VBR(use_vbr));
537885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(cvbr));
538885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity));
539885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(use_inbandfec));
540885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(forcechannels));
541885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       opus_encoder_ctl(enc, OPUS_SET_DTX(use_dtx));
542885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packet_loss_perc));
543885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
544885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&skip));
545885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       opus_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(16));
546e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org       opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration));
547885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
548885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if (!encode_only)
549885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    {
550885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       dec = opus_decoder_create(sampling_rate, channels, &err);
551885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       if (err != OPUS_OK)
552885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       {
553885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          fprintf(stderr, "Cannot create decoder: %s\n", opus_strerror(err));
554885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          fclose(fin);
555885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          fclose(fout);
556885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          return EXIT_FAILURE;
557885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       }
558885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
559885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
560885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
561885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    switch(bandwidth)
562885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    {
563885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    case OPUS_BANDWIDTH_NARROWBAND:
564885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         bandwidth_string = "narrowband";
565885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         break;
566885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    case OPUS_BANDWIDTH_MEDIUMBAND:
567885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         bandwidth_string = "mediumband";
568885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         break;
569885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    case OPUS_BANDWIDTH_WIDEBAND:
570885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         bandwidth_string = "wideband";
571885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         break;
572885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    case OPUS_BANDWIDTH_SUPERWIDEBAND:
573885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         bandwidth_string = "superwideband";
574885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         break;
575885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    case OPUS_BANDWIDTH_FULLBAND:
576885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         bandwidth_string = "fullband";
577885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         break;
578885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    case OPUS_AUTO:
579885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         bandwidth_string = "auto";
580885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         break;
581885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    default:
582885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         bandwidth_string = "unknown";
583885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         break;
584885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
585885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
586885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if (decode_only)
587885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       fprintf(stderr, "Decoding with %ld Hz output (%d channels)\n",
588885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                       (long)sampling_rate, channels);
589885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    else
590885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       fprintf(stderr, "Encoding %ld Hz input at %.3f kb/s "
591885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                       "in %s mode with %d-sample frames.\n",
592885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                       (long)sampling_rate, bitrate_bps*0.001,
593885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                       bandwidth_string, frame_size);
594885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
595885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    in = (short*)malloc(max_frame_size*channels*sizeof(short));
596885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    out = (short*)malloc(max_frame_size*channels*sizeof(short));
597885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fbytes = (unsigned char*)malloc(max_frame_size*channels*sizeof(short));
598885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    data[0] = (unsigned char*)calloc(max_payload_bytes,sizeof(char));
599885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if ( use_inbandfec ) {
600885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        data[1] = (unsigned char*)calloc(max_payload_bytes,sizeof(char));
601885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
602e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org    if(delayed_decision)
603e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org    {
604e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org       if (variable_duration!=OPUS_FRAMESIZE_VARIABLE)
605e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org       {
606e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org          if (frame_size==sampling_rate/400)
607e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org             variable_duration = OPUS_FRAMESIZE_2_5_MS;
608e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org          else if (frame_size==sampling_rate/200)
609e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org             variable_duration = OPUS_FRAMESIZE_5_MS;
610e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org          else if (frame_size==sampling_rate/100)
611e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org             variable_duration = OPUS_FRAMESIZE_10_MS;
612e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org          else if (frame_size==sampling_rate/50)
613e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org             variable_duration = OPUS_FRAMESIZE_20_MS;
614e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org          else if (frame_size==sampling_rate/25)
615e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org             variable_duration = OPUS_FRAMESIZE_40_MS;
616e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org          else
617e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org             variable_duration = OPUS_FRAMESIZE_60_MS;
618e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org          opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration));
619e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org       }
620e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org       frame_size = 2*48000;
621e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org    }
622885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    while (!stop)
623885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    {
624885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if (delayed_celt)
625885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        {
626885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            frame_size = newsize;
627885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            delayed_celt = 0;
628885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if (random_framesize && rand()%20==0)
629885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        {
630885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            newsize = rand()%6;
631885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            switch(newsize)
632885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            {
633885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            case 0: newsize=sampling_rate/400; break;
634885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            case 1: newsize=sampling_rate/200; break;
635885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            case 2: newsize=sampling_rate/100; break;
636885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            case 3: newsize=sampling_rate/50; break;
637885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            case 4: newsize=sampling_rate/25; break;
638885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            case 5: newsize=3*sampling_rate/50; break;
639885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
640885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            while (newsize < sampling_rate/25 && bitrate_bps-fabs(sweep_bps) <= 3*12*sampling_rate/newsize)
641885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               newsize*=2;
642885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (newsize < sampling_rate/100 && frame_size >= sampling_rate/100)
643885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            {
644885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
645885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                delayed_celt=1;
646885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            } else {
647885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                frame_size = newsize;
648885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
649885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
650885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if (random_fec && rand()%30==0)
651885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        {
652885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org           opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(rand()%4==0));
653885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
654885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if (decode_only)
655885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        {
656885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            unsigned char ch[4];
657885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            err = fread(ch, 1, 4, fin);
658885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (feof(fin))
659885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                break;
660885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            len[toggle] = char_to_int(ch);
661885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (len[toggle]>max_payload_bytes || len[toggle]<0)
662885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            {
663885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                fprintf(stderr, "Invalid payload length: %d\n",len[toggle]);
664885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                break;
665885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
666885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            err = fread(ch, 1, 4, fin);
667885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            enc_final_range[toggle] = char_to_int(ch);
668885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            err = fread(data[toggle], 1, len[toggle], fin);
669885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (err<len[toggle])
670885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            {
671885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                fprintf(stderr, "Ran out of input, "
672885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                                "expecting %d bytes got %d\n",
673885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                                len[toggle],err);
674885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                break;
675885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
676885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else {
677885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            int i;
678885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (mode_list!=NULL)
679885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            {
680885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(mode_list[curr_mode][1]));
681885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(mode_list[curr_mode][0]));
682885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(mode_list[curr_mode][3]));
683885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                frame_size = mode_list[curr_mode][2];
684885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
685e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            err = fread(fbytes, sizeof(short)*channels, frame_size-remaining, fin);
686885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            curr_read = err;
687e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            tot_in += curr_read;
688885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            for(i=0;i<curr_read*channels;i++)
689885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            {
690885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                opus_int32 s;
691885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                s=fbytes[2*i+1]<<8|fbytes[2*i];
692885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                s=((s&0xFFFF)^0x8000)-0x8000;
693e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                in[i+remaining*channels]=s;
694885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
695e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            if (curr_read+remaining < frame_size)
696885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            {
697e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                for (i=(curr_read+remaining)*channels;i<frame_size*channels;i++)
698885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                   in[i] = 0;
699e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                if (encode_only || decode_only)
700e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                   stop = 1;
701885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
702885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            len[toggle] = opus_encode(enc, in, frame_size, data[toggle], max_payload_bytes);
703e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            nb_encoded = opus_packet_get_samples_per_frame(data[toggle], sampling_rate)*opus_packet_get_nb_frames(data[toggle], len[toggle]);
704e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            remaining = frame_size-nb_encoded;
705e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            for(i=0;i<remaining*channels;i++)
706e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               in[i] = in[nb_encoded*channels+i];
707885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (sweep_bps!=0)
708885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            {
709885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               bitrate_bps += sweep_bps;
710885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               if (sweep_max)
711885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               {
712885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  if (bitrate_bps > sweep_max)
713885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     sweep_bps = -sweep_bps;
714885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  else if (bitrate_bps < sweep_min)
715885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     sweep_bps = -sweep_bps;
716885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               }
717885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               /* safety */
718885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               if (bitrate_bps<1000)
719885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  bitrate_bps = 1000;
720885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
721885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
722885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range[toggle]));
723885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (len[toggle] < 0)
724885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            {
725885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                fprintf (stderr, "opus_encode() returned %d\n", len[toggle]);
726885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                fclose(fin);
727885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                fclose(fout);
728885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                return EXIT_FAILURE;
729885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
730885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            curr_mode_count += frame_size;
731885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (curr_mode_count > mode_switch_time && curr_mode < nb_modes_in_list-1)
732885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            {
733885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               curr_mode++;
734885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               curr_mode_count = 0;
735885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
736885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
737885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
7383c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com#if 0 /* This is for testing the padding code, do not enable by default */
7393c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com        if (len[toggle]<1275)
7403c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com        {
7413c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com           int new_len = len[toggle]+rand()%(max_payload_bytes-len[toggle]);
7423c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com           if ((err = opus_packet_pad(data[toggle], len[toggle], new_len)) != OPUS_OK)
7433c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com           {
7443c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com              fprintf(stderr, "padding failed: %s\n", opus_strerror(err));
7453c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com              return EXIT_FAILURE;
7463c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com           }
7473c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com           len[toggle] = new_len;
7483c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com        }
7493c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com#endif
750885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if (encode_only)
751885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        {
752885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            unsigned char int_field[4];
753885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            int_to_char(len[toggle], int_field);
754885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (fwrite(int_field, 1, 4, fout) != 4) {
755885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               fprintf(stderr, "Error writing.\n");
756885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               return EXIT_FAILURE;
757885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
758885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            int_to_char(enc_final_range[toggle], int_field);
759885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (fwrite(int_field, 1, 4, fout) != 4) {
760885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               fprintf(stderr, "Error writing.\n");
761885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               return EXIT_FAILURE;
762885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
763885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (fwrite(data[toggle], 1, len[toggle], fout) != (unsigned)len[toggle]) {
764885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               fprintf(stderr, "Error writing.\n");
765885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               return EXIT_FAILURE;
766885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
767e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            tot_samples += nb_encoded;
768885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else {
769885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            int output_samples;
770885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            lost = len[toggle]==0 || (packet_loss_perc>0 && rand()%100 < packet_loss_perc);
7716b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org            if (lost)
7726b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org               opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));
7736b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org            else
7746b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org               output_samples = max_frame_size;
775885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if( count >= use_inbandfec ) {
776885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                /* delay by one packet when using in-band FEC */
777885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                if( use_inbandfec  ) {
778885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    if( lost_prev ) {
779885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        /* attempt to decode with in-band FEC from next packet */
780e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                        opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));
7816b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org                        output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 1);
782885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    } else {
783885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        /* regular decode */
784e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                        output_samples = max_frame_size;
7856b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org                        output_samples = opus_decode(dec, data[1-toggle], len[1-toggle], out, output_samples, 0);
786885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    }
787885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                } else {
7886b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org                    output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 0);
789885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                }
790885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                if (output_samples>0)
791885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                {
792e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                    if (!decode_only && tot_out + output_samples > tot_in)
793e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                    {
794e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                       stop=1;
795e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                       output_samples  = tot_in-tot_out;
796e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                    }
797885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    if (output_samples>skip) {
798885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                       int i;
799885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                       for(i=0;i<(output_samples-skip)*channels;i++)
800885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                       {
801885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                          short s;
802885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                          s=out[i+(skip*channels)];
803885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                          fbytes[2*i]=s&0xFF;
804885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                          fbytes[2*i+1]=(s>>8)&0xFF;
805885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                       }
806885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                       if (fwrite(fbytes, sizeof(short)*channels, output_samples-skip, fout) != (unsigned)(output_samples-skip)){
807885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                          fprintf(stderr, "Error writing.\n");
808885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                          return EXIT_FAILURE;
809885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                       }
810e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                       tot_out += output_samples-skip;
811885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    }
812885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    if (output_samples<skip) skip -= output_samples;
813885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    else skip = 0;
814885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                } else {
815885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                   fprintf(stderr, "error decoding frame: %s\n",
816885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                                   opus_strerror(output_samples));
817885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                }
818e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                tot_samples += output_samples;
819885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
820885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
821885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
822885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if (!encode_only)
823885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org           opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range));
824885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        /* compare final range encoder rng values of encoder and decoder */
825885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if( enc_final_range[toggle^use_inbandfec]!=0  && !encode_only
826885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         && !lost && !lost_prev
827885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         && dec_final_range != enc_final_range[toggle^use_inbandfec] ) {
828885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            fprintf (stderr, "Error: Range coder state mismatch "
829885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                             "between encoder and decoder "
830885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                             "in frame %ld: 0x%8lx vs 0x%8lx\n",
831885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                         (long)count,
832885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                         (unsigned long)enc_final_range[toggle^use_inbandfec],
833885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                         (unsigned long)dec_final_range);
834885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            fclose(fin);
835885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            fclose(fout);
836885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            return EXIT_FAILURE;
837885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
838885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
839885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        lost_prev = lost;
840885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
841885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        /* count bits */
842885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        bits += len[toggle]*8;
843885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        bits_max = ( len[toggle]*8 > bits_max ) ? len[toggle]*8 : bits_max;
844885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if( count >= use_inbandfec ) {
845885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            nrg = 0.0;
846885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (!decode_only)
847885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            {
848885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                for ( k = 0; k < frame_size * channels; k++ ) {
849885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    nrg += in[ k ] * (double)in[ k ];
850885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                }
851885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
852885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if ( ( nrg / ( frame_size * channels ) ) > 1e5 ) {
853885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                bits_act += len[toggle]*8;
854885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                count_act++;
855885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
856885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /* Variance */
857885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            bits2 += len[toggle]*len[toggle]*64;
858885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
859885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        count++;
860885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        toggle = (toggle + use_inbandfec) & 1;
861885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
862885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf (stderr, "average bitrate:             %7.3f kb/s\n",
863e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                     1e-3*bits*sampling_rate/tot_samples);
864885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf (stderr, "maximum bitrate:             %7.3f kb/s\n",
865885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     1e-3*bits_max*sampling_rate/frame_size);
866885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if (!decode_only)
867885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       fprintf (stderr, "active bitrate:              %7.3f kb/s\n",
868885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               1e-3*bits_act*sampling_rate/(frame_size*(double)count_act));
869885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf (stderr, "bitrate standard deviation:  %7.3f kb/s\n",
870885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            1e-3*sqrt(bits2/count - bits*bits/(count*(double)count))*sampling_rate/frame_size);
871885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    /* Close any files to which intermediate results were stored */
872885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    SILK_DEBUG_STORE_CLOSE_FILES
873885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    silk_TimerSave("opus_timing.txt");
874885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_encoder_destroy(enc);
875885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_decoder_destroy(dec);
876885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    free(data[0]);
877885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if (use_inbandfec)
878885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        free(data[1]);
879885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fclose(fin);
880885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fclose(fout);
881885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    free(in);
882885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    free(out);
883885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    free(fbytes);
884885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    return EXIT_SUCCESS;
885885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
886