Attenuates the HF in hybrid mode to match what SILK does below the cutoff
authorKoen Vos <koen.vos@skype.net>
Thu, 12 Jul 2012 18:55:49 +0000 (14:55 -0400)
committerJean-Marc Valin <jmvalin@jmvalin.ca>
Wed, 10 Oct 2012 17:41:07 +0000 (13:41 -0400)
Conflicts:

src/opus_multistream.c
src/opus_private.h

src/opus_decoder.c
src/opus_encoder.c
src/opus_private.h

index 161bd02..be6ae40 100644 (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;
 }
index 4b6995d..61bddc2 100644 (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 */
index 52482bc..e4f4c76 100644 (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);