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