Index: src/opus_demo.c |
diff --git a/src/opus_demo.c b/src/opus_demo.c |
index 09b12a333d16560c0676078964b01cd000ba73f5..9771ed8bb81c3914e743da7a7520a9477d7573ee 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 <NB|MB|WB|SWB|FB> : 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 <bytes> : maximum payload size in bytes, default: 1024\n" ); |
@@ -192,6 +194,35 @@ static const int celt_hq_test[][4] = { |
{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; |
@@ -239,6 +272,10 @@ int main(int argc, char *argv[]) |
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;i<curr_read*channels;i++) |
{ |
opus_int32 s; |
s=fbytes[2*i+1]<<8|fbytes[2*i]; |
s=((s&0xFFFF)^0x8000)-0x8000; |
- in[i]=s; |
+ in[i+remaining*channels]=s; |
} |
- if (curr_read < frame_size) |
+ if (curr_read+remaining < frame_size) |
{ |
- for (i=curr_read*channels;i<frame_size*channels;i++) |
+ for (i=(curr_read+remaining)*channels;i<frame_size*channels;i++) |
in[i] = 0; |
- stop = 1; |
+ if (encode_only || decode_only) |
+ stop = 1; |
} |
len[toggle] = opus_encode(enc, in, frame_size, data[toggle], max_payload_bytes); |
+ 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]; |
if (sweep_bps!=0) |
{ |
bitrate_bps += sweep_bps; |
@@ -681,6 +754,7 @@ int main(int argc, char *argv[]) |
fprintf(stderr, "Error writing.\n"); |
return EXIT_FAILURE; |
} |
+ tot_samples += nb_encoded; |
} else { |
int output_samples; |
lost = len[toggle]==0 || (packet_loss_perc>0 && rand()%100 < packet_loss_perc); |
@@ -693,9 +767,11 @@ int main(int argc, char *argv[]) |
if( use_inbandfec ) { |
if( lost_prev ) { |
/* attempt to decode with in-band FEC from next packet */ |
+ 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 = max_frame_size; |
output_samples = opus_decode(dec, data[1-toggle], len[1-toggle], out, output_samples, 0); |
} |
} else { |
@@ -703,6 +779,11 @@ int main(int argc, char *argv[]) |
} |
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++) |
@@ -716,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<skip) skip -= output_samples; |
else skip = 0; |
@@ -723,6 +805,7 @@ int main(int argc, char *argv[]) |
fprintf(stderr, "error decoding frame: %s\n", |
opus_strerror(output_samples)); |
} |
+ tot_samples += output_samples; |
} |
} |
@@ -767,7 +850,7 @@ int main(int argc, char *argv[]) |
toggle = (toggle + use_inbandfec) & 1; |
} |
fprintf (stderr, "average bitrate: %7.3f kb/s\n", |
- 1e-3*bits*sampling_rate/(frame_size*(double)count)); |
+ 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) |