diff options
author | Koen Vos <koen.vos@skype.net> | 2012-07-12 22:55:49 +0400 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2012-10-10 21:41:07 +0400 |
commit | 0b00b3196713305443080aaf35f1ddc05ce94306 (patch) | |
tree | 64bc8bc50a7ae3a14920c4ed1c7d1eb7474a9920 /src | |
parent | b56c278b0edc7dff90b1a930e8b79edfb4fc4829 (diff) |
Attenuates the HF in hybrid mode to match what SILK does below the cutoff
Conflicts:
src/opus_multistream.c
src/opus_private.h
Diffstat (limited to 'src')
-rw-r--r-- | src/opus_decoder.c | 2 | ||||
-rw-r--r-- | src/opus_encoder.c | 62 | ||||
-rw-r--r-- | src/opus_private.h | 2 |
3 files changed, 41 insertions, 25 deletions
diff --git a/src/opus_decoder.c b/src/opus_decoder.c index 161bd026..be6ae401 100644 --- a/src/opus_decoder.c +++ b/src/opus_decoder.c @@ -693,7 +693,7 @@ static int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, *out_toc = toc; if (payload_offset) - *payload_offset = data-data0; + *payload_offset = (int)(data-data0); return count; } diff --git a/src/opus_encoder.c b/src/opus_encoder.c index 4b6995d1..61bddc2b 100644 --- a/src/opus_encoder.c +++ b/src/opus_encoder.c @@ -97,8 +97,8 @@ struct OpusEncoder { static const opus_int32 mono_voice_bandwidth_thresholds[8] = { 11000, 1000, /* NB<->MB */ 14000, 1000, /* MB<->WB */ - 21000, 2000, /* WB<->SWB */ - 29000, 2000, /* SWB<->FB */ + 17000, 1000, /* WB<->SWB */ + 20000, 1000, /* SWB<->FB */ }; static const opus_int32 mono_music_bandwidth_thresholds[8] = { 14000, 1000, /* MB not allowed */ @@ -946,37 +946,40 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s /* SILK processing */ if (st->mode != MODE_CELT_ONLY) { + opus_int32 total_bitRate, celt_rate, HB_gain_Q16; #ifdef FIXED_POINT const opus_int16 *pcm_silk; #else VARDECL(opus_int16, pcm_silk); ALLOC(pcm_silk, st->channels*frame_size, opus_int16); #endif - st->silk_mode.bitRate = 8*bytes_target*frame_rate; + + /* Distribute bits between SILK and CELT */ + total_bitRate = 8 * bytes_target * frame_rate; if( st->mode == MODE_HYBRID ) { - st->silk_mode.bitRate /= st->stream_channels; + /* Base rate for SILK */ + st->silk_mode.bitRate = st->stream_channels * ( 5000 + 1000 * ( st->Fs == 100 * frame_size ) ); if( curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND ) { - if( st->Fs == 100 * frame_size ) { - /* 24 kHz, 10 ms */ - st->silk_mode.bitRate = ( ( st->silk_mode.bitRate + 2000 + st->use_vbr * 1000 ) * 2 ) / 3; - } else { - /* 24 kHz, 20 ms */ - st->silk_mode.bitRate = ( ( st->silk_mode.bitRate + 1000 + st->use_vbr * 1000 ) * 2 ) / 3; - } - } else { - if( st->Fs == 100 * frame_size ) { - /* 48 kHz, 10 ms */ - st->silk_mode.bitRate = ( st->silk_mode.bitRate + 8000 + st->use_vbr * 3000 ) / 2; - } else { - /* 48 kHz, 20 ms */ - st->silk_mode.bitRate = ( st->silk_mode.bitRate + 9000 + st->use_vbr * 1000 ) / 2; - } + /* SILK gets 2/3 of the remaining bits */ + st->silk_mode.bitRate += ( total_bitRate - st->silk_mode.bitRate ) * 2 / 3; + } else { /* FULLBAND */ + /* SILK gets 3/5 of the remaining bits */ + st->silk_mode.bitRate += ( total_bitRate - st->silk_mode.bitRate ) * 3 / 5; } - st->silk_mode.bitRate *= st->stream_channels; - /* don't let SILK use more than 80% */ - if( st->silk_mode.bitRate > ( st->bitrate_bps - 8*st->Fs/frame_size ) * 4/5 ) { - st->silk_mode.bitRate = ( st->bitrate_bps - 8*st->Fs/frame_size ) * 4/5; + /* Don't let SILK use more than 80% */ + if( st->silk_mode.bitRate > total_bitRate * 4/5 ) { + st->silk_mode.bitRate = total_bitRate * 4/5; } + /* Increasingly attenuate high band when it gets allocated fewer bits */ + celt_rate = total_bitRate - st->silk_mode.bitRate; + if( curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND ) { + HB_gain_Q16 = ( celt_rate << 10 ) / ( ( celt_rate + st->stream_channels * 2000 ) >> 6 ); + } else { /* FULLBAND */ + HB_gain_Q16 = ( celt_rate << 10 ) / ( ( celt_rate + st->stream_channels * 2400 ) >> 6 ); + } + } else { + /* SILK gets all bits */ + st->silk_mode.bitRate = total_bitRate; } st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs; @@ -1086,6 +1089,19 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s celt_to_silk = 0; st->silk_bw_switch = 1; } + + if( st->mode == MODE_HYBRID ) { +#ifdef FIXED_POINT + for (i=0;i<frame_size*st->channels;i++) { + pcm_buf[delay_compensation*st->channels + i] = (opus_val16)( ( HB_gain_Q16 * pcm_buf[delay_compensation*st->channels + i] ) >> 16 ); + } +#else + float HB_gain = HB_gain_Q16 / 65536.0f; + for (i=0;i<frame_size*st->channels;i++) { + pcm_buf[delay_compensation*st->channels + i] *= HB_gain; + } +#endif + } } /* CELT processing */ diff --git a/src/opus_private.h b/src/opus_private.h index 52482bc1..e4f4c76e 100644 --- a/src/opus_private.h +++ b/src/opus_private.h @@ -77,7 +77,7 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data, opus_int32 le /* Make sure everything's aligned to sizeof(void *) bytes */ static inline int align(int i) { - return (i+sizeof(void *)-1)&-((int)sizeof(void *)); + return (i+(int)sizeof(void *)-1)&-(int)sizeof(void *); } opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen, int self_delimited); |