Attenuates the HF in hybrid mode to match what SILK does below the cutoff

Conflicts:

	src/opus_multistream.c
	src/opus_private.h
This commit is contained in:
Koen Vos 2012-07-12 14:55:49 -04:00 committed by Jean-Marc Valin
parent b56c278b0e
commit 0b00b31967
3 changed files with 41 additions and 25 deletions

View file

@ -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;
}

View file

@ -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 */

View file

@ -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);