X-Git-Url: https://git.xiph.org/?p=opus.git;a=blobdiff_plain;f=src%2Fopus_demo.c;h=9771ed8bb81c3914e743da7a7520a9477d7573ee;hp=bc357902986ad3127cb49983bc320f316b43d8aa;hb=1ad6f6d557d06289a58abb726f987e5e79688924;hpb=cf1053dc85625deff2dfd600c83e9201b314f46b diff --git a/src/opus_demo.c b/src/opus_demo.c index bc357902..9771ed8b 100644 --- a/src/opus_demo.c +++ b/src/opus_demo.c @@ -38,6 +38,7 @@ #include "debug.h" #include "opus_types.h" #include "opus_private.h" +#include "opus_multistream.h" #define MAX_PACKET 1500 @@ -53,6 +54,7 @@ void print_usage( char* argv[] ) 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" ); + fprintf(stderr, "-variable-duration : enable frames of variable duration (experts only); default: disabled\n" ); fprintf(stderr, "-bandwidth : audio bandwidth (from narrowband to fullband); default: sampling rate\n" ); fprintf(stderr, "-framesize <2.5|5|10|20|40|60> : frame size in ms; default: 20 \n" ); fprintf(stderr, "-max_payload : maximum payload size in bytes, default: 1024\n" ); @@ -95,7 +97,7 @@ static void check_encoder_option(int decode_only, const char *opt) } } -int silk8_test[][4] = { +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}, @@ -106,7 +108,7 @@ int silk8_test[][4] = { {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 2} }; -int silk12_test[][4] = { +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}, @@ -117,7 +119,7 @@ int silk12_test[][4] = { {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480, 2} }; -int silk16_test[][4] = { +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}, @@ -128,21 +130,21 @@ int silk16_test[][4] = { {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 2} }; -int hybrid24_test[][4] = { +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} }; -int hybrid48_test[][4] = { +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} }; -int celt_test[][4] = { +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}, @@ -185,13 +187,42 @@ int celt_test[][4] = { }; -int celt_hq_test[][4] = { +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}, }; +#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 + int main(int argc, char *argv[]) { int err; @@ -221,6 +252,8 @@ int main(int argc, char *argv[]) short *in, *out; int application=OPUS_APPLICATION_AUDIO; double bits=0.0, bits_max=0.0, bits_act=0.0, bits2=0.0, nrg; + double tot_samples=0; + opus_uint64 tot_in, tot_out; int bandwidth=-1; const char *bandwidth_string; int lost = 0, lost_prev = 1; @@ -234,11 +267,15 @@ int main(int argc, char *argv[]) int random_framesize=0, newsize=0, delayed_celt=0; int sweep_max=0, sweep_min=0; int random_fec=0; - int (*mode_list)[4]=NULL; + 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; + int nb_encoded=0; + int remaining=0; + int variable_duration=OPUS_FRAMESIZE_ARG; + int delayed_decision=0; if (argc < 5 ) { @@ -246,6 +283,7 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } + tot_in=tot_out=0; fprintf(stderr, "%s\n", opus_get_version_string()); args = 1; @@ -306,7 +344,7 @@ int main(int argc, char *argv[]) forcechannels = OPUS_AUTO; use_dtx = 0; packet_loss_perc = 0; - max_frame_size = 960*6; + max_frame_size = 2*48000; curr_read=0; while( args < argc - 2 ) { @@ -374,6 +412,14 @@ int main(int argc, char *argv[]) check_encoder_option(decode_only, "-cvbr"); cvbr = 1; args++; + } else if( strcmp( argv[ args ], "-variable-duration" ) == 0 ) { + check_encoder_option(decode_only, "-variable-duration"); + variable_duration = OPUS_FRAMESIZE_VARIABLE; + args++; + } else if( strcmp( argv[ args ], "-delayed-decision" ) == 0 ) { + check_encoder_option(decode_only, "-delayed-decision"); + delayed_decision = 1; + args++; } else if( strcmp( argv[ args ], "-dtx") == 0 ) { check_encoder_option(decode_only, "-dtx"); use_dtx = 1; @@ -499,6 +545,7 @@ int main(int argc, char *argv[]) opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&skip)); opus_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(16)); + opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration)); } if (!encode_only) { @@ -554,6 +601,26 @@ int main(int argc, char *argv[]) if ( use_inbandfec ) { data[1] = (unsigned char*)calloc(max_payload_bytes,sizeof(char)); } + if(delayed_decision) + { + if (variable_duration!=OPUS_FRAMESIZE_VARIABLE) + { + 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 + variable_duration = OPUS_FRAMESIZE_60_MS; + opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration)); + } + frame_size = 2*48000; + } while (!stop) { if (delayed_celt) @@ -617,22 +684,28 @@ int main(int argc, char *argv[]) opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(mode_list[curr_mode][3])); frame_size = mode_list[curr_mode][2]; } - err = fread(fbytes, sizeof(short)*channels, frame_size, fin); + err = fread(fbytes, sizeof(short)*channels, frame_size-remaining, fin); curr_read = err; + tot_in += curr_read; for(i=0;i0 && 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 */ - output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, max_frame_size, 1); + opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples)); + output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 1); } else { /* regular decode */ - output_samples = opus_decode(dec, data[1-toggle], len[1-toggle], out, max_frame_size, 0); + output_samples = max_frame_size; + 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, max_frame_size, 0); + output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 0); } if (output_samples>0) { + if (!decode_only && tot_out + output_samples > tot_in) + { + stop=1; + output_samples = tot_in-tot_out; + } if (output_samples>skip) { int i; for(i=0;i<(output_samples-skip)*channels;i++) @@ -712,6 +797,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "Error writing.\n"); return EXIT_FAILURE; } + tot_out += output_samples-skip; } if (output_samples