Simplifying fast_atan2f()
[opus.git] / src / opus_encoder.c
index 5b911c7..4a1bd47 100644 (file)
@@ -114,27 +114,27 @@ struct OpusEncoder {
    (difference with the middle) */
 static const opus_int32 mono_voice_bandwidth_thresholds[8] = {
         11000, 1000, /* NB<->MB */
-        14000, 1000, /* MB<->WB */
-        17000, 1000, /* WB<->SWB */
-        21000, 2000, /* SWB<->FB */
+        12500, 1000, /* MB<->WB */
+        14000, 1000, /* WB<->SWB */
+        15000, 2000, /* SWB<->FB */
 };
 static const opus_int32 mono_music_bandwidth_thresholds[8] = {
-        12000, 1000, /* NB<->MB */
-        15000, 1000, /* MB<->WB */
-        18000, 2000, /* WB<->SWB */
-        22000, 2000, /* SWB<->FB */
+        11000, 1000, /* NB<->MB */
+        12500, 1000, /* MB<->WB */
+        14000, 1000, /* WB<->SWB */
+        15000, 2000, /* SWB<->FB */
 };
 static const opus_int32 stereo_voice_bandwidth_thresholds[8] = {
         11000, 1000, /* NB<->MB */
-        14000, 1000, /* MB<->WB */
-        21000, 2000, /* WB<->SWB */
-        28000, 2000, /* SWB<->FB */
+        12500, 1000, /* MB<->WB */
+        14000, 1000, /* WB<->SWB */
+        15000, 2000, /* SWB<->FB */
 };
 static const opus_int32 stereo_music_bandwidth_thresholds[8] = {
-        12000, 1000, /* NB<->MB */
-        18000, 2000, /* MB<->WB */
-        20000, 2000, /* WB<->SWB */
-        24000, 2000, /* SWB<->FB */
+        11000, 1000, /* NB<->MB */
+        12500, 1000, /* MB<->WB */
+        14000, 1000, /* WB<->SWB */
+        15000, 2000, /* SWB<->FB */
 };
 /* Threshold bit-rates for switching between mono and stereo */
 static const opus_int32 stereo_voice_threshold = 24000;
@@ -934,6 +934,80 @@ opus_val16 compute_stereo_width(const opus_val16 *pcm, int frame_size, opus_int3
    return EXTRACT16(MIN32(Q15ONE, MULT16_16(20, mem->max_follower)));
 }
 
+static int compute_silk_rate_for_hybrid(int rate, int bandwidth, int frame20ms, int vbr) {
+   int entry;
+   int i;
+   int N;
+   int silk_rate;
+   static int rate_table[][5] = {
+  /*  |total| |-------- SILK------------|
+              SWB-10  FB-10 SWB-20  FB-20 */
+      {    0,     0,     0,     0,     0},
+      {12000, 10000, 10000, 10000, 10000},
+      {16000, 14000, 14000, 14000, 14000},
+      {20000, 16000, 16000, 16000, 16000},
+      {24000, 18000, 18000, 18000, 18000},
+      {32000, 22000, 22000, 22000, 22000},
+      {64000, 38000, 38000, 38000, 38000}
+   };
+   entry = 1 + 2*frame20ms + (bandwidth==OPUS_BANDWIDTH_FULLBAND);
+   N = sizeof(rate_table)/sizeof(rate_table[0]);
+   for (i=1;i<N;i++)
+   {
+      if (rate_table[i][0] > rate) break;
+   }
+   if (i == N)
+   {
+      silk_rate = rate_table[i-1][entry];
+      /* For now, just give 50% of the extra bits to SILK. */
+      silk_rate += (rate-rate_table[i-1][0])/2;
+   } else {
+      opus_int32 lo, hi, x0, x1;
+      lo = rate_table[i-1][entry];
+      hi = rate_table[i][entry];
+      x0 = rate_table[i-1][0];
+      x1 = rate_table[i][0];
+      silk_rate = (lo*(x1-rate) + hi*(rate-x0))/(x1-x0);
+   }
+   if (!vbr)
+   {
+      if (silk_rate > 8000)
+         silk_rate -= 1000;
+   }
+   return silk_rate;
+}
+
+/* Returns the equivalent bitrate corresponding to 20 ms frames,
+   complexity 10 VBR operation. */
+static opus_int32 compute_equiv_rate(opus_int32 bitrate, int channels,
+      int frame_rate, int vbr, int mode, int complexity)
+{
+   int equiv;
+   equiv = bitrate;
+   /* Take into account overhead from smaller frames. */
+   equiv -= (40*channels+20)*(frame_rate - 50);
+   /* CBR is about a 10% penalty for both SILK and CELT. */
+   if (!vbr)
+      equiv = equiv*9/10;
+   /* Complexity makes about 10% difference (from 0 to 10) in general. */
+   equiv = equiv * (90+complexity)/100;
+   if (mode == MODE_SILK_ONLY || mode == MODE_HYBRID)
+   {
+      /* SILK complexity 0-3 uses the non-delayed-decision NSQ, which
+         costs about 20%. */
+      if (complexity<4)
+         equiv = equiv*4/5;
+   } else if (mode == MODE_CELT_ONLY) {
+      /* CELT complexity 0-4 doesn't have the pitch filter, which costs
+         about 10%. */
+      if (complexity<5)
+         equiv = equiv*9/10;
+   } else {
+      /* Mode not known yet */
+   }
+   return equiv;
+}
+
 opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
                 unsigned char *data, opus_int32 out_data_bytes, int lsb_depth,
                 const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2,
@@ -1091,7 +1165,8 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
     max_rate = frame_rate*max_data_bytes*8;
 
     /* Equivalent 20-ms rate for mode/channel/bandwidth decisions */
-    equiv_rate = st->bitrate_bps - (40*st->channels+20)*(st->Fs/frame_size - 50);
+    equiv_rate = compute_equiv_rate(st->bitrate_bps, st->channels, st->Fs/frame_size,
+          st->use_vbr, 0, st->silk_mode.complexity);
 
     if (st->signal_type == OPUS_SIGNAL_VOICE)
        voice_est = 127;
@@ -1132,7 +1207,9 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
        }
 #endif
     }
-    equiv_rate = st->bitrate_bps - (40*st->stream_channels+20)*(st->Fs/frame_size - 50);
+    /* Update equivalent rate for channels decision. */
+    equiv_rate = compute_equiv_rate(st->bitrate_bps, st->stream_channels, st->Fs/frame_size,
+          st->use_vbr, 0, st->silk_mode.complexity);
 
     /* Mode selection depending on application and signal type */
     if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
@@ -1226,6 +1303,11 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
             }
         }
     }
+
+    /* Update equivalent rate with mode decision. */
+    equiv_rate = compute_equiv_rate(st->bitrate_bps, st->stream_channels, st->Fs/frame_size,
+          st->use_vbr, st->mode, st->silk_mode.complexity);
+
     /* For the first frame at a new SILK bandwidth */
     if (st->silk_bw_switch)
     {
@@ -1257,17 +1339,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
         const opus_int32 *voice_bandwidth_thresholds, *music_bandwidth_thresholds;
         opus_int32 bandwidth_thresholds[8];
         int bandwidth = OPUS_BANDWIDTH_FULLBAND;
-        opus_int32 equiv_rate2;
 
-        equiv_rate2 = equiv_rate;
-        if (st->mode != MODE_CELT_ONLY)
-        {
-           /* Adjust the threshold +/- 10% depending on complexity */
-           equiv_rate2 = equiv_rate2 * (45+st->silk_mode.complexity)/50;
-           /* CBR is less efficient by ~1 kb/s */
-           if (!st->use_vbr)
-              equiv_rate2 -= 1000;
-        }
         if (st->channels==2 && st->force_channels!=1)
         {
            voice_bandwidth_thresholds = stereo_voice_bandwidth_thresholds;
@@ -1293,7 +1365,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
                 else
                     threshold += hysteresis;
             }
-            if (equiv_rate2 >= threshold)
+            if (equiv_rate >= threshold)
                 break;
         } while (--bandwidth>OPUS_BANDWIDTH_NARROWBAND);
         st->bandwidth = bandwidth;
@@ -1502,27 +1574,14 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
         /* Distribute bits between SILK and CELT */
         total_bitRate = 8 * bytes_target * frame_rate;
         if( st->mode == MODE_HYBRID ) {
-            int HB_gain_ref;
             /* Base rate for SILK */
-            st->silk_mode.bitRate = st->stream_channels * ( 5000 + 1000 * ( st->Fs == 100 * frame_size ) );
-            if( curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND ) {
-                /* 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;
-            }
-            /* 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;
-            }
+            st->silk_mode.bitRate = compute_silk_rate_for_hybrid(total_bitRate,
+                  curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr);
             if (!st->energy_masking)
             {
                /* Increasingly attenuate high band when it gets allocated fewer bits */
                celt_rate = total_bitRate - st->silk_mode.bitRate;
-               HB_gain_ref = (curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND) ? 3000 : 3600;
-               HB_gain = SHL32((opus_val32)celt_rate, 9) / SHR32((opus_val32)celt_rate + st->stream_channels * HB_gain_ref, 6);
-               HB_gain = HB_gain < (opus_val32)Q15ONE*6/7 ? HB_gain + Q15ONE/7 : Q15ONE;
+               HB_gain = Q15ONE - SHR32(celt_exp2(-celt_rate * QCONST16(1.f/1024, 10)), 1);
             }
         } else {
             /* SILK gets all bits */
@@ -1733,7 +1792,9 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
             if (redundancy)
                len += st->mode == MODE_HYBRID ? 3 : 1;
             if( st->use_vbr ) {
-                nb_compr_bytes = len + bytes_target - (st->silk_mode.bitRate * frame_size) / (8 * st->Fs);
+                celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps-st->silk_mode.bitRate));
+                nb_compr_bytes = max_data_bytes-1-redundancy_bytes;
+                celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(0));
             } else {
                 /* check if SILK used up too much */
                 nb_compr_bytes = len > bytes_target ? len : bytes_target;
@@ -1851,6 +1912,14 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
     if (redundancy || st->mode != MODE_SILK_ONLY)
        celt_encoder_ctl(celt_enc, CELT_SET_ANALYSIS(&analysis_info));
 #endif
+    if (st->mode == MODE_HYBRID) {
+       SILKInfo info;
+       info.signalType = st->silk_mode.signalType;
+       info.offset = st->silk_mode.offset;
+       celt_encoder_ctl(celt_enc, CELT_SET_SILK_INFO(&info));
+    } else {
+       celt_encoder_ctl(celt_enc, CELT_SET_SILK_INFO((SILKInfo*)NULL));
+    }
 
     /* 5 ms redundant frame for CELT->SILK */
     if (redundancy && celt_to_silk)
@@ -1858,6 +1927,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
         int err;
         celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
         celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0));
+        celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX));
         err = celt_encode_with_ec(celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes, NULL);
         if (err < 0)
         {
@@ -1884,12 +1954,22 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
         /* If false, we already busted the budget and we'll end up with a "PLC packet" */
         if (ec_tell(&enc) <= 8*nb_compr_bytes)
         {
+           /* Set the bitrate again if it was overridden in the redundancy code above*/
+           if (redundancy && celt_to_silk && st->mode==MODE_HYBRID && st->use_vbr)
+              celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps-st->silk_mode.bitRate));
+           celt_encoder_ctl(celt_enc, OPUS_SET_VBR(st->use_vbr));
            ret = celt_encode_with_ec(celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc);
            if (ret < 0)
            {
               RESTORE_STACK;
               return OPUS_INTERNAL_ERROR;
            }
+           /* Put CELT->SILK redundancy data in the right place. */
+           if (redundancy && celt_to_silk && st->mode==MODE_HYBRID && st->use_vbr)
+           {
+              OPUS_COPY(data+ret, data+nb_compr_bytes, redundancy_bytes);
+              nb_compr_bytes = nb_compr_bytes+redundancy_bytes;
+           }
         }
     }
 
@@ -1905,7 +1985,15 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
         celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
         celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
         celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
+        celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0));
+        celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX));
 
+        if (st->mode == MODE_HYBRID)
+        {
+           /* Shrink packet to what the encoder actually used. */
+           nb_compr_bytes = ret;
+           ec_enc_shrink(&enc, nb_compr_bytes);
+        }
         /* NOTE: We could speed this up slightly (at the expense of code size) by just adding a function that prefills the buffer */
         celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, dummy, 2, NULL);