diff options
Diffstat (limited to 'lib/rbcodec/codecs/libopus/opus_demo.c')
-rw-r--r-- | lib/rbcodec/codecs/libopus/opus_demo.c | 892 |
1 files changed, 892 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libopus/opus_demo.c b/lib/rbcodec/codecs/libopus/opus_demo.c new file mode 100644 index 0000000000..4cc26a6c77 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/opus_demo.c | |||
@@ -0,0 +1,892 @@ | |||
1 | /* Copyright (c) 2007-2008 CSIRO | ||
2 | Copyright (c) 2007-2009 Xiph.Org Foundation | ||
3 | Written by Jean-Marc Valin */ | ||
4 | /* | ||
5 | Redistribution and use in source and binary forms, with or without | ||
6 | modification, are permitted provided that the following conditions | ||
7 | are met: | ||
8 | |||
9 | - Redistributions of source code must retain the above copyright | ||
10 | notice, this list of conditions and the following disclaimer. | ||
11 | |||
12 | - Redistributions in binary form must reproduce the above copyright | ||
13 | notice, this list of conditions and the following disclaimer in the | ||
14 | documentation and/or other materials provided with the distribution. | ||
15 | |||
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
17 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
20 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
21 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
22 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
23 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
27 | */ | ||
28 | |||
29 | #ifdef HAVE_CONFIG_H | ||
30 | #include "config.h" | ||
31 | #endif | ||
32 | |||
33 | #include <stdio.h> | ||
34 | #include <stdlib.h> | ||
35 | #include <math.h> | ||
36 | #include <string.h> | ||
37 | #include "opus.h" | ||
38 | #include "debug.h" | ||
39 | #include "opus_types.h" | ||
40 | #include "opus_private.h" | ||
41 | #include "opus_multistream.h" | ||
42 | |||
43 | #define MAX_PACKET 1500 | ||
44 | |||
45 | void print_usage( char* argv[] ) | ||
46 | { | ||
47 | fprintf(stderr, "Usage: %s [-e] <application> <sampling rate (Hz)> <channels (1/2)> " | ||
48 | "<bits per second> [options] <input> <output>\n", argv[0]); | ||
49 | fprintf(stderr, " %s -d <sampling rate (Hz)> <channels (1/2)> " | ||
50 | "[options] <input> <output>\n\n", argv[0]); | ||
51 | fprintf(stderr, "application: voip | audio | restricted-lowdelay\n" ); | ||
52 | fprintf(stderr, "options:\n" ); | ||
53 | fprintf(stderr, "-e : only runs the encoder (output the bit-stream)\n" ); | ||
54 | fprintf(stderr, "-d : only runs the decoder (reads the bit-stream as input)\n" ); | ||
55 | fprintf(stderr, "-cbr : enable constant bitrate; default: variable bitrate\n" ); | ||
56 | fprintf(stderr, "-cvbr : enable constrained variable bitrate; default: unconstrained\n" ); | ||
57 | fprintf(stderr, "-delayed-decision : use look-ahead for speech/music detection (experts only); default: disabled\n" ); | ||
58 | fprintf(stderr, "-bandwidth <NB|MB|WB|SWB|FB> : audio bandwidth (from narrowband to fullband); default: sampling rate\n" ); | ||
59 | fprintf(stderr, "-framesize <2.5|5|10|20|40|60|80|100|120> : frame size in ms; default: 20 \n" ); | ||
60 | fprintf(stderr, "-max_payload <bytes> : maximum payload size in bytes, default: 1024\n" ); | ||
61 | fprintf(stderr, "-complexity <comp> : complexity, 0 (lowest) ... 10 (highest); default: 10\n" ); | ||
62 | fprintf(stderr, "-inbandfec : enable SILK inband FEC\n" ); | ||
63 | fprintf(stderr, "-forcemono : force mono encoding, even for stereo input\n" ); | ||
64 | fprintf(stderr, "-dtx : enable SILK DTX\n" ); | ||
65 | fprintf(stderr, "-loss <perc> : simulate packet loss, in percent (0-100); default: 0\n" ); | ||
66 | } | ||
67 | |||
68 | static void int_to_char(opus_uint32 i, unsigned char ch[4]) | ||
69 | { | ||
70 | ch[0] = i>>24; | ||
71 | ch[1] = (i>>16)&0xFF; | ||
72 | ch[2] = (i>>8)&0xFF; | ||
73 | ch[3] = i&0xFF; | ||
74 | } | ||
75 | |||
76 | static opus_uint32 char_to_int(unsigned char ch[4]) | ||
77 | { | ||
78 | return ((opus_uint32)ch[0]<<24) | ((opus_uint32)ch[1]<<16) | ||
79 | | ((opus_uint32)ch[2]<< 8) | (opus_uint32)ch[3]; | ||
80 | } | ||
81 | |||
82 | #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) | ||
83 | |||
84 | static const int silk8_test[][4] = { | ||
85 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 1}, | ||
86 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 1}, | ||
87 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 1}, | ||
88 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 1}, | ||
89 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 2}, | ||
90 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 2}, | ||
91 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 2}, | ||
92 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 2} | ||
93 | }; | ||
94 | |||
95 | static const int silk12_test[][4] = { | ||
96 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 1}, | ||
97 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 1}, | ||
98 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960, 1}, | ||
99 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480, 1}, | ||
100 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 2}, | ||
101 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 2}, | ||
102 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960, 2}, | ||
103 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480, 2} | ||
104 | }; | ||
105 | |||
106 | static const int silk16_test[][4] = { | ||
107 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 1}, | ||
108 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 1}, | ||
109 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 1}, | ||
110 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 1}, | ||
111 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 2}, | ||
112 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 2}, | ||
113 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 2}, | ||
114 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 2} | ||
115 | }; | ||
116 | |||
117 | static const int hybrid24_test[][4] = { | ||
118 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1}, | ||
119 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1}, | ||
120 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2}, | ||
121 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2} | ||
122 | }; | ||
123 | |||
124 | static const int hybrid48_test[][4] = { | ||
125 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 1}, | ||
126 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 1}, | ||
127 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2}, | ||
128 | {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2} | ||
129 | }; | ||
130 | |||
131 | static const int celt_test[][4] = { | ||
132 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 1}, | ||
133 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1}, | ||
134 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 1}, | ||
135 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 1}, | ||
136 | |||
137 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 1}, | ||
138 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1}, | ||
139 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 1}, | ||
140 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 1}, | ||
141 | |||
142 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 240, 1}, | ||
143 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 240, 1}, | ||
144 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 240, 1}, | ||
145 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 240, 1}, | ||
146 | |||
147 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 120, 1}, | ||
148 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 120, 1}, | ||
149 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 120, 1}, | ||
150 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 120, 1}, | ||
151 | |||
152 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2}, | ||
153 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2}, | ||
154 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 2}, | ||
155 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 2}, | ||
156 | |||
157 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2}, | ||
158 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2}, | ||
159 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 2}, | ||
160 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 2}, | ||
161 | |||
162 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 240, 2}, | ||
163 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 240, 2}, | ||
164 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 240, 2}, | ||
165 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 240, 2}, | ||
166 | |||
167 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 120, 2}, | ||
168 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 120, 2}, | ||
169 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 120, 2}, | ||
170 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 120, 2}, | ||
171 | |||
172 | }; | ||
173 | |||
174 | static const int celt_hq_test[][4] = { | ||
175 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2}, | ||
176 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2}, | ||
177 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 240, 2}, | ||
178 | {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 120, 2}, | ||
179 | }; | ||
180 | |||
181 | #if 0 /* This is a hack that replaces the normal encoder/decoder with the multistream version */ | ||
182 | #define OpusEncoder OpusMSEncoder | ||
183 | #define OpusDecoder OpusMSDecoder | ||
184 | #define opus_encode opus_multistream_encode | ||
185 | #define opus_decode opus_multistream_decode | ||
186 | #define opus_encoder_ctl opus_multistream_encoder_ctl | ||
187 | #define opus_decoder_ctl opus_multistream_decoder_ctl | ||
188 | #define opus_encoder_create ms_opus_encoder_create | ||
189 | #define opus_decoder_create ms_opus_decoder_create | ||
190 | #define opus_encoder_destroy opus_multistream_encoder_destroy | ||
191 | #define opus_decoder_destroy opus_multistream_decoder_destroy | ||
192 | |||
193 | static OpusEncoder *ms_opus_encoder_create(opus_int32 Fs, int channels, int application, int *error) | ||
194 | { | ||
195 | int streams, coupled_streams; | ||
196 | unsigned char mapping[256]; | ||
197 | return (OpusEncoder *)opus_multistream_surround_encoder_create(Fs, channels, 1, &streams, &coupled_streams, mapping, application, error); | ||
198 | } | ||
199 | static OpusDecoder *ms_opus_decoder_create(opus_int32 Fs, int channels, int *error) | ||
200 | { | ||
201 | int streams; | ||
202 | int coupled_streams; | ||
203 | unsigned char mapping[256]={0,1}; | ||
204 | streams = 1; | ||
205 | coupled_streams = channels==2; | ||
206 | return (OpusDecoder *)opus_multistream_decoder_create(Fs, channels, streams, coupled_streams, mapping, error); | ||
207 | } | ||
208 | #endif | ||
209 | |||
210 | int main(int argc, char *argv[]) | ||
211 | { | ||
212 | int err; | ||
213 | char *inFile, *outFile; | ||
214 | FILE *fin=NULL; | ||
215 | FILE *fout=NULL; | ||
216 | OpusEncoder *enc=NULL; | ||
217 | OpusDecoder *dec=NULL; | ||
218 | int args; | ||
219 | int len[2]; | ||
220 | int frame_size, channels; | ||
221 | opus_int32 bitrate_bps=0; | ||
222 | unsigned char *data[2] = {NULL, NULL}; | ||
223 | unsigned char *fbytes=NULL; | ||
224 | opus_int32 sampling_rate; | ||
225 | int use_vbr; | ||
226 | int max_payload_bytes; | ||
227 | int complexity; | ||
228 | int use_inbandfec; | ||
229 | int use_dtx; | ||
230 | int forcechannels; | ||
231 | int cvbr = 0; | ||
232 | int packet_loss_perc; | ||
233 | opus_int32 count=0, count_act=0; | ||
234 | int k; | ||
235 | opus_int32 skip=0; | ||
236 | int stop=0; | ||
237 | short *in=NULL; | ||
238 | short *out=NULL; | ||
239 | int application=OPUS_APPLICATION_AUDIO; | ||
240 | double bits=0.0, bits_max=0.0, bits_act=0.0, bits2=0.0, nrg; | ||
241 | double tot_samples=0; | ||
242 | opus_uint64 tot_in, tot_out; | ||
243 | int bandwidth=OPUS_AUTO; | ||
244 | const char *bandwidth_string; | ||
245 | int lost = 0, lost_prev = 1; | ||
246 | int toggle = 0; | ||
247 | opus_uint32 enc_final_range[2]; | ||
248 | opus_uint32 dec_final_range; | ||
249 | int encode_only=0, decode_only=0; | ||
250 | int max_frame_size = 48000*2; | ||
251 | size_t num_read; | ||
252 | int curr_read=0; | ||
253 | int sweep_bps = 0; | ||
254 | int random_framesize=0, newsize=0, delayed_celt=0; | ||
255 | int sweep_max=0, sweep_min=0; | ||
256 | int random_fec=0; | ||
257 | const int (*mode_list)[4]=NULL; | ||
258 | int nb_modes_in_list=0; | ||
259 | int curr_mode=0; | ||
260 | int curr_mode_count=0; | ||
261 | int mode_switch_time = 48000; | ||
262 | int nb_encoded=0; | ||
263 | int remaining=0; | ||
264 | int variable_duration=OPUS_FRAMESIZE_ARG; | ||
265 | int delayed_decision=0; | ||
266 | int ret = EXIT_FAILURE; | ||
267 | |||
268 | if (argc < 5 ) | ||
269 | { | ||
270 | print_usage( argv ); | ||
271 | goto failure; | ||
272 | } | ||
273 | |||
274 | tot_in=tot_out=0; | ||
275 | fprintf(stderr, "%s\n", opus_get_version_string()); | ||
276 | |||
277 | args = 1; | ||
278 | if (strcmp(argv[args], "-e")==0) | ||
279 | { | ||
280 | encode_only = 1; | ||
281 | args++; | ||
282 | } else if (strcmp(argv[args], "-d")==0) | ||
283 | { | ||
284 | decode_only = 1; | ||
285 | args++; | ||
286 | } | ||
287 | if (!decode_only && argc < 7 ) | ||
288 | { | ||
289 | print_usage( argv ); | ||
290 | goto failure; | ||
291 | } | ||
292 | |||
293 | if (!decode_only) | ||
294 | { | ||
295 | if (strcmp(argv[args], "voip")==0) | ||
296 | application = OPUS_APPLICATION_VOIP; | ||
297 | else if (strcmp(argv[args], "restricted-lowdelay")==0) | ||
298 | application = OPUS_APPLICATION_RESTRICTED_LOWDELAY; | ||
299 | else if (strcmp(argv[args], "audio")!=0) { | ||
300 | fprintf(stderr, "unknown application: %s\n", argv[args]); | ||
301 | print_usage(argv); | ||
302 | goto failure; | ||
303 | } | ||
304 | args++; | ||
305 | } | ||
306 | sampling_rate = (opus_int32)atol(argv[args]); | ||
307 | args++; | ||
308 | |||
309 | if (sampling_rate != 8000 && sampling_rate != 12000 | ||
310 | && sampling_rate != 16000 && sampling_rate != 24000 | ||
311 | && sampling_rate != 48000) | ||
312 | { | ||
313 | fprintf(stderr, "Supported sampling rates are 8000, 12000, " | ||
314 | "16000, 24000 and 48000.\n"); | ||
315 | goto failure; | ||
316 | } | ||
317 | frame_size = sampling_rate/50; | ||
318 | |||
319 | channels = atoi(argv[args]); | ||
320 | args++; | ||
321 | |||
322 | if (channels < 1 || channels > 2) | ||
323 | { | ||
324 | fprintf(stderr, "Opus_demo supports only 1 or 2 channels.\n"); | ||
325 | goto failure; | ||
326 | } | ||
327 | |||
328 | if (!decode_only) | ||
329 | { | ||
330 | bitrate_bps = (opus_int32)atol(argv[args]); | ||
331 | args++; | ||
332 | } | ||
333 | |||
334 | /* defaults: */ | ||
335 | use_vbr = 1; | ||
336 | max_payload_bytes = MAX_PACKET; | ||
337 | complexity = 10; | ||
338 | use_inbandfec = 0; | ||
339 | forcechannels = OPUS_AUTO; | ||
340 | use_dtx = 0; | ||
341 | packet_loss_perc = 0; | ||
342 | |||
343 | while( args < argc - 2 ) { | ||
344 | /* process command line options */ | ||
345 | if( strcmp( argv[ args ], "-cbr" ) == 0 ) { | ||
346 | check_encoder_option(decode_only, "-cbr"); | ||
347 | use_vbr = 0; | ||
348 | args++; | ||
349 | } else if( strcmp( argv[ args ], "-bandwidth" ) == 0 ) { | ||
350 | check_encoder_option(decode_only, "-bandwidth"); | ||
351 | if (strcmp(argv[ args + 1 ], "NB")==0) | ||
352 | bandwidth = OPUS_BANDWIDTH_NARROWBAND; | ||
353 | else if (strcmp(argv[ args + 1 ], "MB")==0) | ||
354 | bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; | ||
355 | else if (strcmp(argv[ args + 1 ], "WB")==0) | ||
356 | bandwidth = OPUS_BANDWIDTH_WIDEBAND; | ||
357 | else if (strcmp(argv[ args + 1 ], "SWB")==0) | ||
358 | bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; | ||
359 | else if (strcmp(argv[ args + 1 ], "FB")==0) | ||
360 | bandwidth = OPUS_BANDWIDTH_FULLBAND; | ||
361 | else { | ||
362 | fprintf(stderr, "Unknown bandwidth %s. " | ||
363 | "Supported are NB, MB, WB, SWB, FB.\n", | ||
364 | argv[ args + 1 ]); | ||
365 | goto failure; | ||
366 | } | ||
367 | args += 2; | ||
368 | } else if( strcmp( argv[ args ], "-framesize" ) == 0 ) { | ||
369 | check_encoder_option(decode_only, "-framesize"); | ||
370 | if (strcmp(argv[ args + 1 ], "2.5")==0) | ||
371 | frame_size = sampling_rate/400; | ||
372 | else if (strcmp(argv[ args + 1 ], "5")==0) | ||
373 | frame_size = sampling_rate/200; | ||
374 | else if (strcmp(argv[ args + 1 ], "10")==0) | ||
375 | frame_size = sampling_rate/100; | ||
376 | else if (strcmp(argv[ args + 1 ], "20")==0) | ||
377 | frame_size = sampling_rate/50; | ||
378 | else if (strcmp(argv[ args + 1 ], "40")==0) | ||
379 | frame_size = sampling_rate/25; | ||
380 | else if (strcmp(argv[ args + 1 ], "60")==0) | ||
381 | frame_size = 3*sampling_rate/50; | ||
382 | else if (strcmp(argv[ args + 1 ], "80")==0) | ||
383 | frame_size = 4*sampling_rate/50; | ||
384 | else if (strcmp(argv[ args + 1 ], "100")==0) | ||
385 | frame_size = 5*sampling_rate/50; | ||
386 | else if (strcmp(argv[ args + 1 ], "120")==0) | ||
387 | frame_size = 6*sampling_rate/50; | ||
388 | else { | ||
389 | fprintf(stderr, "Unsupported frame size: %s ms. " | ||
390 | "Supported are 2.5, 5, 10, 20, 40, 60, 80, 100, 120.\n", | ||
391 | argv[ args + 1 ]); | ||
392 | goto failure; | ||
393 | } | ||
394 | args += 2; | ||
395 | } else if( strcmp( argv[ args ], "-max_payload" ) == 0 ) { | ||
396 | check_encoder_option(decode_only, "-max_payload"); | ||
397 | max_payload_bytes = atoi( argv[ args + 1 ] ); | ||
398 | args += 2; | ||
399 | } else if( strcmp( argv[ args ], "-complexity" ) == 0 ) { | ||
400 | check_encoder_option(decode_only, "-complexity"); | ||
401 | complexity = atoi( argv[ args + 1 ] ); | ||
402 | args += 2; | ||
403 | } else if( strcmp( argv[ args ], "-inbandfec" ) == 0 ) { | ||
404 | use_inbandfec = 1; | ||
405 | args++; | ||
406 | } else if( strcmp( argv[ args ], "-forcemono" ) == 0 ) { | ||
407 | check_encoder_option(decode_only, "-forcemono"); | ||
408 | forcechannels = 1; | ||
409 | args++; | ||
410 | } else if( strcmp( argv[ args ], "-cvbr" ) == 0 ) { | ||
411 | check_encoder_option(decode_only, "-cvbr"); | ||
412 | cvbr = 1; | ||
413 | args++; | ||
414 | } else if( strcmp( argv[ args ], "-delayed-decision" ) == 0 ) { | ||
415 | check_encoder_option(decode_only, "-delayed-decision"); | ||
416 | delayed_decision = 1; | ||
417 | args++; | ||
418 | } else if( strcmp( argv[ args ], "-dtx") == 0 ) { | ||
419 | check_encoder_option(decode_only, "-dtx"); | ||
420 | use_dtx = 1; | ||
421 | args++; | ||
422 | } else if( strcmp( argv[ args ], "-loss" ) == 0 ) { | ||
423 | packet_loss_perc = atoi( argv[ args + 1 ] ); | ||
424 | args += 2; | ||
425 | } else if( strcmp( argv[ args ], "-sweep" ) == 0 ) { | ||
426 | check_encoder_option(decode_only, "-sweep"); | ||
427 | sweep_bps = atoi( argv[ args + 1 ] ); | ||
428 | args += 2; | ||
429 | } else if( strcmp( argv[ args ], "-random_framesize" ) == 0 ) { | ||
430 | check_encoder_option(decode_only, "-random_framesize"); | ||
431 | random_framesize = 1; | ||
432 | args++; | ||
433 | } else if( strcmp( argv[ args ], "-sweep_max" ) == 0 ) { | ||
434 | check_encoder_option(decode_only, "-sweep_max"); | ||
435 | sweep_max = atoi( argv[ args + 1 ] ); | ||
436 | args += 2; | ||
437 | } else if( strcmp( argv[ args ], "-random_fec" ) == 0 ) { | ||
438 | check_encoder_option(decode_only, "-random_fec"); | ||
439 | random_fec = 1; | ||
440 | args++; | ||
441 | } else if( strcmp( argv[ args ], "-silk8k_test" ) == 0 ) { | ||
442 | check_encoder_option(decode_only, "-silk8k_test"); | ||
443 | mode_list = silk8_test; | ||
444 | nb_modes_in_list = 8; | ||
445 | args++; | ||
446 | } else if( strcmp( argv[ args ], "-silk12k_test" ) == 0 ) { | ||
447 | check_encoder_option(decode_only, "-silk12k_test"); | ||
448 | mode_list = silk12_test; | ||
449 | nb_modes_in_list = 8; | ||
450 | args++; | ||
451 | } else if( strcmp( argv[ args ], "-silk16k_test" ) == 0 ) { | ||
452 | check_encoder_option(decode_only, "-silk16k_test"); | ||
453 | mode_list = silk16_test; | ||
454 | nb_modes_in_list = 8; | ||
455 | args++; | ||
456 | } else if( strcmp( argv[ args ], "-hybrid24k_test" ) == 0 ) { | ||
457 | check_encoder_option(decode_only, "-hybrid24k_test"); | ||
458 | mode_list = hybrid24_test; | ||
459 | nb_modes_in_list = 4; | ||
460 | args++; | ||
461 | } else if( strcmp( argv[ args ], "-hybrid48k_test" ) == 0 ) { | ||
462 | check_encoder_option(decode_only, "-hybrid48k_test"); | ||
463 | mode_list = hybrid48_test; | ||
464 | nb_modes_in_list = 4; | ||
465 | args++; | ||
466 | } else if( strcmp( argv[ args ], "-celt_test" ) == 0 ) { | ||
467 | check_encoder_option(decode_only, "-celt_test"); | ||
468 | mode_list = celt_test; | ||
469 | nb_modes_in_list = 32; | ||
470 | args++; | ||
471 | } else if( strcmp( argv[ args ], "-celt_hq_test" ) == 0 ) { | ||
472 | check_encoder_option(decode_only, "-celt_hq_test"); | ||
473 | mode_list = celt_hq_test; | ||
474 | nb_modes_in_list = 4; | ||
475 | args++; | ||
476 | } else { | ||
477 | printf( "Error: unrecognized setting: %s\n\n", argv[ args ] ); | ||
478 | print_usage( argv ); | ||
479 | goto failure; | ||
480 | } | ||
481 | } | ||
482 | |||
483 | if (sweep_max) | ||
484 | sweep_min = bitrate_bps; | ||
485 | |||
486 | if (max_payload_bytes < 0 || max_payload_bytes > MAX_PACKET) | ||
487 | { | ||
488 | fprintf (stderr, "max_payload_bytes must be between 0 and %d\n", | ||
489 | MAX_PACKET); | ||
490 | goto failure; | ||
491 | } | ||
492 | |||
493 | inFile = argv[argc-2]; | ||
494 | fin = fopen(inFile, "rb"); | ||
495 | if (!fin) | ||
496 | { | ||
497 | fprintf (stderr, "Could not open input file %s\n", argv[argc-2]); | ||
498 | goto failure; | ||
499 | } | ||
500 | if (mode_list) | ||
501 | { | ||
502 | int size; | ||
503 | fseek(fin, 0, SEEK_END); | ||
504 | size = ftell(fin); | ||
505 | fprintf(stderr, "File size is %d bytes\n", size); | ||
506 | fseek(fin, 0, SEEK_SET); | ||
507 | mode_switch_time = size/sizeof(short)/channels/nb_modes_in_list; | ||
508 | fprintf(stderr, "Switching mode every %d samples\n", mode_switch_time); | ||
509 | } | ||
510 | |||
511 | outFile = argv[argc-1]; | ||
512 | fout = fopen(outFile, "wb+"); | ||
513 | if (!fout) | ||
514 | { | ||
515 | fprintf (stderr, "Could not open output file %s\n", argv[argc-1]); | ||
516 | goto failure; | ||
517 | } | ||
518 | |||
519 | if (!decode_only) | ||
520 | { | ||
521 | enc = opus_encoder_create(sampling_rate, channels, application, &err); | ||
522 | if (err != OPUS_OK) | ||
523 | { | ||
524 | fprintf(stderr, "Cannot create encoder: %s\n", opus_strerror(err)); | ||
525 | goto failure; | ||
526 | } | ||
527 | opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps)); | ||
528 | opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bandwidth)); | ||
529 | opus_encoder_ctl(enc, OPUS_SET_VBR(use_vbr)); | ||
530 | opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(cvbr)); | ||
531 | opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity)); | ||
532 | opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(use_inbandfec)); | ||
533 | opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(forcechannels)); | ||
534 | opus_encoder_ctl(enc, OPUS_SET_DTX(use_dtx)); | ||
535 | opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packet_loss_perc)); | ||
536 | |||
537 | opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&skip)); | ||
538 | opus_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(16)); | ||
539 | opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration)); | ||
540 | } | ||
541 | if (!encode_only) | ||
542 | { | ||
543 | dec = opus_decoder_create(sampling_rate, channels, &err); | ||
544 | if (err != OPUS_OK) | ||
545 | { | ||
546 | fprintf(stderr, "Cannot create decoder: %s\n", opus_strerror(err)); | ||
547 | goto failure; | ||
548 | } | ||
549 | } | ||
550 | |||
551 | |||
552 | switch(bandwidth) | ||
553 | { | ||
554 | case OPUS_BANDWIDTH_NARROWBAND: | ||
555 | bandwidth_string = "narrowband"; | ||
556 | break; | ||
557 | case OPUS_BANDWIDTH_MEDIUMBAND: | ||
558 | bandwidth_string = "mediumband"; | ||
559 | break; | ||
560 | case OPUS_BANDWIDTH_WIDEBAND: | ||
561 | bandwidth_string = "wideband"; | ||
562 | break; | ||
563 | case OPUS_BANDWIDTH_SUPERWIDEBAND: | ||
564 | bandwidth_string = "superwideband"; | ||
565 | break; | ||
566 | case OPUS_BANDWIDTH_FULLBAND: | ||
567 | bandwidth_string = "fullband"; | ||
568 | break; | ||
569 | case OPUS_AUTO: | ||
570 | bandwidth_string = "auto bandwidth"; | ||
571 | break; | ||
572 | default: | ||
573 | bandwidth_string = "unknown"; | ||
574 | break; | ||
575 | } | ||
576 | |||
577 | if (decode_only) | ||
578 | fprintf(stderr, "Decoding with %ld Hz output (%d channels)\n", | ||
579 | (long)sampling_rate, channels); | ||
580 | else | ||
581 | fprintf(stderr, "Encoding %ld Hz input at %.3f kb/s " | ||
582 | "in %s with %d-sample frames.\n", | ||
583 | (long)sampling_rate, bitrate_bps*0.001, | ||
584 | bandwidth_string, frame_size); | ||
585 | |||
586 | in = (short*)malloc(max_frame_size*channels*sizeof(short)); | ||
587 | out = (short*)malloc(max_frame_size*channels*sizeof(short)); | ||
588 | /* We need to allocate for 16-bit PCM data, but we store it as unsigned char. */ | ||
589 | fbytes = (unsigned char*)malloc(max_frame_size*channels*sizeof(short)); | ||
590 | data[0] = (unsigned char*)calloc(max_payload_bytes,sizeof(unsigned char)); | ||
591 | if ( use_inbandfec ) { | ||
592 | data[1] = (unsigned char*)calloc(max_payload_bytes,sizeof(unsigned char)); | ||
593 | } | ||
594 | if(delayed_decision) | ||
595 | { | ||
596 | if (frame_size==sampling_rate/400) | ||
597 | variable_duration = OPUS_FRAMESIZE_2_5_MS; | ||
598 | else if (frame_size==sampling_rate/200) | ||
599 | variable_duration = OPUS_FRAMESIZE_5_MS; | ||
600 | else if (frame_size==sampling_rate/100) | ||
601 | variable_duration = OPUS_FRAMESIZE_10_MS; | ||
602 | else if (frame_size==sampling_rate/50) | ||
603 | variable_duration = OPUS_FRAMESIZE_20_MS; | ||
604 | else if (frame_size==sampling_rate/25) | ||
605 | variable_duration = OPUS_FRAMESIZE_40_MS; | ||
606 | else if (frame_size==3*sampling_rate/50) | ||
607 | variable_duration = OPUS_FRAMESIZE_60_MS; | ||
608 | else if (frame_size==4*sampling_rate/50) | ||
609 | variable_duration = OPUS_FRAMESIZE_80_MS; | ||
610 | else if (frame_size==5*sampling_rate/50) | ||
611 | variable_duration = OPUS_FRAMESIZE_100_MS; | ||
612 | else | ||
613 | variable_duration = OPUS_FRAMESIZE_120_MS; | ||
614 | opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration)); | ||
615 | frame_size = 2*48000; | ||
616 | } | ||
617 | while (!stop) | ||
618 | { | ||
619 | if (delayed_celt) | ||
620 | { | ||
621 | frame_size = newsize; | ||
622 | delayed_celt = 0; | ||
623 | } else if (random_framesize && rand()%20==0) | ||
624 | { | ||
625 | newsize = rand()%6; | ||
626 | switch(newsize) | ||
627 | { | ||
628 | case 0: newsize=sampling_rate/400; break; | ||
629 | case 1: newsize=sampling_rate/200; break; | ||
630 | case 2: newsize=sampling_rate/100; break; | ||
631 | case 3: newsize=sampling_rate/50; break; | ||
632 | case 4: newsize=sampling_rate/25; break; | ||
633 | case 5: newsize=3*sampling_rate/50; break; | ||
634 | } | ||
635 | while (newsize < sampling_rate/25 && bitrate_bps-abs(sweep_bps) <= 3*12*sampling_rate/newsize) | ||
636 | newsize*=2; | ||
637 | if (newsize < sampling_rate/100 && frame_size >= sampling_rate/100) | ||
638 | { | ||
639 | opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY)); | ||
640 | delayed_celt=1; | ||
641 | } else { | ||
642 | frame_size = newsize; | ||
643 | } | ||
644 | } | ||
645 | if (random_fec && rand()%30==0) | ||
646 | { | ||
647 | opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(rand()%4==0)); | ||
648 | } | ||
649 | if (decode_only) | ||
650 | { | ||
651 | unsigned char ch[4]; | ||
652 | num_read = fread(ch, 1, 4, fin); | ||
653 | if (num_read!=4) | ||
654 | break; | ||
655 | len[toggle] = char_to_int(ch); | ||
656 | if (len[toggle]>max_payload_bytes || len[toggle]<0) | ||
657 | { | ||
658 | fprintf(stderr, "Invalid payload length: %d\n",len[toggle]); | ||
659 | break; | ||
660 | } | ||
661 | num_read = fread(ch, 1, 4, fin); | ||
662 | if (num_read!=4) | ||
663 | break; | ||
664 | enc_final_range[toggle] = char_to_int(ch); | ||
665 | num_read = fread(data[toggle], 1, len[toggle], fin); | ||
666 | if (num_read!=(size_t)len[toggle]) | ||
667 | { | ||
668 | fprintf(stderr, "Ran out of input, " | ||
669 | "expecting %d bytes got %d\n", | ||
670 | len[toggle],(int)num_read); | ||
671 | break; | ||
672 | } | ||
673 | } else { | ||
674 | int i; | ||
675 | if (mode_list!=NULL) | ||
676 | { | ||
677 | opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(mode_list[curr_mode][1])); | ||
678 | opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(mode_list[curr_mode][0])); | ||
679 | opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(mode_list[curr_mode][3])); | ||
680 | frame_size = mode_list[curr_mode][2]; | ||
681 | } | ||
682 | num_read = fread(fbytes, sizeof(short)*channels, frame_size-remaining, fin); | ||
683 | curr_read = (int)num_read; | ||
684 | tot_in += curr_read; | ||
685 | for(i=0;i<curr_read*channels;i++) | ||
686 | { | ||
687 | opus_int32 s; | ||
688 | s=fbytes[2*i+1]<<8|fbytes[2*i]; | ||
689 | s=((s&0xFFFF)^0x8000)-0x8000; | ||
690 | in[i+remaining*channels]=s; | ||
691 | } | ||
692 | if (curr_read+remaining < frame_size) | ||
693 | { | ||
694 | for (i=(curr_read+remaining)*channels;i<frame_size*channels;i++) | ||
695 | in[i] = 0; | ||
696 | if (encode_only || decode_only) | ||
697 | stop = 1; | ||
698 | } | ||
699 | len[toggle] = opus_encode(enc, in, frame_size, data[toggle], max_payload_bytes); | ||
700 | nb_encoded = opus_packet_get_samples_per_frame(data[toggle], sampling_rate)*opus_packet_get_nb_frames(data[toggle], len[toggle]); | ||
701 | remaining = frame_size-nb_encoded; | ||
702 | for(i=0;i<remaining*channels;i++) | ||
703 | in[i] = in[nb_encoded*channels+i]; | ||
704 | if (sweep_bps!=0) | ||
705 | { | ||
706 | bitrate_bps += sweep_bps; | ||
707 | if (sweep_max) | ||
708 | { | ||
709 | if (bitrate_bps > sweep_max) | ||
710 | sweep_bps = -sweep_bps; | ||
711 | else if (bitrate_bps < sweep_min) | ||
712 | sweep_bps = -sweep_bps; | ||
713 | } | ||
714 | /* safety */ | ||
715 | if (bitrate_bps<1000) | ||
716 | bitrate_bps = 1000; | ||
717 | opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps)); | ||
718 | } | ||
719 | opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range[toggle])); | ||
720 | if (len[toggle] < 0) | ||
721 | { | ||
722 | fprintf (stderr, "opus_encode() returned %d\n", len[toggle]); | ||
723 | goto failure; | ||
724 | } | ||
725 | curr_mode_count += frame_size; | ||
726 | if (curr_mode_count > mode_switch_time && curr_mode < nb_modes_in_list-1) | ||
727 | { | ||
728 | curr_mode++; | ||
729 | curr_mode_count = 0; | ||
730 | } | ||
731 | } | ||
732 | |||
733 | #if 0 /* This is for testing the padding code, do not enable by default */ | ||
734 | if (len[toggle]<1275) | ||
735 | { | ||
736 | int new_len = len[toggle]+rand()%(max_payload_bytes-len[toggle]); | ||
737 | if ((err = opus_packet_pad(data[toggle], len[toggle], new_len)) != OPUS_OK) | ||
738 | { | ||
739 | fprintf(stderr, "padding failed: %s\n", opus_strerror(err)); | ||
740 | goto failure; | ||
741 | } | ||
742 | len[toggle] = new_len; | ||
743 | } | ||
744 | #endif | ||
745 | if (encode_only) | ||
746 | { | ||
747 | unsigned char int_field[4]; | ||
748 | int_to_char(len[toggle], int_field); | ||
749 | if (fwrite(int_field, 1, 4, fout) != 4) { | ||
750 | fprintf(stderr, "Error writing.\n"); | ||
751 | goto failure; | ||
752 | } | ||
753 | int_to_char(enc_final_range[toggle], int_field); | ||
754 | if (fwrite(int_field, 1, 4, fout) != 4) { | ||
755 | fprintf(stderr, "Error writing.\n"); | ||
756 | goto failure; | ||
757 | } | ||
758 | if (fwrite(data[toggle], 1, len[toggle], fout) != (unsigned)len[toggle]) { | ||
759 | fprintf(stderr, "Error writing.\n"); | ||
760 | goto failure; | ||
761 | } | ||
762 | tot_samples += nb_encoded; | ||
763 | } else { | ||
764 | opus_int32 output_samples; | ||
765 | lost = len[toggle]==0 || (packet_loss_perc>0 && rand()%100 < packet_loss_perc); | ||
766 | if (lost) | ||
767 | opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples)); | ||
768 | else | ||
769 | output_samples = max_frame_size; | ||
770 | if( count >= use_inbandfec ) { | ||
771 | /* delay by one packet when using in-band FEC */ | ||
772 | if( use_inbandfec ) { | ||
773 | if( lost_prev ) { | ||
774 | /* attempt to decode with in-band FEC from next packet */ | ||
775 | opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples)); | ||
776 | output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 1); | ||
777 | } else { | ||
778 | /* regular decode */ | ||
779 | output_samples = max_frame_size; | ||
780 | output_samples = opus_decode(dec, data[1-toggle], len[1-toggle], out, output_samples, 0); | ||
781 | } | ||
782 | } else { | ||
783 | output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 0); | ||
784 | } | ||
785 | if (output_samples>0) | ||
786 | { | ||
787 | if (!decode_only && tot_out + output_samples > tot_in) | ||
788 | { | ||
789 | stop=1; | ||
790 | output_samples = (opus_int32)(tot_in - tot_out); | ||
791 | } | ||
792 | if (output_samples>skip) { | ||
793 | int i; | ||
794 | for(i=0;i<(output_samples-skip)*channels;i++) | ||
795 | { | ||
796 | short s; | ||
797 | s=out[i+(skip*channels)]; | ||
798 | fbytes[2*i]=s&0xFF; | ||
799 | fbytes[2*i+1]=(s>>8)&0xFF; | ||
800 | } | ||
801 | if (fwrite(fbytes, sizeof(short)*channels, output_samples-skip, fout) != (unsigned)(output_samples-skip)){ | ||
802 | fprintf(stderr, "Error writing.\n"); | ||
803 | goto failure; | ||
804 | } | ||
805 | tot_out += output_samples-skip; | ||
806 | } | ||
807 | if (output_samples<skip) skip -= output_samples; | ||
808 | else skip = 0; | ||
809 | } else { | ||
810 | fprintf(stderr, "error decoding frame: %s\n", | ||
811 | opus_strerror(output_samples)); | ||
812 | } | ||
813 | tot_samples += output_samples; | ||
814 | } | ||
815 | } | ||
816 | |||
817 | if (!encode_only) | ||
818 | opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range)); | ||
819 | /* compare final range encoder rng values of encoder and decoder */ | ||
820 | if( enc_final_range[toggle^use_inbandfec]!=0 && !encode_only | ||
821 | && !lost && !lost_prev | ||
822 | && dec_final_range != enc_final_range[toggle^use_inbandfec] ) { | ||
823 | fprintf (stderr, "Error: Range coder state mismatch " | ||
824 | "between encoder and decoder " | ||
825 | "in frame %ld: 0x%8lx vs 0x%8lx\n", | ||
826 | (long)count, | ||
827 | (unsigned long)enc_final_range[toggle^use_inbandfec], | ||
828 | (unsigned long)dec_final_range); | ||
829 | goto failure; | ||
830 | } | ||
831 | |||
832 | lost_prev = lost; | ||
833 | if( count >= use_inbandfec ) { | ||
834 | /* count bits */ | ||
835 | bits += len[toggle]*8; | ||
836 | bits_max = ( len[toggle]*8 > bits_max ) ? len[toggle]*8 : bits_max; | ||
837 | bits2 += len[toggle]*len[toggle]*64; | ||
838 | if (!decode_only) | ||
839 | { | ||
840 | nrg = 0.0; | ||
841 | for ( k = 0; k < frame_size * channels; k++ ) { | ||
842 | nrg += in[ k ] * (double)in[ k ]; | ||
843 | } | ||
844 | nrg /= frame_size * channels; | ||
845 | if( nrg > 1e5 ) { | ||
846 | bits_act += len[toggle]*8; | ||
847 | count_act++; | ||
848 | } | ||
849 | } | ||
850 | } | ||
851 | count++; | ||
852 | toggle = (toggle + use_inbandfec) & 1; | ||
853 | } | ||
854 | |||
855 | if(decode_only && count > 0) | ||
856 | frame_size = (int)(tot_samples / count); | ||
857 | count -= use_inbandfec; | ||
858 | if (tot_samples >= 1 && count > 0 && frame_size) | ||
859 | { | ||
860 | /* Print out bitrate statistics */ | ||
861 | double var; | ||
862 | fprintf (stderr, "average bitrate: %7.3f kb/s\n", | ||
863 | 1e-3*bits*sampling_rate/tot_samples); | ||
864 | fprintf (stderr, "maximum bitrate: %7.3f kb/s\n", | ||
865 | 1e-3*bits_max*sampling_rate/frame_size); | ||
866 | if (!decode_only) | ||
867 | fprintf (stderr, "active bitrate: %7.3f kb/s\n", | ||
868 | 1e-3*bits_act*sampling_rate/(1e-15+frame_size*(double)count_act)); | ||
869 | var = bits2/count - bits*bits/(count*(double)count); | ||
870 | if (var < 0) | ||
871 | var = 0; | ||
872 | fprintf (stderr, "bitrate standard deviation: %7.3f kb/s\n", | ||
873 | 1e-3*sqrt(var)*sampling_rate/frame_size); | ||
874 | } else { | ||
875 | fprintf(stderr, "bitrate statistics are undefined\n"); | ||
876 | } | ||
877 | silk_TimerSave("opus_timing.txt"); | ||
878 | ret = EXIT_SUCCESS; | ||
879 | failure: | ||
880 | opus_encoder_destroy(enc); | ||
881 | opus_decoder_destroy(dec); | ||
882 | free(data[0]); | ||
883 | free(data[1]); | ||
884 | if (fin) | ||
885 | fclose(fin); | ||
886 | if (fout) | ||
887 | fclose(fout); | ||
888 | free(in); | ||
889 | free(out); | ||
890 | free(fbytes); | ||
891 | return ret; | ||
892 | } | ||