diff --git a/celt b/celt index 0b405d1170122c859faab435405666506d52fa2e..b3c05b6be2a6579af55a625903e9e70687a4d77f 160000 --- a/celt +++ b/celt @@ -1 +1 @@ -Subproject commit 0b405d1170122c859faab435405666506d52fa2e +Subproject commit b3c05b6be2a6579af55a625903e9e70687a4d77f diff --git a/silk b/silk index fc06bda89e40f8adfa1af9cebf869e63ef693bb5..485d64dfdf4145bf45929c697cdb2b3eed9c91c1 160000 --- a/silk +++ b/silk @@ -1 +1 @@ -Subproject commit fc06bda89e40f8adfa1af9cebf869e63ef693bb5 +Subproject commit 485d64dfdf4145bf45929c697cdb2b3eed9c91c1 diff --git a/silk_headers.txt b/silk_headers.txt index 230082530e0905e406370e39ce929338891adce0..1157db7999bc937d27a9aba338d3e312babc2343 100644 --- a/silk_headers.txt +++ b/silk_headers.txt @@ -6,7 +6,7 @@ silk/interface/SKP_Silk_typedef.h silk/src_common/SKP_Silk_define.h silk/src_common/SKP_Silk_main.h silk/src_common/SKP_Silk_PLC.h -silk/src_common/SKP_Silk_setup_complexity.h +silk/src_common/SKP_Silk_setup.h silk/src_common/SKP_Silk_structs.h silk/src_common/SKP_Silk_tables.h silk/src_common/SKP_Silk_tables_NLSF_CB.h diff --git a/silk_sources.mk b/silk_sources.mk index 815ad4b6862646466dc28e12c953940120445768..7fc3e6e13f234dd37d6a39f5f1f73881bab5b2ac 100644 --- a/silk_sources.mk +++ b/silk_sources.mk @@ -13,13 +13,13 @@ silk/src_common/SKP_Silk_encode_indices.c \ silk/src_common/SKP_Silk_encode_pulses.c \ silk/src_common/SKP_Silk_gain_quant.c \ silk/src_common/SKP_Silk_interpolate.c \ +silk/src_common/SKP_Silk_LBRR_embed.c \ silk/src_common/SKP_Silk_LP_variable_cutoff.c \ silk/src_common/SKP_Silk_NLSF2A_stable.c \ silk/src_common/SKP_Silk_NLSF_MSVQ_decode.c \ silk/src_common/SKP_Silk_NSQ.c \ silk/src_common/SKP_Silk_NSQ_del_dec.c \ silk/src_common/SKP_Silk_PLC.c \ -silk/src_common/SKP_Silk_pulses_to_bytes.c \ silk/src_common/SKP_Silk_shell_coder.c \ silk/src_common/SKP_Silk_tables_gain.c \ silk/src_common/SKP_Silk_tables_LTP.c \ @@ -51,7 +51,6 @@ silk/src_FLP/SKP_Silk_NLSF_MSVQ_decode_FLP.c \ silk/src_FLP/SKP_Silk_NLSF_MSVQ_encode_FLP.c \ silk/src_FLP/SKP_Silk_NLSF_VQ_rate_distortion_FLP.c \ silk/src_FLP/SKP_Silk_NLSF_VQ_sum_error_FLP.c \ -silk/src_FLP/SKP_Silk_NLSF_VQ_weights_laroia_FLP.c \ silk/src_FLP/SKP_Silk_noise_shape_analysis_FLP.c \ silk/src_FLP/SKP_Silk_prefilter_FLP.c \ silk/src_FLP/SKP_Silk_process_gains_FLP.c \ @@ -111,12 +110,9 @@ silk/src_SigProc_FIX/SKP_Silk_schur.c \ silk/src_SigProc_FIX/SKP_Silk_sigm_Q15.c \ silk/src_SigProc_FIX/SKP_Silk_sort.c \ silk/src_SigProc_FIX/SKP_Silk_sum_sqr_shift.c \ -silk/src_SigProc_FLP/SKP_Silk_allpass_int_FLP.c \ silk/src_SigProc_FLP/SKP_Silk_autocorrelation_FLP.c \ silk/src_SigProc_FLP/SKP_Silk_burg_modified_FLP.c \ silk/src_SigProc_FLP/SKP_Silk_bwexpander_FLP.c \ -silk/src_SigProc_FLP/SKP_Silk_decimate2_coarse_FLP.c \ -silk/src_SigProc_FLP/SKP_Silk_decimate2_coarsest_FLP.c \ silk/src_SigProc_FLP/SKP_Silk_energy_FLP.c \ silk/src_SigProc_FLP/SKP_Silk_inner_product_FLP.c \ silk/src_SigProc_FLP/SKP_Silk_k2a_FLP.c \ diff --git a/src/opus.h b/src/opus.h index 6e42949edb58403af000877579c56dc724c557c3..a7c8569d384fbca8631e4e1dd27baaf23b66e480 100644 --- a/src/opus.h +++ b/src/opus.h @@ -114,7 +114,7 @@ OpusDecoder *opus_decoder_create(int Fs, int channels); /* returns (CELT) error code */ int opus_decode(OpusDecoder *st, const unsigned char *data, int len, - short *pcm, int frame_size); + short *pcm, int frame_size, int decode_fec); void opus_decoder_ctl(OpusDecoder *st, int request, ...); diff --git a/src/opus_decoder.c b/src/opus_decoder.c index 525ad9780a62c5d0ba982625520434bffa9a556e..624b7fe2309fc4a1078b799bd13026f4d2a345c7 100644 --- a/src/opus_decoder.c +++ b/src/opus_decoder.c @@ -71,7 +71,7 @@ OpusDecoder *opus_decoder_create(int Fs, int channels) } int opus_decode(OpusDecoder *st, const unsigned char *data, - int len, short *pcm, int frame_size) + int len, short *pcm, int frame_size, int decode_fec) { int i, silk_ret=0, celt_ret=0; ec_dec dec; @@ -131,6 +131,7 @@ int opus_decode(OpusDecoder *st, const unsigned char *data, /* SILK processing */ if (st->mode != MODE_CELT_ONLY) { + int lost_flag, decoded_samples; SKP_int16 *pcm_ptr = pcm; DecControl.API_sampleRate = st->Fs; DecControl.payloadSize_ms = 1000 * audiosize / st->Fs; @@ -149,15 +150,20 @@ int opus_decode(OpusDecoder *st, const unsigned char *data, DecControl.internalSampleRate = 16000; } + lost_flag = data == NULL ? 1 : 2 * decode_fec; + decoded_samples = 0; do { /* Call SILK decoder */ - silk_ret = SKP_Silk_SDK_Decode( st->silk_dec, &DecControl, data == NULL, &dec, len, pcm_ptr, &silk_frame_size ); + int first_frame = decoded_samples == 0; + silk_ret = SKP_Silk_SDK_Decode( st->silk_dec, &DecControl, + lost_flag, first_frame, &dec, len, pcm_ptr, &silk_frame_size ); if( silk_ret ) { fprintf (stderr, "SILK decode error\n"); /* Handle error */ } pcm_ptr += silk_frame_size; - } while( DecControl.moreInternalDecoderFrames ); + decoded_samples += silk_frame_size; + } while( decoded_samples < frame_size ); } else { for (i=0;i<frame_size*st->channels;i++) pcm[i] = 0; diff --git a/src/opus_encoder.c b/src/opus_encoder.c index 66da681fc1912804862822884554e18d8c401eb2..ca908916f352aa57398ef7a86e8c4ad3bd2d6473 100644 --- a/src/opus_encoder.c +++ b/src/opus_encoder.c @@ -134,7 +134,9 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size, } if( st->mode == MODE_HYBRID ) { /* Don't allow bandwidth reduction at lowest bitrates in hybrid mode */ - st->silk_mode.minInternalSampleRate = st->silk_mode.maxInternalSampleRate ; + st->silk_mode.minInternalSampleRate = 16000; + } else { + st->silk_mode.minInternalSampleRate = 8000; } /* Call SILK encoder for the low band */ diff --git a/src/test_opus.c b/src/test_opus.c index e8a6583e0a256b40e57f1b0a62d1884a2a63e924..e322be062b330f919ead41a2040058aa4c457119 100644 --- a/src/test_opus.c +++ b/src/test_opus.c @@ -71,10 +71,10 @@ int main(int argc, char *argv[]) OpusEncoder *enc; OpusDecoder *dec; int args; - int len; + int len[2]; int frame_size, channels; int bitrate_bps; - unsigned char *data; + unsigned char *data[2]; int sampling_rate; int use_vbr; int internal_sampling_rate_Hz; @@ -92,6 +92,10 @@ int main(int argc, char *argv[]) double bits=0.0, bits_act=0.0, bits2=0.0, nrg; int bandwidth=-1; const char *bandwidth_string; + int write_samples; + int lost, lost_prev = 1; + int toggle = 0; + int enc_final_range[2]; if (argc < 7 ) { @@ -257,20 +261,19 @@ int main(int argc, char *argv[]) enc = opus_encoder_create(sampling_rate, channels); dec = opus_decoder_create(sampling_rate, channels); - opus_encoder_ctl(enc, OPUS_SET_MODE(mode)); - opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps)); - if (bandwidth == -1) { fprintf (stderr, "Please specify a bandwidth when the sampling rate does not match one exactly\n"); return 1; } + opus_encoder_ctl(enc, OPUS_SET_MODE(mode)); + opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps)); opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bandwidth)); - opus_encoder_ctl(enc, OPUS_SET_VBR_FLAG(use_vbr)); opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity)); opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC_FLAG(use_inbandfec)); opus_encoder_ctl(enc, OPUS_SET_DTX_FLAG(use_dtx)); + opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packet_loss_perc)); skip = 5*sampling_rate/1000; /* When SILK resamples, add 18 samples delay */ @@ -302,11 +305,13 @@ int main(int argc, char *argv[]) in = (short*)malloc(frame_size*channels*sizeof(short)); out = (short*)malloc(frame_size*channels*sizeof(short)); - data = (unsigned char*)calloc(max_payload_bytes,sizeof(char)); + data[0] = (unsigned char*)calloc(max_payload_bytes,sizeof(char)); + if( use_inbandfec ) { + data[1] = (unsigned char*)calloc(max_payload_bytes,sizeof(char)); + } while (!stop) { - int write_samples; - int lost; + err = fread(in, sizeof(short), frame_size*channels, fin); tot_read += err; if (err < frame_size*channels) @@ -315,51 +320,75 @@ int main(int argc, char *argv[]) for (i=err;i<frame_size*channels;i++) in[i] = 0; } - len = opus_encode(enc, in, frame_size, data, max_payload_bytes); - if (len <= 0) + + len[toggle] = opus_encode(enc, in, frame_size, data[toggle], max_payload_bytes); +#if OPUS_TEST_RANGE_CODER_STATE + enc_final_range[toggle] = opus_encoder_get_final_range( enc ); +#endif + if (len[toggle] <= 0) { - fprintf (stderr, "opus_encode() returned %d\n", len); + fprintf (stderr, "opus_encode() returned %d\n", len[toggle]); return 1; } lost = rand()%100<packet_loss_perc; - opus_decode(dec, lost ? NULL : data, len, out, frame_size); - count++; - tot_written += (frame_size-skip)*channels; - write_samples = frame_size; - if (tot_written > tot_read && skip==0) - { - write_samples -= (tot_written-tot_read)/channels; - stop = 1; + 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 */ + opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, frame_size, 1); + } else { + /* regular decode */ + opus_decode(dec, data[1-toggle], len[1-toggle], out, frame_size, 0); + } + } else { + opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, frame_size, 0); + } + write_samples = frame_size-skip; + tot_written += write_samples*channels; + if (tot_written > tot_read) + { + write_samples -= (tot_written-tot_read)/channels; + stop = 1; + } + fwrite(out+skip, sizeof(short), write_samples*channels, fout); + skip = 0; } - fwrite(out+skip, sizeof(short), (write_samples-skip)*channels, fout); - skip = 0; #if OPUS_TEST_RANGE_CODER_STATE /* compare final range encoder rng values of encoder and decoder */ - if( !lost && opus_decoder_get_final_range( dec ) != opus_encoder_get_final_range( enc ) ) { + if( !lost && !lost_prev && opus_decoder_get_final_range( dec ) != enc_final_range[toggle^use_inbandfec] ) { fprintf (stderr, "Error: Range coder state mismatch between encoder and decoder.\n"); return 0; } #endif + lost_prev = lost; + /* count bits */ - bits += len*8; - nrg = 0.0; - for ( k = 0; k < frame_size * channels; k++ ) { - nrg += out[ k ] * (double)out[ k ]; + bits += len[toggle]*8; + if( count >= use_inbandfec ) { + nrg = 0.0; + for ( k = 0; k < frame_size * channels; k++ ) { + nrg += in[ k ] * (double)in[ k ]; + } + if ( ( nrg / ( frame_size * channels ) ) > 1e5 ) { + bits_act += len[toggle]*8; + count_act++; + } + /* Variance */ + bits2 += len[toggle]*len[toggle]*64; } - if ( ( nrg / ( frame_size * channels ) ) > 1e5 ) { - bits_act += len*8; - count_act++; - } - /* Variance */ - bits2 += len*len*64; + count++; + toggle = (toggle + use_inbandfec) & 1; } fprintf (stderr, "average bitrate: %7.3f kb/s\n", 1e-3*bits*sampling_rate/(frame_size*(double)count)); fprintf (stderr, "active bitrate: %7.3f kb/s\n", 1e-3*bits_act*sampling_rate/(frame_size*(double)count_act)); fprintf (stderr, "bitrate standard deviation: %7.3f kb/s\n", 1e-3*sqrt(bits2/count - bits*bits/(count*(double)count))*sampling_rate/frame_size); - DEBUG_STORE_CLOSE_FILES /* Close any files to which intermediate results were stored */ + /* Close any files to which intermediate results were stored */ + DEBUG_STORE_CLOSE_FILES + SKP_TimerSave("opus_timing.txt"); opus_encoder_destroy(enc); opus_decoder_destroy(dec); fclose(fin);