1*a58d3d2aSXin Li /* Copyright (c) 2007-2008 CSIRO
2*a58d3d2aSXin Li Copyright (c) 2007-2009 Xiph.Org Foundation
3*a58d3d2aSXin Li Written by Jean-Marc Valin */
4*a58d3d2aSXin Li /*
5*a58d3d2aSXin Li Redistribution and use in source and binary forms, with or without
6*a58d3d2aSXin Li modification, are permitted provided that the following conditions
7*a58d3d2aSXin Li are met:
8*a58d3d2aSXin Li
9*a58d3d2aSXin Li - Redistributions of source code must retain the above copyright
10*a58d3d2aSXin Li notice, this list of conditions and the following disclaimer.
11*a58d3d2aSXin Li
12*a58d3d2aSXin Li - Redistributions in binary form must reproduce the above copyright
13*a58d3d2aSXin Li notice, this list of conditions and the following disclaimer in the
14*a58d3d2aSXin Li documentation and/or other materials provided with the distribution.
15*a58d3d2aSXin Li
16*a58d3d2aSXin Li THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17*a58d3d2aSXin Li ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18*a58d3d2aSXin Li LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19*a58d3d2aSXin Li A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20*a58d3d2aSXin Li OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21*a58d3d2aSXin Li EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22*a58d3d2aSXin Li PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23*a58d3d2aSXin Li PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24*a58d3d2aSXin Li LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25*a58d3d2aSXin Li NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26*a58d3d2aSXin Li SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*a58d3d2aSXin Li */
28*a58d3d2aSXin Li
29*a58d3d2aSXin Li #ifdef HAVE_CONFIG_H
30*a58d3d2aSXin Li #include "config.h"
31*a58d3d2aSXin Li #endif
32*a58d3d2aSXin Li
33*a58d3d2aSXin Li #include <stdio.h>
34*a58d3d2aSXin Li #include <stdlib.h>
35*a58d3d2aSXin Li #include <math.h>
36*a58d3d2aSXin Li #include <string.h>
37*a58d3d2aSXin Li #include "opus.h"
38*a58d3d2aSXin Li #include "debug.h"
39*a58d3d2aSXin Li #include "opus_types.h"
40*a58d3d2aSXin Li #include "opus_private.h"
41*a58d3d2aSXin Li #include "opus_multistream.h"
42*a58d3d2aSXin Li #ifdef ENABLE_LOSSGEN
43*a58d3d2aSXin Li #include "lossgen.h"
44*a58d3d2aSXin Li #endif
45*a58d3d2aSXin Li
46*a58d3d2aSXin Li #define MAX_PACKET 1500
47*a58d3d2aSXin Li
48*a58d3d2aSXin Li #ifdef USE_WEIGHTS_FILE
49*a58d3d2aSXin Li # if __unix__
50*a58d3d2aSXin Li # include <fcntl.h>
51*a58d3d2aSXin Li # include <sys/mman.h>
52*a58d3d2aSXin Li # include <unistd.h>
53*a58d3d2aSXin Li # include <sys/stat.h>
54*a58d3d2aSXin Li /* When available, mmap() is preferable to reading the file, as it leads to
55*a58d3d2aSXin Li better resource utilization, especially if multiple processes are using the same
56*a58d3d2aSXin Li file (mapping will be shared in cache). */
load_blob(const char * filename,int * len)57*a58d3d2aSXin Li void *load_blob(const char *filename, int *len) {
58*a58d3d2aSXin Li int fd;
59*a58d3d2aSXin Li void *data;
60*a58d3d2aSXin Li struct stat st;
61*a58d3d2aSXin Li if (stat(filename, &st)) {
62*a58d3d2aSXin Li *len = 0;
63*a58d3d2aSXin Li return NULL;
64*a58d3d2aSXin Li }
65*a58d3d2aSXin Li *len = st.st_size;
66*a58d3d2aSXin Li fd = open(filename, O_RDONLY);
67*a58d3d2aSXin Li if (fd<0) {
68*a58d3d2aSXin Li *len = 0;
69*a58d3d2aSXin Li return NULL;
70*a58d3d2aSXin Li }
71*a58d3d2aSXin Li data = mmap(NULL, *len, PROT_READ, MAP_SHARED, fd, 0);
72*a58d3d2aSXin Li if (data == MAP_FAILED) {
73*a58d3d2aSXin Li *len = 0;
74*a58d3d2aSXin Li data = NULL;
75*a58d3d2aSXin Li }
76*a58d3d2aSXin Li close(fd);
77*a58d3d2aSXin Li return data;
78*a58d3d2aSXin Li }
free_blob(void * blob,int len)79*a58d3d2aSXin Li void free_blob(void *blob, int len) {
80*a58d3d2aSXin Li if (blob) munmap(blob, len);
81*a58d3d2aSXin Li }
82*a58d3d2aSXin Li # else
load_blob(const char * filename,int * len)83*a58d3d2aSXin Li void *load_blob(const char *filename, int *len) {
84*a58d3d2aSXin Li FILE *file;
85*a58d3d2aSXin Li void *data;
86*a58d3d2aSXin Li file = fopen(filename, "r");
87*a58d3d2aSXin Li if (file == NULL)
88*a58d3d2aSXin Li {
89*a58d3d2aSXin Li perror("could not open blob file");
90*a58d3d2aSXin Li *len = 0;
91*a58d3d2aSXin Li return NULL;
92*a58d3d2aSXin Li }
93*a58d3d2aSXin Li fseek(file, 0L, SEEK_END);
94*a58d3d2aSXin Li *len = ftell(file);
95*a58d3d2aSXin Li fseek(file, 0L, SEEK_SET);
96*a58d3d2aSXin Li if (*len <= 0) {
97*a58d3d2aSXin Li *len = 0;
98*a58d3d2aSXin Li return NULL;
99*a58d3d2aSXin Li }
100*a58d3d2aSXin Li data = malloc(*len);
101*a58d3d2aSXin Li if (!data) {
102*a58d3d2aSXin Li *len = 0;
103*a58d3d2aSXin Li return NULL;
104*a58d3d2aSXin Li }
105*a58d3d2aSXin Li *len = fread(data, 1, *len, file);
106*a58d3d2aSXin Li return data;
107*a58d3d2aSXin Li }
free_blob(void * blob,int len)108*a58d3d2aSXin Li void free_blob(void *blob, int len) {
109*a58d3d2aSXin Li free(blob);
110*a58d3d2aSXin Li (void)len;
111*a58d3d2aSXin Li }
112*a58d3d2aSXin Li # endif
113*a58d3d2aSXin Li #endif
114*a58d3d2aSXin Li
115*a58d3d2aSXin Li
print_usage(char * argv[])116*a58d3d2aSXin Li void print_usage( char* argv[] )
117*a58d3d2aSXin Li {
118*a58d3d2aSXin Li fprintf(stderr, "Usage: %s [-e] <application> <sampling rate (Hz)> <channels (1/2)> "
119*a58d3d2aSXin Li "<bits per second> [options] <input> <output>\n", argv[0]);
120*a58d3d2aSXin Li fprintf(stderr, " %s -d <sampling rate (Hz)> <channels (1/2)> "
121*a58d3d2aSXin Li "[options] <input> <output>\n\n", argv[0]);
122*a58d3d2aSXin Li fprintf(stderr, "application: voip | audio | restricted-lowdelay\n" );
123*a58d3d2aSXin Li fprintf(stderr, "options:\n" );
124*a58d3d2aSXin Li fprintf(stderr, "-e : only runs the encoder (output the bit-stream)\n" );
125*a58d3d2aSXin Li fprintf(stderr, "-d : only runs the decoder (reads the bit-stream as input)\n" );
126*a58d3d2aSXin Li fprintf(stderr, "-cbr : enable constant bitrate; default: variable bitrate\n" );
127*a58d3d2aSXin Li fprintf(stderr, "-cvbr : enable constrained variable bitrate; default: unconstrained\n" );
128*a58d3d2aSXin Li fprintf(stderr, "-delayed-decision : use look-ahead for speech/music detection (experts only); default: disabled\n" );
129*a58d3d2aSXin Li fprintf(stderr, "-bandwidth <NB|MB|WB|SWB|FB> : audio bandwidth (from narrowband to fullband); default: sampling rate\n" );
130*a58d3d2aSXin Li fprintf(stderr, "-framesize <2.5|5|10|20|40|60|80|100|120> : frame size in ms; default: 20 \n" );
131*a58d3d2aSXin Li fprintf(stderr, "-max_payload <bytes> : maximum payload size in bytes, default: 1024\n" );
132*a58d3d2aSXin Li fprintf(stderr, "-complexity <comp> : encoder complexity, 0 (lowest) ... 10 (highest); default: 10\n" );
133*a58d3d2aSXin Li fprintf(stderr, "-dec_complexity <comp> : decoder complexity, 0 (lowest) ... 10 (highest); default: 0\n" );
134*a58d3d2aSXin Li fprintf(stderr, "-inbandfec : enable SILK inband FEC\n" );
135*a58d3d2aSXin Li fprintf(stderr, "-forcemono : force mono encoding, even for stereo input\n" );
136*a58d3d2aSXin Li fprintf(stderr, "-dtx : enable SILK DTX\n" );
137*a58d3d2aSXin Li fprintf(stderr, "-loss <perc> : optimize for loss percentage and simulate packet loss, in percent (0-100); default: 0\n" );
138*a58d3d2aSXin Li #ifdef ENABLE_LOSSGEN
139*a58d3d2aSXin Li fprintf(stderr, "-sim_loss <perc> : simulate realistic (bursty) packet loss from percentage, using generative model\n" );
140*a58d3d2aSXin Li #endif
141*a58d3d2aSXin Li fprintf(stderr, "-lossfile <file> : simulate packet loss, reading loss from file\n" );
142*a58d3d2aSXin Li fprintf(stderr, "-dred <frames> : add Deep REDundancy (in units of 10-ms frames)\n" );
143*a58d3d2aSXin Li }
144*a58d3d2aSXin Li
int_to_char(opus_uint32 i,unsigned char ch[4])145*a58d3d2aSXin Li static void int_to_char(opus_uint32 i, unsigned char ch[4])
146*a58d3d2aSXin Li {
147*a58d3d2aSXin Li ch[0] = i>>24;
148*a58d3d2aSXin Li ch[1] = (i>>16)&0xFF;
149*a58d3d2aSXin Li ch[2] = (i>>8)&0xFF;
150*a58d3d2aSXin Li ch[3] = i&0xFF;
151*a58d3d2aSXin Li }
152*a58d3d2aSXin Li
char_to_int(unsigned char ch[4])153*a58d3d2aSXin Li static opus_uint32 char_to_int(unsigned char ch[4])
154*a58d3d2aSXin Li {
155*a58d3d2aSXin Li return ((opus_uint32)ch[0]<<24) | ((opus_uint32)ch[1]<<16)
156*a58d3d2aSXin Li | ((opus_uint32)ch[2]<< 8) | (opus_uint32)ch[3];
157*a58d3d2aSXin Li }
158*a58d3d2aSXin Li
159*a58d3d2aSXin Li #define check_encoder_option(decode_only, opt) do {if (decode_only) {fprintf(stderr, "option %s is only for encoding\n", opt); goto failure;}} while(0)
160*a58d3d2aSXin Li #define check_decoder_option(encode_only, opt) do {if (encode_only) {fprintf(stderr, "option %s is only for decoding\n", opt); goto failure;}} while(0)
161*a58d3d2aSXin Li
162*a58d3d2aSXin Li static const int silk8_test[][4] = {
163*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 1},
164*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 1},
165*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 1},
166*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 1},
167*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 2},
168*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 2},
169*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 2},
170*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 2}
171*a58d3d2aSXin Li };
172*a58d3d2aSXin Li
173*a58d3d2aSXin Li static const int silk12_test[][4] = {
174*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 1},
175*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 1},
176*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960, 1},
177*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480, 1},
178*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 2},
179*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 2},
180*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960, 2},
181*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480, 2}
182*a58d3d2aSXin Li };
183*a58d3d2aSXin Li
184*a58d3d2aSXin Li static const int silk16_test[][4] = {
185*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 1},
186*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 1},
187*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 1},
188*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 1},
189*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 2},
190*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 2},
191*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 2},
192*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 2}
193*a58d3d2aSXin Li };
194*a58d3d2aSXin Li
195*a58d3d2aSXin Li static const int hybrid24_test[][4] = {
196*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1},
197*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1},
198*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2},
199*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2}
200*a58d3d2aSXin Li };
201*a58d3d2aSXin Li
202*a58d3d2aSXin Li static const int hybrid48_test[][4] = {
203*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 1},
204*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 1},
205*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2},
206*a58d3d2aSXin Li {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2}
207*a58d3d2aSXin Li };
208*a58d3d2aSXin Li
209*a58d3d2aSXin Li static const int celt_test[][4] = {
210*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 1},
211*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1},
212*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 1},
213*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 1},
214*a58d3d2aSXin Li
215*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 1},
216*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1},
217*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 1},
218*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 1},
219*a58d3d2aSXin Li
220*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 240, 1},
221*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 240, 1},
222*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 240, 1},
223*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 240, 1},
224*a58d3d2aSXin Li
225*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 120, 1},
226*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 120, 1},
227*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 120, 1},
228*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 120, 1},
229*a58d3d2aSXin Li
230*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2},
231*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2},
232*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 2},
233*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 2},
234*a58d3d2aSXin Li
235*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2},
236*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2},
237*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 2},
238*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 2},
239*a58d3d2aSXin Li
240*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 240, 2},
241*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 240, 2},
242*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 240, 2},
243*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 240, 2},
244*a58d3d2aSXin Li
245*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 120, 2},
246*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 120, 2},
247*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 120, 2},
248*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 120, 2},
249*a58d3d2aSXin Li
250*a58d3d2aSXin Li };
251*a58d3d2aSXin Li
252*a58d3d2aSXin Li static const int celt_hq_test[][4] = {
253*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2},
254*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2},
255*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 240, 2},
256*a58d3d2aSXin Li {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 120, 2},
257*a58d3d2aSXin Li };
258*a58d3d2aSXin Li
259*a58d3d2aSXin Li #if 0 /* This is a hack that replaces the normal encoder/decoder with the multistream version */
260*a58d3d2aSXin Li #define OpusEncoder OpusMSEncoder
261*a58d3d2aSXin Li #define OpusDecoder OpusMSDecoder
262*a58d3d2aSXin Li #define opus_encode opus_multistream_encode
263*a58d3d2aSXin Li #define opus_decode opus_multistream_decode
264*a58d3d2aSXin Li #define opus_encoder_ctl opus_multistream_encoder_ctl
265*a58d3d2aSXin Li #define opus_decoder_ctl opus_multistream_decoder_ctl
266*a58d3d2aSXin Li #define opus_encoder_create ms_opus_encoder_create
267*a58d3d2aSXin Li #define opus_decoder_create ms_opus_decoder_create
268*a58d3d2aSXin Li #define opus_encoder_destroy opus_multistream_encoder_destroy
269*a58d3d2aSXin Li #define opus_decoder_destroy opus_multistream_decoder_destroy
270*a58d3d2aSXin Li
271*a58d3d2aSXin Li static OpusEncoder *ms_opus_encoder_create(opus_int32 Fs, int channels, int application, int *error)
272*a58d3d2aSXin Li {
273*a58d3d2aSXin Li int streams, coupled_streams;
274*a58d3d2aSXin Li unsigned char mapping[256];
275*a58d3d2aSXin Li return (OpusEncoder *)opus_multistream_surround_encoder_create(Fs, channels, 1, &streams, &coupled_streams, mapping, application, error);
276*a58d3d2aSXin Li }
277*a58d3d2aSXin Li static OpusDecoder *ms_opus_decoder_create(opus_int32 Fs, int channels, int *error)
278*a58d3d2aSXin Li {
279*a58d3d2aSXin Li int streams;
280*a58d3d2aSXin Li int coupled_streams;
281*a58d3d2aSXin Li unsigned char mapping[256]={0,1};
282*a58d3d2aSXin Li streams = 1;
283*a58d3d2aSXin Li coupled_streams = channels==2;
284*a58d3d2aSXin Li return (OpusDecoder *)opus_multistream_decoder_create(Fs, channels, streams, coupled_streams, mapping, error);
285*a58d3d2aSXin Li }
286*a58d3d2aSXin Li #endif
287*a58d3d2aSXin Li
288*a58d3d2aSXin Li
289*a58d3d2aSXin Li #ifdef ENABLE_OSCE_TRAINING_DATA
290*a58d3d2aSXin Li #define COMPLEXITY_MIN 0
291*a58d3d2aSXin Li #define COMPLEXITY_MAX 10
292*a58d3d2aSXin Li
293*a58d3d2aSXin Li #define PACKET_LOSS_PERC_MIN 0
294*a58d3d2aSXin Li #define PACKET_LOSS_PERC_MAX 50
295*a58d3d2aSXin Li #define PACKET_LOSS_PERC_STEP 5
296*a58d3d2aSXin Li
297*a58d3d2aSXin Li #define CBR_BITRATE_LIMIT 8000
298*a58d3d2aSXin Li
299*a58d3d2aSXin Li #define NUM_BITRATES 102
300*a58d3d2aSXin Li static int bitrates[NUM_BITRATES] = {
301*a58d3d2aSXin Li 6000, 6060, 6120, 6180, 6240, 6300, 6360, 6420, 6480,
302*a58d3d2aSXin Li 6525, 6561, 6598, 6634, 6670, 6707, 6743, 6780, 6816,
303*a58d3d2aSXin Li 6853, 6889, 6926, 6962, 6999, 7042, 7085, 7128, 7171,
304*a58d3d2aSXin Li 7215, 7258, 7301, 7344, 7388, 7431, 7474, 7512, 7541,
305*a58d3d2aSXin Li 7570, 7599, 7628, 7657, 7686, 7715, 7744, 7773, 7802,
306*a58d3d2aSXin Li 7831, 7860, 7889, 7918, 7947, 7976, 8013, 8096, 8179,
307*a58d3d2aSXin Li 8262, 8344, 8427, 8511, 8605, 8699, 8792, 8886, 8980,
308*a58d3d2aSXin Li 9100, 9227, 9354, 9480, 9561, 9634, 9706, 9779, 9851,
309*a58d3d2aSXin Li 9924, 9996, 10161, 10330, 10499, 10698, 10898, 11124, 11378,
310*a58d3d2aSXin Li 11575, 11719, 11862, 12014, 12345, 12751, 13195, 13561, 13795,
311*a58d3d2aSXin Li 14069, 14671, 15403, 15790, 16371, 17399, 17968, 19382, 20468,
312*a58d3d2aSXin Li 22000, 32000, 64000
313*a58d3d2aSXin Li };
314*a58d3d2aSXin Li
randint(int min,int max,int step)315*a58d3d2aSXin Li static int randint(int min, int max, int step)
316*a58d3d2aSXin Li {
317*a58d3d2aSXin Li double r = ((double) rand())/ (RAND_MAX + 1.);
318*a58d3d2aSXin Li int d;
319*a58d3d2aSXin Li
320*a58d3d2aSXin Li d = ((int) ((max + 1 - min) * r / step) * step) + min;
321*a58d3d2aSXin Li
322*a58d3d2aSXin Li return d;
323*a58d3d2aSXin Li }
324*a58d3d2aSXin Li
new_random_setting(OpusEncoder * enc)325*a58d3d2aSXin Li static void new_random_setting(OpusEncoder *enc)
326*a58d3d2aSXin Li {
327*a58d3d2aSXin Li int bitrate_bps;
328*a58d3d2aSXin Li int complexity;
329*a58d3d2aSXin Li int packet_loss_perc;
330*a58d3d2aSXin Li int use_vbr;
331*a58d3d2aSXin Li
332*a58d3d2aSXin Li bitrate_bps = bitrates[randint(0, NUM_BITRATES - 1, 1)];
333*a58d3d2aSXin Li complexity = randint(COMPLEXITY_MIN, COMPLEXITY_MAX, 1);
334*a58d3d2aSXin Li packet_loss_perc = randint(PACKET_LOSS_PERC_MIN, PACKET_LOSS_PERC_MAX, PACKET_LOSS_PERC_STEP);
335*a58d3d2aSXin Li use_vbr = bitrate_bps < CBR_BITRATE_LIMIT ? 1 : randint(0, 1, 1);
336*a58d3d2aSXin Li
337*a58d3d2aSXin Li if (1)
338*a58d3d2aSXin Li {
339*a58d3d2aSXin Li printf("changing settings to %d\t%d\t%d\t%d\n", bitrate_bps, complexity, packet_loss_perc, use_vbr);
340*a58d3d2aSXin Li }
341*a58d3d2aSXin Li
342*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
343*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity));
344*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packet_loss_perc));
345*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_VBR(use_vbr));
346*a58d3d2aSXin Li }
347*a58d3d2aSXin Li
348*a58d3d2aSXin Li #endif
349*a58d3d2aSXin Li
main(int argc,char * argv[])350*a58d3d2aSXin Li int main(int argc, char *argv[])
351*a58d3d2aSXin Li {
352*a58d3d2aSXin Li int err;
353*a58d3d2aSXin Li char *inFile, *outFile;
354*a58d3d2aSXin Li FILE *fin=NULL;
355*a58d3d2aSXin Li FILE *fout=NULL;
356*a58d3d2aSXin Li OpusEncoder *enc=NULL;
357*a58d3d2aSXin Li OpusDecoder *dec=NULL;
358*a58d3d2aSXin Li OpusDRED *dred=NULL;
359*a58d3d2aSXin Li OpusDREDDecoder *dred_dec=NULL;
360*a58d3d2aSXin Li int args;
361*a58d3d2aSXin Li int len;
362*a58d3d2aSXin Li int frame_size, channels;
363*a58d3d2aSXin Li opus_int32 bitrate_bps=0;
364*a58d3d2aSXin Li unsigned char *data = NULL;
365*a58d3d2aSXin Li unsigned char *fbytes=NULL;
366*a58d3d2aSXin Li opus_int32 sampling_rate;
367*a58d3d2aSXin Li int use_vbr;
368*a58d3d2aSXin Li int max_payload_bytes;
369*a58d3d2aSXin Li int complexity;
370*a58d3d2aSXin Li int dec_complexity;
371*a58d3d2aSXin Li int use_inbandfec;
372*a58d3d2aSXin Li int use_dtx;
373*a58d3d2aSXin Li int forcechannels;
374*a58d3d2aSXin Li int cvbr = 0;
375*a58d3d2aSXin Li int packet_loss_perc;
376*a58d3d2aSXin Li #ifdef ENABLE_LOSSGEN
377*a58d3d2aSXin Li float lossgen_perc = -1.f;
378*a58d3d2aSXin Li LossGenState lossgen;
379*a58d3d2aSXin Li #endif
380*a58d3d2aSXin Li opus_int32 count=0, count_act=0;
381*a58d3d2aSXin Li int k;
382*a58d3d2aSXin Li opus_int32 skip=0;
383*a58d3d2aSXin Li int stop=0;
384*a58d3d2aSXin Li short *in=NULL;
385*a58d3d2aSXin Li short *out=NULL;
386*a58d3d2aSXin Li int application=OPUS_APPLICATION_AUDIO;
387*a58d3d2aSXin Li double bits=0.0, bits_max=0.0, bits_act=0.0, bits2=0.0, nrg;
388*a58d3d2aSXin Li double tot_samples=0;
389*a58d3d2aSXin Li opus_uint64 tot_in, tot_out;
390*a58d3d2aSXin Li int bandwidth=OPUS_AUTO;
391*a58d3d2aSXin Li const char *bandwidth_string;
392*a58d3d2aSXin Li int lost = 0, lost_prev = 1;
393*a58d3d2aSXin Li opus_uint32 enc_final_range;
394*a58d3d2aSXin Li opus_uint32 dec_final_range;
395*a58d3d2aSXin Li int encode_only=0, decode_only=0;
396*a58d3d2aSXin Li int max_frame_size = 48000*2;
397*a58d3d2aSXin Li size_t num_read;
398*a58d3d2aSXin Li int curr_read=0;
399*a58d3d2aSXin Li int sweep_bps = 0;
400*a58d3d2aSXin Li int random_framesize=0, newsize=0, delayed_celt=0;
401*a58d3d2aSXin Li int sweep_max=0, sweep_min=0;
402*a58d3d2aSXin Li int random_fec=0;
403*a58d3d2aSXin Li const int (*mode_list)[4]=NULL;
404*a58d3d2aSXin Li int nb_modes_in_list=0;
405*a58d3d2aSXin Li int curr_mode=0;
406*a58d3d2aSXin Li int curr_mode_count=0;
407*a58d3d2aSXin Li int mode_switch_time = 48000;
408*a58d3d2aSXin Li int nb_encoded=0;
409*a58d3d2aSXin Li int remaining=0;
410*a58d3d2aSXin Li int variable_duration=OPUS_FRAMESIZE_ARG;
411*a58d3d2aSXin Li int delayed_decision=0;
412*a58d3d2aSXin Li int ret = EXIT_FAILURE;
413*a58d3d2aSXin Li int lost_count=0;
414*a58d3d2aSXin Li FILE *packet_loss_file=NULL;
415*a58d3d2aSXin Li int dred_duration=0;
416*a58d3d2aSXin Li #ifdef ENABLE_OSCE_TRAINING_DATA
417*a58d3d2aSXin Li int silk_random_switching = 0;
418*a58d3d2aSXin Li int silk_frame_counter = 0;
419*a58d3d2aSXin Li #endif
420*a58d3d2aSXin Li #ifdef USE_WEIGHTS_FILE
421*a58d3d2aSXin Li int blob_len;
422*a58d3d2aSXin Li void *blob_data;
423*a58d3d2aSXin Li const char *filename = "weights_blob.bin";
424*a58d3d2aSXin Li blob_data = load_blob(filename, &blob_len);
425*a58d3d2aSXin Li #endif
426*a58d3d2aSXin Li
427*a58d3d2aSXin Li if (argc < 5 )
428*a58d3d2aSXin Li {
429*a58d3d2aSXin Li print_usage( argv );
430*a58d3d2aSXin Li goto failure;
431*a58d3d2aSXin Li }
432*a58d3d2aSXin Li
433*a58d3d2aSXin Li tot_in=tot_out=0;
434*a58d3d2aSXin Li fprintf(stderr, "%s\n", opus_get_version_string());
435*a58d3d2aSXin Li
436*a58d3d2aSXin Li args = 1;
437*a58d3d2aSXin Li if (strcmp(argv[args], "-e")==0)
438*a58d3d2aSXin Li {
439*a58d3d2aSXin Li encode_only = 1;
440*a58d3d2aSXin Li args++;
441*a58d3d2aSXin Li } else if (strcmp(argv[args], "-d")==0)
442*a58d3d2aSXin Li {
443*a58d3d2aSXin Li decode_only = 1;
444*a58d3d2aSXin Li args++;
445*a58d3d2aSXin Li }
446*a58d3d2aSXin Li if (!decode_only && argc < 7 )
447*a58d3d2aSXin Li {
448*a58d3d2aSXin Li print_usage( argv );
449*a58d3d2aSXin Li goto failure;
450*a58d3d2aSXin Li }
451*a58d3d2aSXin Li
452*a58d3d2aSXin Li if (!decode_only)
453*a58d3d2aSXin Li {
454*a58d3d2aSXin Li if (strcmp(argv[args], "voip")==0)
455*a58d3d2aSXin Li application = OPUS_APPLICATION_VOIP;
456*a58d3d2aSXin Li else if (strcmp(argv[args], "restricted-lowdelay")==0)
457*a58d3d2aSXin Li application = OPUS_APPLICATION_RESTRICTED_LOWDELAY;
458*a58d3d2aSXin Li else if (strcmp(argv[args], "audio")!=0) {
459*a58d3d2aSXin Li fprintf(stderr, "unknown application: %s\n", argv[args]);
460*a58d3d2aSXin Li print_usage(argv);
461*a58d3d2aSXin Li goto failure;
462*a58d3d2aSXin Li }
463*a58d3d2aSXin Li args++;
464*a58d3d2aSXin Li }
465*a58d3d2aSXin Li sampling_rate = (opus_int32)atol(argv[args]);
466*a58d3d2aSXin Li args++;
467*a58d3d2aSXin Li
468*a58d3d2aSXin Li if (sampling_rate != 8000 && sampling_rate != 12000
469*a58d3d2aSXin Li && sampling_rate != 16000 && sampling_rate != 24000
470*a58d3d2aSXin Li && sampling_rate != 48000)
471*a58d3d2aSXin Li {
472*a58d3d2aSXin Li fprintf(stderr, "Supported sampling rates are 8000, 12000, "
473*a58d3d2aSXin Li "16000, 24000 and 48000.\n");
474*a58d3d2aSXin Li goto failure;
475*a58d3d2aSXin Li }
476*a58d3d2aSXin Li frame_size = sampling_rate/50;
477*a58d3d2aSXin Li
478*a58d3d2aSXin Li channels = atoi(argv[args]);
479*a58d3d2aSXin Li args++;
480*a58d3d2aSXin Li
481*a58d3d2aSXin Li if (channels < 1 || channels > 2)
482*a58d3d2aSXin Li {
483*a58d3d2aSXin Li fprintf(stderr, "Opus_demo supports only 1 or 2 channels.\n");
484*a58d3d2aSXin Li goto failure;
485*a58d3d2aSXin Li }
486*a58d3d2aSXin Li
487*a58d3d2aSXin Li if (!decode_only)
488*a58d3d2aSXin Li {
489*a58d3d2aSXin Li bitrate_bps = (opus_int32)atol(argv[args]);
490*a58d3d2aSXin Li args++;
491*a58d3d2aSXin Li }
492*a58d3d2aSXin Li
493*a58d3d2aSXin Li /* defaults: */
494*a58d3d2aSXin Li use_vbr = 1;
495*a58d3d2aSXin Li max_payload_bytes = MAX_PACKET;
496*a58d3d2aSXin Li complexity = 10;
497*a58d3d2aSXin Li dec_complexity = 0;
498*a58d3d2aSXin Li use_inbandfec = 0;
499*a58d3d2aSXin Li forcechannels = OPUS_AUTO;
500*a58d3d2aSXin Li use_dtx = 0;
501*a58d3d2aSXin Li packet_loss_perc = 0;
502*a58d3d2aSXin Li
503*a58d3d2aSXin Li while( args < argc - 2 ) {
504*a58d3d2aSXin Li /* process command line options */
505*a58d3d2aSXin Li if( strcmp( argv[ args ], "-cbr" ) == 0 ) {
506*a58d3d2aSXin Li check_encoder_option(decode_only, "-cbr");
507*a58d3d2aSXin Li use_vbr = 0;
508*a58d3d2aSXin Li args++;
509*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-bandwidth" ) == 0 ) {
510*a58d3d2aSXin Li check_encoder_option(decode_only, "-bandwidth");
511*a58d3d2aSXin Li if (strcmp(argv[ args + 1 ], "NB")==0)
512*a58d3d2aSXin Li bandwidth = OPUS_BANDWIDTH_NARROWBAND;
513*a58d3d2aSXin Li else if (strcmp(argv[ args + 1 ], "MB")==0)
514*a58d3d2aSXin Li bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
515*a58d3d2aSXin Li else if (strcmp(argv[ args + 1 ], "WB")==0)
516*a58d3d2aSXin Li bandwidth = OPUS_BANDWIDTH_WIDEBAND;
517*a58d3d2aSXin Li else if (strcmp(argv[ args + 1 ], "SWB")==0)
518*a58d3d2aSXin Li bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
519*a58d3d2aSXin Li else if (strcmp(argv[ args + 1 ], "FB")==0)
520*a58d3d2aSXin Li bandwidth = OPUS_BANDWIDTH_FULLBAND;
521*a58d3d2aSXin Li else {
522*a58d3d2aSXin Li fprintf(stderr, "Unknown bandwidth %s. "
523*a58d3d2aSXin Li "Supported are NB, MB, WB, SWB, FB.\n",
524*a58d3d2aSXin Li argv[ args + 1 ]);
525*a58d3d2aSXin Li goto failure;
526*a58d3d2aSXin Li }
527*a58d3d2aSXin Li args += 2;
528*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-framesize" ) == 0 ) {
529*a58d3d2aSXin Li check_encoder_option(decode_only, "-framesize");
530*a58d3d2aSXin Li if (strcmp(argv[ args + 1 ], "2.5")==0)
531*a58d3d2aSXin Li frame_size = sampling_rate/400;
532*a58d3d2aSXin Li else if (strcmp(argv[ args + 1 ], "5")==0)
533*a58d3d2aSXin Li frame_size = sampling_rate/200;
534*a58d3d2aSXin Li else if (strcmp(argv[ args + 1 ], "10")==0)
535*a58d3d2aSXin Li frame_size = sampling_rate/100;
536*a58d3d2aSXin Li else if (strcmp(argv[ args + 1 ], "20")==0)
537*a58d3d2aSXin Li frame_size = sampling_rate/50;
538*a58d3d2aSXin Li else if (strcmp(argv[ args + 1 ], "40")==0)
539*a58d3d2aSXin Li frame_size = sampling_rate/25;
540*a58d3d2aSXin Li else if (strcmp(argv[ args + 1 ], "60")==0)
541*a58d3d2aSXin Li frame_size = 3*sampling_rate/50;
542*a58d3d2aSXin Li else if (strcmp(argv[ args + 1 ], "80")==0)
543*a58d3d2aSXin Li frame_size = 4*sampling_rate/50;
544*a58d3d2aSXin Li else if (strcmp(argv[ args + 1 ], "100")==0)
545*a58d3d2aSXin Li frame_size = 5*sampling_rate/50;
546*a58d3d2aSXin Li else if (strcmp(argv[ args + 1 ], "120")==0)
547*a58d3d2aSXin Li frame_size = 6*sampling_rate/50;
548*a58d3d2aSXin Li else {
549*a58d3d2aSXin Li fprintf(stderr, "Unsupported frame size: %s ms. "
550*a58d3d2aSXin Li "Supported are 2.5, 5, 10, 20, 40, 60, 80, 100, 120.\n",
551*a58d3d2aSXin Li argv[ args + 1 ]);
552*a58d3d2aSXin Li goto failure;
553*a58d3d2aSXin Li }
554*a58d3d2aSXin Li args += 2;
555*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-max_payload" ) == 0 ) {
556*a58d3d2aSXin Li check_encoder_option(decode_only, "-max_payload");
557*a58d3d2aSXin Li max_payload_bytes = atoi( argv[ args + 1 ] );
558*a58d3d2aSXin Li args += 2;
559*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-complexity" ) == 0 ) {
560*a58d3d2aSXin Li check_encoder_option(decode_only, "-complexity");
561*a58d3d2aSXin Li complexity = atoi( argv[ args + 1 ] );
562*a58d3d2aSXin Li args += 2;
563*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-dec_complexity" ) == 0 ) {
564*a58d3d2aSXin Li check_decoder_option(encode_only, "-dec_complexity");
565*a58d3d2aSXin Li dec_complexity = atoi( argv[ args + 1 ] );
566*a58d3d2aSXin Li args += 2;
567*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-inbandfec" ) == 0 ) {
568*a58d3d2aSXin Li use_inbandfec = 1;
569*a58d3d2aSXin Li args++;
570*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-forcemono" ) == 0 ) {
571*a58d3d2aSXin Li check_encoder_option(decode_only, "-forcemono");
572*a58d3d2aSXin Li forcechannels = 1;
573*a58d3d2aSXin Li args++;
574*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-cvbr" ) == 0 ) {
575*a58d3d2aSXin Li check_encoder_option(decode_only, "-cvbr");
576*a58d3d2aSXin Li cvbr = 1;
577*a58d3d2aSXin Li args++;
578*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-delayed-decision" ) == 0 ) {
579*a58d3d2aSXin Li check_encoder_option(decode_only, "-delayed-decision");
580*a58d3d2aSXin Li delayed_decision = 1;
581*a58d3d2aSXin Li args++;
582*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-dtx") == 0 ) {
583*a58d3d2aSXin Li check_encoder_option(decode_only, "-dtx");
584*a58d3d2aSXin Li use_dtx = 1;
585*a58d3d2aSXin Li args++;
586*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-loss" ) == 0 ) {
587*a58d3d2aSXin Li packet_loss_perc = atoi( argv[ args + 1 ] );
588*a58d3d2aSXin Li args += 2;
589*a58d3d2aSXin Li #ifdef ENABLE_LOSSGEN
590*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-sim_loss" ) == 0 ) {
591*a58d3d2aSXin Li lossgen_perc = atof( argv[ args + 1 ] );
592*a58d3d2aSXin Li lossgen_init(&lossgen);
593*a58d3d2aSXin Li args += 2;
594*a58d3d2aSXin Li #endif
595*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-lossfile" ) == 0 ) {
596*a58d3d2aSXin Li packet_loss_file = fopen( argv[ args + 1 ], "r" );
597*a58d3d2aSXin Li if (packet_loss_file == NULL) {
598*a58d3d2aSXin Li fprintf(stderr, "failed to open loss file %s\n", argv[ args + 1 ] );
599*a58d3d2aSXin Li exit(1);
600*a58d3d2aSXin Li }
601*a58d3d2aSXin Li args += 2;
602*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-dred" ) == 0 ) {
603*a58d3d2aSXin Li dred_duration = atoi( argv[ args + 1 ] );
604*a58d3d2aSXin Li args += 2;
605*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-sweep" ) == 0 ) {
606*a58d3d2aSXin Li check_encoder_option(decode_only, "-sweep");
607*a58d3d2aSXin Li sweep_bps = atoi( argv[ args + 1 ] );
608*a58d3d2aSXin Li args += 2;
609*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-random_framesize" ) == 0 ) {
610*a58d3d2aSXin Li check_encoder_option(decode_only, "-random_framesize");
611*a58d3d2aSXin Li random_framesize = 1;
612*a58d3d2aSXin Li args++;
613*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-sweep_max" ) == 0 ) {
614*a58d3d2aSXin Li check_encoder_option(decode_only, "-sweep_max");
615*a58d3d2aSXin Li sweep_max = atoi( argv[ args + 1 ] );
616*a58d3d2aSXin Li args += 2;
617*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-random_fec" ) == 0 ) {
618*a58d3d2aSXin Li check_encoder_option(decode_only, "-random_fec");
619*a58d3d2aSXin Li random_fec = 1;
620*a58d3d2aSXin Li args++;
621*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-silk8k_test" ) == 0 ) {
622*a58d3d2aSXin Li check_encoder_option(decode_only, "-silk8k_test");
623*a58d3d2aSXin Li mode_list = silk8_test;
624*a58d3d2aSXin Li nb_modes_in_list = 8;
625*a58d3d2aSXin Li args++;
626*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-silk12k_test" ) == 0 ) {
627*a58d3d2aSXin Li check_encoder_option(decode_only, "-silk12k_test");
628*a58d3d2aSXin Li mode_list = silk12_test;
629*a58d3d2aSXin Li nb_modes_in_list = 8;
630*a58d3d2aSXin Li args++;
631*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-silk16k_test" ) == 0 ) {
632*a58d3d2aSXin Li check_encoder_option(decode_only, "-silk16k_test");
633*a58d3d2aSXin Li mode_list = silk16_test;
634*a58d3d2aSXin Li nb_modes_in_list = 8;
635*a58d3d2aSXin Li args++;
636*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-hybrid24k_test" ) == 0 ) {
637*a58d3d2aSXin Li check_encoder_option(decode_only, "-hybrid24k_test");
638*a58d3d2aSXin Li mode_list = hybrid24_test;
639*a58d3d2aSXin Li nb_modes_in_list = 4;
640*a58d3d2aSXin Li args++;
641*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-hybrid48k_test" ) == 0 ) {
642*a58d3d2aSXin Li check_encoder_option(decode_only, "-hybrid48k_test");
643*a58d3d2aSXin Li mode_list = hybrid48_test;
644*a58d3d2aSXin Li nb_modes_in_list = 4;
645*a58d3d2aSXin Li args++;
646*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-celt_test" ) == 0 ) {
647*a58d3d2aSXin Li check_encoder_option(decode_only, "-celt_test");
648*a58d3d2aSXin Li mode_list = celt_test;
649*a58d3d2aSXin Li nb_modes_in_list = 32;
650*a58d3d2aSXin Li args++;
651*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-celt_hq_test" ) == 0 ) {
652*a58d3d2aSXin Li check_encoder_option(decode_only, "-celt_hq_test");
653*a58d3d2aSXin Li mode_list = celt_hq_test;
654*a58d3d2aSXin Li nb_modes_in_list = 4;
655*a58d3d2aSXin Li args++;
656*a58d3d2aSXin Li #ifdef ENABLE_OSCE_TRAINING_DATA
657*a58d3d2aSXin Li } else if( strcmp( argv[ args ], "-silk_random_switching" ) == 0 ){
658*a58d3d2aSXin Li silk_random_switching = atoi( argv[ args + 1 ] );
659*a58d3d2aSXin Li printf("switching encoding parameters every %dth frame\n", silk_random_switching);
660*a58d3d2aSXin Li args += 2;
661*a58d3d2aSXin Li #endif
662*a58d3d2aSXin Li } else {
663*a58d3d2aSXin Li printf( "Error: unrecognized setting: %s\n\n", argv[ args ] );
664*a58d3d2aSXin Li print_usage( argv );
665*a58d3d2aSXin Li goto failure;
666*a58d3d2aSXin Li }
667*a58d3d2aSXin Li }
668*a58d3d2aSXin Li
669*a58d3d2aSXin Li if (sweep_max)
670*a58d3d2aSXin Li sweep_min = bitrate_bps;
671*a58d3d2aSXin Li
672*a58d3d2aSXin Li if (max_payload_bytes < 0 || max_payload_bytes > MAX_PACKET)
673*a58d3d2aSXin Li {
674*a58d3d2aSXin Li fprintf (stderr, "max_payload_bytes must be between 0 and %d\n",
675*a58d3d2aSXin Li MAX_PACKET);
676*a58d3d2aSXin Li goto failure;
677*a58d3d2aSXin Li }
678*a58d3d2aSXin Li
679*a58d3d2aSXin Li inFile = argv[argc-2];
680*a58d3d2aSXin Li fin = fopen(inFile, "rb");
681*a58d3d2aSXin Li if (!fin)
682*a58d3d2aSXin Li {
683*a58d3d2aSXin Li fprintf (stderr, "Could not open input file %s\n", argv[argc-2]);
684*a58d3d2aSXin Li goto failure;
685*a58d3d2aSXin Li }
686*a58d3d2aSXin Li if (mode_list)
687*a58d3d2aSXin Li {
688*a58d3d2aSXin Li int size;
689*a58d3d2aSXin Li fseek(fin, 0, SEEK_END);
690*a58d3d2aSXin Li size = ftell(fin);
691*a58d3d2aSXin Li fprintf(stderr, "File size is %d bytes\n", size);
692*a58d3d2aSXin Li fseek(fin, 0, SEEK_SET);
693*a58d3d2aSXin Li mode_switch_time = size/sizeof(short)/channels/nb_modes_in_list;
694*a58d3d2aSXin Li fprintf(stderr, "Switching mode every %d samples\n", mode_switch_time);
695*a58d3d2aSXin Li }
696*a58d3d2aSXin Li
697*a58d3d2aSXin Li outFile = argv[argc-1];
698*a58d3d2aSXin Li fout = fopen(outFile, "wb+");
699*a58d3d2aSXin Li if (!fout)
700*a58d3d2aSXin Li {
701*a58d3d2aSXin Li fprintf (stderr, "Could not open output file %s\n", argv[argc-1]);
702*a58d3d2aSXin Li goto failure;
703*a58d3d2aSXin Li }
704*a58d3d2aSXin Li
705*a58d3d2aSXin Li if (!decode_only)
706*a58d3d2aSXin Li {
707*a58d3d2aSXin Li enc = opus_encoder_create(sampling_rate, channels, application, &err);
708*a58d3d2aSXin Li if (err != OPUS_OK)
709*a58d3d2aSXin Li {
710*a58d3d2aSXin Li fprintf(stderr, "Cannot create encoder: %s\n", opus_strerror(err));
711*a58d3d2aSXin Li goto failure;
712*a58d3d2aSXin Li }
713*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
714*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bandwidth));
715*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_VBR(use_vbr));
716*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(cvbr));
717*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity));
718*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(use_inbandfec));
719*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(forcechannels));
720*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_DTX(use_dtx));
721*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packet_loss_perc));
722*a58d3d2aSXin Li
723*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&skip));
724*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(16));
725*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration));
726*a58d3d2aSXin Li if (dred_duration > 0)
727*a58d3d2aSXin Li {
728*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_DRED_DURATION(dred_duration));
729*a58d3d2aSXin Li }
730*a58d3d2aSXin Li }
731*a58d3d2aSXin Li if (!encode_only)
732*a58d3d2aSXin Li {
733*a58d3d2aSXin Li dec = opus_decoder_create(sampling_rate, channels, &err);
734*a58d3d2aSXin Li if (err != OPUS_OK)
735*a58d3d2aSXin Li {
736*a58d3d2aSXin Li fprintf(stderr, "Cannot create decoder: %s\n", opus_strerror(err));
737*a58d3d2aSXin Li goto failure;
738*a58d3d2aSXin Li }
739*a58d3d2aSXin Li opus_decoder_ctl(dec, OPUS_SET_COMPLEXITY(dec_complexity));
740*a58d3d2aSXin Li }
741*a58d3d2aSXin Li switch(bandwidth)
742*a58d3d2aSXin Li {
743*a58d3d2aSXin Li case OPUS_BANDWIDTH_NARROWBAND:
744*a58d3d2aSXin Li bandwidth_string = "narrowband";
745*a58d3d2aSXin Li break;
746*a58d3d2aSXin Li case OPUS_BANDWIDTH_MEDIUMBAND:
747*a58d3d2aSXin Li bandwidth_string = "mediumband";
748*a58d3d2aSXin Li break;
749*a58d3d2aSXin Li case OPUS_BANDWIDTH_WIDEBAND:
750*a58d3d2aSXin Li bandwidth_string = "wideband";
751*a58d3d2aSXin Li break;
752*a58d3d2aSXin Li case OPUS_BANDWIDTH_SUPERWIDEBAND:
753*a58d3d2aSXin Li bandwidth_string = "superwideband";
754*a58d3d2aSXin Li break;
755*a58d3d2aSXin Li case OPUS_BANDWIDTH_FULLBAND:
756*a58d3d2aSXin Li bandwidth_string = "fullband";
757*a58d3d2aSXin Li break;
758*a58d3d2aSXin Li case OPUS_AUTO:
759*a58d3d2aSXin Li bandwidth_string = "auto bandwidth";
760*a58d3d2aSXin Li break;
761*a58d3d2aSXin Li default:
762*a58d3d2aSXin Li bandwidth_string = "unknown";
763*a58d3d2aSXin Li break;
764*a58d3d2aSXin Li }
765*a58d3d2aSXin Li
766*a58d3d2aSXin Li if (decode_only)
767*a58d3d2aSXin Li fprintf(stderr, "Decoding with %ld Hz output (%d channels)\n",
768*a58d3d2aSXin Li (long)sampling_rate, channels);
769*a58d3d2aSXin Li else
770*a58d3d2aSXin Li fprintf(stderr, "Encoding %ld Hz input at %.3f kb/s "
771*a58d3d2aSXin Li "in %s with %d-sample frames.\n",
772*a58d3d2aSXin Li (long)sampling_rate, bitrate_bps*0.001,
773*a58d3d2aSXin Li bandwidth_string, frame_size);
774*a58d3d2aSXin Li
775*a58d3d2aSXin Li in = (short*)malloc(max_frame_size*channels*sizeof(short));
776*a58d3d2aSXin Li out = (short*)malloc(max_frame_size*channels*sizeof(short));
777*a58d3d2aSXin Li /* We need to allocate for 16-bit PCM data, but we store it as unsigned char. */
778*a58d3d2aSXin Li fbytes = (unsigned char*)malloc(max_frame_size*channels*sizeof(short));
779*a58d3d2aSXin Li data = (unsigned char*)calloc(max_payload_bytes,sizeof(unsigned char));
780*a58d3d2aSXin Li if(delayed_decision)
781*a58d3d2aSXin Li {
782*a58d3d2aSXin Li if (frame_size==sampling_rate/400)
783*a58d3d2aSXin Li variable_duration = OPUS_FRAMESIZE_2_5_MS;
784*a58d3d2aSXin Li else if (frame_size==sampling_rate/200)
785*a58d3d2aSXin Li variable_duration = OPUS_FRAMESIZE_5_MS;
786*a58d3d2aSXin Li else if (frame_size==sampling_rate/100)
787*a58d3d2aSXin Li variable_duration = OPUS_FRAMESIZE_10_MS;
788*a58d3d2aSXin Li else if (frame_size==sampling_rate/50)
789*a58d3d2aSXin Li variable_duration = OPUS_FRAMESIZE_20_MS;
790*a58d3d2aSXin Li else if (frame_size==sampling_rate/25)
791*a58d3d2aSXin Li variable_duration = OPUS_FRAMESIZE_40_MS;
792*a58d3d2aSXin Li else if (frame_size==3*sampling_rate/50)
793*a58d3d2aSXin Li variable_duration = OPUS_FRAMESIZE_60_MS;
794*a58d3d2aSXin Li else if (frame_size==4*sampling_rate/50)
795*a58d3d2aSXin Li variable_duration = OPUS_FRAMESIZE_80_MS;
796*a58d3d2aSXin Li else if (frame_size==5*sampling_rate/50)
797*a58d3d2aSXin Li variable_duration = OPUS_FRAMESIZE_100_MS;
798*a58d3d2aSXin Li else
799*a58d3d2aSXin Li variable_duration = OPUS_FRAMESIZE_120_MS;
800*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration));
801*a58d3d2aSXin Li frame_size = 2*48000;
802*a58d3d2aSXin Li }
803*a58d3d2aSXin Li dred_dec = opus_dred_decoder_create(&err);
804*a58d3d2aSXin Li dred = opus_dred_alloc(&err);
805*a58d3d2aSXin Li #ifdef USE_WEIGHTS_FILE
806*a58d3d2aSXin Li if (enc) opus_encoder_ctl(enc, OPUS_SET_DNN_BLOB(blob_data, blob_len));
807*a58d3d2aSXin Li if (dec) opus_decoder_ctl(dec, OPUS_SET_DNN_BLOB(blob_data, blob_len));
808*a58d3d2aSXin Li if (dred_dec) opus_dred_decoder_ctl(dred_dec, OPUS_SET_DNN_BLOB(blob_data, blob_len));
809*a58d3d2aSXin Li #endif
810*a58d3d2aSXin Li while (!stop)
811*a58d3d2aSXin Li {
812*a58d3d2aSXin Li if (delayed_celt)
813*a58d3d2aSXin Li {
814*a58d3d2aSXin Li frame_size = newsize;
815*a58d3d2aSXin Li delayed_celt = 0;
816*a58d3d2aSXin Li } else if (random_framesize && rand()%20==0)
817*a58d3d2aSXin Li {
818*a58d3d2aSXin Li newsize = rand()%6;
819*a58d3d2aSXin Li switch(newsize)
820*a58d3d2aSXin Li {
821*a58d3d2aSXin Li case 0: newsize=sampling_rate/400; break;
822*a58d3d2aSXin Li case 1: newsize=sampling_rate/200; break;
823*a58d3d2aSXin Li case 2: newsize=sampling_rate/100; break;
824*a58d3d2aSXin Li case 3: newsize=sampling_rate/50; break;
825*a58d3d2aSXin Li case 4: newsize=sampling_rate/25; break;
826*a58d3d2aSXin Li case 5: newsize=3*sampling_rate/50; break;
827*a58d3d2aSXin Li }
828*a58d3d2aSXin Li while (newsize < sampling_rate/25 && bitrate_bps-abs(sweep_bps) <= 3*12*sampling_rate/newsize)
829*a58d3d2aSXin Li newsize*=2;
830*a58d3d2aSXin Li if (newsize < sampling_rate/100 && frame_size >= sampling_rate/100)
831*a58d3d2aSXin Li {
832*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
833*a58d3d2aSXin Li delayed_celt=1;
834*a58d3d2aSXin Li } else {
835*a58d3d2aSXin Li frame_size = newsize;
836*a58d3d2aSXin Li }
837*a58d3d2aSXin Li }
838*a58d3d2aSXin Li if (random_fec && rand()%30==0)
839*a58d3d2aSXin Li {
840*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(rand()%4==0));
841*a58d3d2aSXin Li }
842*a58d3d2aSXin Li if (decode_only)
843*a58d3d2aSXin Li {
844*a58d3d2aSXin Li unsigned char ch[4];
845*a58d3d2aSXin Li num_read = fread(ch, 1, 4, fin);
846*a58d3d2aSXin Li if (num_read!=4)
847*a58d3d2aSXin Li break;
848*a58d3d2aSXin Li len = char_to_int(ch);
849*a58d3d2aSXin Li if (len>max_payload_bytes || len<0)
850*a58d3d2aSXin Li {
851*a58d3d2aSXin Li fprintf(stderr, "Invalid payload length: %d\n",len);
852*a58d3d2aSXin Li break;
853*a58d3d2aSXin Li }
854*a58d3d2aSXin Li num_read = fread(ch, 1, 4, fin);
855*a58d3d2aSXin Li if (num_read!=4)
856*a58d3d2aSXin Li break;
857*a58d3d2aSXin Li enc_final_range = char_to_int(ch);
858*a58d3d2aSXin Li num_read = fread(data, 1, len, fin);
859*a58d3d2aSXin Li if (num_read!=(size_t)len)
860*a58d3d2aSXin Li {
861*a58d3d2aSXin Li fprintf(stderr, "Ran out of input, "
862*a58d3d2aSXin Li "expecting %d bytes got %d\n",
863*a58d3d2aSXin Li len,(int)num_read);
864*a58d3d2aSXin Li break;
865*a58d3d2aSXin Li }
866*a58d3d2aSXin Li } else {
867*a58d3d2aSXin Li int i;
868*a58d3d2aSXin Li if (mode_list!=NULL)
869*a58d3d2aSXin Li {
870*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(mode_list[curr_mode][1]));
871*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(mode_list[curr_mode][0]));
872*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(mode_list[curr_mode][3]));
873*a58d3d2aSXin Li frame_size = mode_list[curr_mode][2];
874*a58d3d2aSXin Li }
875*a58d3d2aSXin Li #ifdef ENABLE_OSCE_TRAINING_DATA
876*a58d3d2aSXin Li if (silk_random_switching)
877*a58d3d2aSXin Li {
878*a58d3d2aSXin Li silk_frame_counter += 1;
879*a58d3d2aSXin Li if (silk_frame_counter % silk_random_switching == 0) {
880*a58d3d2aSXin Li new_random_setting(enc);
881*a58d3d2aSXin Li }
882*a58d3d2aSXin Li }
883*a58d3d2aSXin Li #endif
884*a58d3d2aSXin Li num_read = fread(fbytes, sizeof(short)*channels, frame_size-remaining, fin);
885*a58d3d2aSXin Li curr_read = (int)num_read;
886*a58d3d2aSXin Li tot_in += curr_read;
887*a58d3d2aSXin Li for(i=0;i<curr_read*channels;i++)
888*a58d3d2aSXin Li {
889*a58d3d2aSXin Li opus_int32 s;
890*a58d3d2aSXin Li s=fbytes[2*i+1]<<8|fbytes[2*i];
891*a58d3d2aSXin Li s=((s&0xFFFF)^0x8000)-0x8000;
892*a58d3d2aSXin Li in[i+remaining*channels]=s;
893*a58d3d2aSXin Li }
894*a58d3d2aSXin Li if (curr_read+remaining < frame_size)
895*a58d3d2aSXin Li {
896*a58d3d2aSXin Li for (i=(curr_read+remaining)*channels;i<frame_size*channels;i++)
897*a58d3d2aSXin Li in[i] = 0;
898*a58d3d2aSXin Li if (encode_only || decode_only)
899*a58d3d2aSXin Li stop = 1;
900*a58d3d2aSXin Li }
901*a58d3d2aSXin Li len = opus_encode(enc, in, frame_size, data, max_payload_bytes);
902*a58d3d2aSXin Li if (len < 0)
903*a58d3d2aSXin Li {
904*a58d3d2aSXin Li fprintf (stderr, "opus_encode() returned %d\n", len);
905*a58d3d2aSXin Li goto failure;
906*a58d3d2aSXin Li }
907*a58d3d2aSXin Li nb_encoded = opus_packet_get_samples_per_frame(data, sampling_rate)*opus_packet_get_nb_frames(data, len);
908*a58d3d2aSXin Li remaining = frame_size-nb_encoded;
909*a58d3d2aSXin Li for(i=0;i<remaining*channels;i++)
910*a58d3d2aSXin Li in[i] = in[nb_encoded*channels+i];
911*a58d3d2aSXin Li if (sweep_bps!=0)
912*a58d3d2aSXin Li {
913*a58d3d2aSXin Li bitrate_bps += sweep_bps;
914*a58d3d2aSXin Li if (sweep_max)
915*a58d3d2aSXin Li {
916*a58d3d2aSXin Li if (bitrate_bps > sweep_max)
917*a58d3d2aSXin Li sweep_bps = -sweep_bps;
918*a58d3d2aSXin Li else if (bitrate_bps < sweep_min)
919*a58d3d2aSXin Li sweep_bps = -sweep_bps;
920*a58d3d2aSXin Li }
921*a58d3d2aSXin Li /* safety */
922*a58d3d2aSXin Li if (bitrate_bps<1000)
923*a58d3d2aSXin Li bitrate_bps = 1000;
924*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
925*a58d3d2aSXin Li }
926*a58d3d2aSXin Li opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range));
927*a58d3d2aSXin Li curr_mode_count += frame_size;
928*a58d3d2aSXin Li if (curr_mode_count > mode_switch_time && curr_mode < nb_modes_in_list-1)
929*a58d3d2aSXin Li {
930*a58d3d2aSXin Li curr_mode++;
931*a58d3d2aSXin Li curr_mode_count = 0;
932*a58d3d2aSXin Li }
933*a58d3d2aSXin Li }
934*a58d3d2aSXin Li
935*a58d3d2aSXin Li #if 0 /* This is for testing the padding code, do not enable by default */
936*a58d3d2aSXin Li if (len<1275)
937*a58d3d2aSXin Li {
938*a58d3d2aSXin Li int new_len = len+rand()%(max_payload_bytes-len);
939*a58d3d2aSXin Li if ((err = opus_packet_pad(data, len, new_len)) != OPUS_OK)
940*a58d3d2aSXin Li {
941*a58d3d2aSXin Li fprintf(stderr, "padding failed: %s\n", opus_strerror(err));
942*a58d3d2aSXin Li goto failure;
943*a58d3d2aSXin Li }
944*a58d3d2aSXin Li len = new_len;
945*a58d3d2aSXin Li }
946*a58d3d2aSXin Li #endif
947*a58d3d2aSXin Li if (encode_only)
948*a58d3d2aSXin Li {
949*a58d3d2aSXin Li unsigned char int_field[4];
950*a58d3d2aSXin Li int_to_char(len, int_field);
951*a58d3d2aSXin Li if (fwrite(int_field, 1, 4, fout) != 4) {
952*a58d3d2aSXin Li fprintf(stderr, "Error writing.\n");
953*a58d3d2aSXin Li goto failure;
954*a58d3d2aSXin Li }
955*a58d3d2aSXin Li int_to_char(enc_final_range, int_field);
956*a58d3d2aSXin Li if (fwrite(int_field, 1, 4, fout) != 4) {
957*a58d3d2aSXin Li fprintf(stderr, "Error writing.\n");
958*a58d3d2aSXin Li goto failure;
959*a58d3d2aSXin Li }
960*a58d3d2aSXin Li if (fwrite(data, 1, len, fout) != (unsigned)len) {
961*a58d3d2aSXin Li fprintf(stderr, "Error writing.\n");
962*a58d3d2aSXin Li goto failure;
963*a58d3d2aSXin Li }
964*a58d3d2aSXin Li tot_samples += nb_encoded;
965*a58d3d2aSXin Li } else {
966*a58d3d2aSXin Li int fr;
967*a58d3d2aSXin Li int run_decoder;
968*a58d3d2aSXin Li int dred_input=0;
969*a58d3d2aSXin Li int dred_end=0;
970*a58d3d2aSXin Li if (packet_loss_file != NULL) {
971*a58d3d2aSXin Li if ( fscanf(packet_loss_file, "%d", &lost) != 1) {
972*a58d3d2aSXin Li lost = 0;
973*a58d3d2aSXin Li }
974*a58d3d2aSXin Li #ifdef ENABLE_LOSSGEN
975*a58d3d2aSXin Li } else if (lossgen_perc >= 0) {
976*a58d3d2aSXin Li lost = sample_loss(&lossgen, lossgen_perc*.01f);
977*a58d3d2aSXin Li #endif
978*a58d3d2aSXin Li } else {
979*a58d3d2aSXin Li lost = (packet_loss_perc>0) && (rand()%100 < packet_loss_perc);
980*a58d3d2aSXin Li }
981*a58d3d2aSXin Li if (len == 0) lost = 1;
982*a58d3d2aSXin Li if (lost)
983*a58d3d2aSXin Li {
984*a58d3d2aSXin Li lost_count++;
985*a58d3d2aSXin Li run_decoder = 0;
986*a58d3d2aSXin Li } else {
987*a58d3d2aSXin Li run_decoder= 1;
988*a58d3d2aSXin Li }
989*a58d3d2aSXin Li if (run_decoder)
990*a58d3d2aSXin Li run_decoder += lost_count;
991*a58d3d2aSXin Li if (!lost && lost_count > 0) {
992*a58d3d2aSXin Li opus_int32 output_samples=0;
993*a58d3d2aSXin Li opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));
994*a58d3d2aSXin Li dred_input = lost_count*output_samples;
995*a58d3d2aSXin Li /* Only decode the amount we need to fill in the gap. */
996*a58d3d2aSXin Li ret = opus_dred_parse(dred_dec, dred, data, len, IMIN(48000, IMAX(0, dred_input)), sampling_rate, &dred_end, 0);
997*a58d3d2aSXin Li dred_input = ret > 0 ? ret : 0;
998*a58d3d2aSXin Li }
999*a58d3d2aSXin Li /* FIXME: Figure out how to trigger the decoder when the last packet of the file is lost. */
1000*a58d3d2aSXin Li for (fr=0;fr<run_decoder;fr++) {
1001*a58d3d2aSXin Li opus_int32 output_samples=0;
1002*a58d3d2aSXin Li if (fr == lost_count-1 && opus_packet_has_lbrr(data, len)) {
1003*a58d3d2aSXin Li opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));
1004*a58d3d2aSXin Li output_samples = opus_decode(dec, data, len, out, output_samples, 1);
1005*a58d3d2aSXin Li } else if (fr < lost_count) {
1006*a58d3d2aSXin Li opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));
1007*a58d3d2aSXin Li if (dred_input > 0)
1008*a58d3d2aSXin Li output_samples = opus_decoder_dred_decode(dec, dred, (lost_count-fr)*output_samples, out, output_samples);
1009*a58d3d2aSXin Li else
1010*a58d3d2aSXin Li output_samples = opus_decode(dec, NULL, 0, out, output_samples, 0);
1011*a58d3d2aSXin Li } else {
1012*a58d3d2aSXin Li output_samples = max_frame_size;
1013*a58d3d2aSXin Li output_samples = opus_decode(dec, data, len, out, output_samples, 0);
1014*a58d3d2aSXin Li }
1015*a58d3d2aSXin Li if (output_samples>0)
1016*a58d3d2aSXin Li {
1017*a58d3d2aSXin Li if (!decode_only && tot_out + output_samples > tot_in)
1018*a58d3d2aSXin Li {
1019*a58d3d2aSXin Li stop=1;
1020*a58d3d2aSXin Li output_samples = (opus_int32)(tot_in - tot_out);
1021*a58d3d2aSXin Li }
1022*a58d3d2aSXin Li if (output_samples>skip) {
1023*a58d3d2aSXin Li int i;
1024*a58d3d2aSXin Li for(i=0;i<(output_samples-skip)*channels;i++)
1025*a58d3d2aSXin Li {
1026*a58d3d2aSXin Li short s;
1027*a58d3d2aSXin Li s=out[i+(skip*channels)];
1028*a58d3d2aSXin Li fbytes[2*i]=s&0xFF;
1029*a58d3d2aSXin Li fbytes[2*i+1]=(s>>8)&0xFF;
1030*a58d3d2aSXin Li }
1031*a58d3d2aSXin Li if (fwrite(fbytes, sizeof(short)*channels, output_samples-skip, fout) != (unsigned)(output_samples-skip)){
1032*a58d3d2aSXin Li fprintf(stderr, "Error writing.\n");
1033*a58d3d2aSXin Li goto failure;
1034*a58d3d2aSXin Li }
1035*a58d3d2aSXin Li tot_out += output_samples-skip;
1036*a58d3d2aSXin Li }
1037*a58d3d2aSXin Li if (output_samples<skip) skip -= output_samples;
1038*a58d3d2aSXin Li else skip = 0;
1039*a58d3d2aSXin Li } else {
1040*a58d3d2aSXin Li fprintf(stderr, "error decoding frame: %s\n",
1041*a58d3d2aSXin Li opus_strerror(output_samples));
1042*a58d3d2aSXin Li }
1043*a58d3d2aSXin Li tot_samples += output_samples;
1044*a58d3d2aSXin Li }
1045*a58d3d2aSXin Li }
1046*a58d3d2aSXin Li
1047*a58d3d2aSXin Li if (!encode_only)
1048*a58d3d2aSXin Li opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range));
1049*a58d3d2aSXin Li /* compare final range encoder rng values of encoder and decoder */
1050*a58d3d2aSXin Li if( enc_final_range!=0 && !encode_only
1051*a58d3d2aSXin Li && !lost && !lost_prev
1052*a58d3d2aSXin Li && dec_final_range != enc_final_range ) {
1053*a58d3d2aSXin Li fprintf (stderr, "Error: Range coder state mismatch "
1054*a58d3d2aSXin Li "between encoder and decoder "
1055*a58d3d2aSXin Li "in frame %ld: 0x%8lx vs 0x%8lx\n",
1056*a58d3d2aSXin Li (long)count,
1057*a58d3d2aSXin Li (unsigned long)enc_final_range,
1058*a58d3d2aSXin Li (unsigned long)dec_final_range);
1059*a58d3d2aSXin Li goto failure;
1060*a58d3d2aSXin Li }
1061*a58d3d2aSXin Li
1062*a58d3d2aSXin Li lost_prev = lost;
1063*a58d3d2aSXin Li if (!lost)
1064*a58d3d2aSXin Li lost_count = 0;
1065*a58d3d2aSXin Li if( count >= use_inbandfec ) {
1066*a58d3d2aSXin Li /* count bits */
1067*a58d3d2aSXin Li bits += len*8;
1068*a58d3d2aSXin Li bits_max = ( len*8 > bits_max ) ? len*8 : bits_max;
1069*a58d3d2aSXin Li bits2 += len*len*64;
1070*a58d3d2aSXin Li if (!decode_only)
1071*a58d3d2aSXin Li {
1072*a58d3d2aSXin Li nrg = 0.0;
1073*a58d3d2aSXin Li for ( k = 0; k < frame_size * channels; k++ ) {
1074*a58d3d2aSXin Li nrg += in[ k ] * (double)in[ k ];
1075*a58d3d2aSXin Li }
1076*a58d3d2aSXin Li nrg /= frame_size * channels;
1077*a58d3d2aSXin Li if( nrg > 1e5 ) {
1078*a58d3d2aSXin Li bits_act += len*8;
1079*a58d3d2aSXin Li count_act++;
1080*a58d3d2aSXin Li }
1081*a58d3d2aSXin Li }
1082*a58d3d2aSXin Li }
1083*a58d3d2aSXin Li count++;
1084*a58d3d2aSXin Li }
1085*a58d3d2aSXin Li
1086*a58d3d2aSXin Li if(decode_only && count > 0)
1087*a58d3d2aSXin Li frame_size = (int)(tot_samples / count);
1088*a58d3d2aSXin Li count -= use_inbandfec;
1089*a58d3d2aSXin Li if (tot_samples >= 1 && count > 0 && frame_size)
1090*a58d3d2aSXin Li {
1091*a58d3d2aSXin Li /* Print out bitrate statistics */
1092*a58d3d2aSXin Li double var;
1093*a58d3d2aSXin Li fprintf (stderr, "average bitrate: %7.3f kb/s\n",
1094*a58d3d2aSXin Li 1e-3*bits*sampling_rate/tot_samples);
1095*a58d3d2aSXin Li fprintf (stderr, "maximum bitrate: %7.3f kb/s\n",
1096*a58d3d2aSXin Li 1e-3*bits_max*sampling_rate/frame_size);
1097*a58d3d2aSXin Li if (!decode_only)
1098*a58d3d2aSXin Li fprintf (stderr, "active bitrate: %7.3f kb/s\n",
1099*a58d3d2aSXin Li 1e-3*bits_act*sampling_rate/(1e-15+frame_size*(double)count_act));
1100*a58d3d2aSXin Li var = bits2/count - bits*bits/(count*(double)count);
1101*a58d3d2aSXin Li if (var < 0)
1102*a58d3d2aSXin Li var = 0;
1103*a58d3d2aSXin Li fprintf (stderr, "bitrate standard deviation: %7.3f kb/s\n",
1104*a58d3d2aSXin Li 1e-3*sqrt(var)*sampling_rate/frame_size);
1105*a58d3d2aSXin Li } else {
1106*a58d3d2aSXin Li fprintf(stderr, "bitrate statistics are undefined\n");
1107*a58d3d2aSXin Li }
1108*a58d3d2aSXin Li silk_TimerSave("opus_timing.txt");
1109*a58d3d2aSXin Li ret = EXIT_SUCCESS;
1110*a58d3d2aSXin Li failure:
1111*a58d3d2aSXin Li opus_encoder_destroy(enc);
1112*a58d3d2aSXin Li opus_decoder_destroy(dec);
1113*a58d3d2aSXin Li opus_dred_free(dred);
1114*a58d3d2aSXin Li opus_dred_decoder_destroy(dred_dec);
1115*a58d3d2aSXin Li free(data);
1116*a58d3d2aSXin Li if (fin)
1117*a58d3d2aSXin Li fclose(fin);
1118*a58d3d2aSXin Li if (fout)
1119*a58d3d2aSXin Li fclose(fout);
1120*a58d3d2aSXin Li free(in);
1121*a58d3d2aSXin Li free(out);
1122*a58d3d2aSXin Li free(fbytes);
1123*a58d3d2aSXin Li #ifdef USE_WEIGHTS_FILE
1124*a58d3d2aSXin Li free_blob(blob_data, blob_len);
1125*a58d3d2aSXin Li #endif
1126*a58d3d2aSXin Li return ret;
1127*a58d3d2aSXin Li }
1128