Fixing DTX for fixed-point too, updating project files
[opus.git] / src_FIX / SKP_Silk_control_codec_FIX.c
index 5c34fc1..b092460 100644 (file)
@@ -1,5 +1,5 @@
 /***********************************************************************\r
-Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Copyright (c) 2006-2011, Skype Limited. All rights reserved. \r
 Redistribution and use in source and binary forms, with or without \r
 modification, (subject to the limitations in the disclaimer below) \r
 are permitted provided that the following conditions are met:\r
@@ -26,9 +26,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ***********************************************************************/\r
 \r
 #include "SKP_Silk_main_FIX.h"\r
-#include "SKP_Silk_setup_complexity.h"\r
+#include "SKP_Silk_setup.h"\r
 \r
-/* ToDo: Move the functions belowto common to be able to use them in FLP control codec also */\r
 SKP_INLINE SKP_int SKP_Silk_setup_resamplers(\r
     SKP_Silk_encoder_state_FIX      *psEnc,             /* I/O                      */\r
     SKP_int                         fs_kHz              /* I                        */\r
@@ -42,11 +41,7 @@ SKP_INLINE SKP_int SKP_Silk_setup_fs(
 \r
 SKP_INLINE SKP_int SKP_Silk_setup_rate(\r
     SKP_Silk_encoder_state_FIX      *psEnc,             /* I/O                      */\r
-    SKP_int                         TargetRate_bps      /* I                        */\r
-);\r
-\r
-SKP_INLINE SKP_int SKP_Silk_setup_LBRR(\r
-    SKP_Silk_encoder_state_FIX      *psEnc              /* I/O                      */\r
+    SKP_int32                       TargetRate_bps      /* I                        */\r
 );\r
 \r
 /* Control encoder SNR */\r
@@ -60,7 +55,7 @@ SKP_int SKP_Silk_control_encoder_FIX(
 {\r
     SKP_int   fs_kHz, ret = 0;\r
 \r
-    if( psEnc->sCmn.controlled_since_last_payload != 0 ) {\r
+    if( psEnc->sCmn.controlled_since_last_payload != 0 && psEnc->sCmn.prefillFlag == 0 ) {\r
         if( psEnc->sCmn.API_fs_Hz != psEnc->sCmn.prev_API_fs_Hz && psEnc->sCmn.fs_kHz > 0 ) {\r
             /* Change in API sampling rate in the middle of encoding a packet */\r
             ret += SKP_Silk_setup_resamplers( psEnc, psEnc->sCmn.fs_kHz );\r
@@ -106,7 +101,7 @@ SKP_int SKP_Silk_control_encoder_FIX(
     /********************************************/\r
     /* Set LBRR usage                           */\r
     /********************************************/\r
-    ret += SKP_Silk_setup_LBRR( psEnc );\r
+    ret += SKP_Silk_setup_LBRR( &psEnc->sCmn );\r
 \r
     psEnc->sCmn.controlled_since_last_payload = 1;\r
 \r
@@ -181,128 +176,94 @@ SKP_INLINE SKP_int SKP_Silk_setup_fs(
             ( PacketSize_ms !=  60 ) ) {\r
             ret = SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED;\r
         }\r
-        if( PacketSize_ms == 10 ) {\r
-            /* Only allowed when the payload buffer is empty */\r
-            psEnc->sCmn.nb_subfr = MAX_NB_SUBFR >> 1;\r
-            psEnc->sPred.pitch_LPC_win_length = SKP_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz );\r
+        if( PacketSize_ms <= 10 ) {\r
+            psEnc->sCmn.nFramesPerPacket = 1;\r
+            psEnc->sCmn.nb_subfr = PacketSize_ms == 10 ? 2 : 1;\r
+            psEnc->sCmn.frame_length = SKP_SMULBB( PacketSize_ms, fs_kHz );\r
+            psEnc->sCmn.pitch_LPC_win_length = SKP_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz );\r
             if( psEnc->sCmn.fs_kHz == 8 ) {\r
                 psEnc->sCmn.pitch_contour_iCDF = SKP_Silk_pitch_contour_10_ms_NB_iCDF;\r
             } else {\r
                 psEnc->sCmn.pitch_contour_iCDF = SKP_Silk_pitch_contour_10_ms_iCDF;\r
             }\r
         } else {\r
+            psEnc->sCmn.nFramesPerPacket = SKP_DIV32_16( PacketSize_ms, MAX_FRAME_LENGTH_MS );\r
             psEnc->sCmn.nb_subfr = MAX_NB_SUBFR;\r
-            psEnc->sPred.pitch_LPC_win_length = SKP_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz );\r
+            psEnc->sCmn.frame_length = SKP_SMULBB( 20, fs_kHz );\r
+            psEnc->sCmn.pitch_LPC_win_length = SKP_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz );\r
             if( psEnc->sCmn.fs_kHz == 8 ) {\r
                 psEnc->sCmn.pitch_contour_iCDF = SKP_Silk_pitch_contour_NB_iCDF;\r
             } else {\r
                 psEnc->sCmn.pitch_contour_iCDF = SKP_Silk_pitch_contour_iCDF; \r
             }\r
         }\r
-        psEnc->sCmn.PacketSize_ms = PacketSize_ms;\r
-        psEnc->sCmn.LBRR_nBytes = 0;\r
+        psEnc->sCmn.PacketSize_ms  = PacketSize_ms;\r
+        psEnc->sCmn.TargetRate_bps = 0;         /* trigger new SNR computation */\r
     }\r
 \r
     /* Set internal sampling frequency */\r
+    SKP_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 );\r
+    SKP_assert( psEnc->sCmn.nb_subfr == 2 || psEnc->sCmn.nb_subfr == 4 );\r
     if( psEnc->sCmn.fs_kHz != fs_kHz ) {\r
         /* reset part of the state */\r
-        SKP_memset( &psEnc->sShape,              0,                        sizeof( SKP_Silk_shape_state_FIX ) );\r
-        SKP_memset( &psEnc->sPrefilt,            0,                        sizeof( SKP_Silk_prefilter_state_FIX ) );\r
-        SKP_memset( &psEnc->sNSQ,                0,                        sizeof( SKP_Silk_nsq_state ) );\r
-        SKP_memset( &psEnc->sPred,               0,                        sizeof( SKP_Silk_predict_state_FIX ) );\r
-        SKP_memset( psEnc->sNSQ.xq,              0, 2 * MAX_FRAME_LENGTH * sizeof( SKP_int16 ) );\r
-        SKP_memset( psEnc->sNSQ_LBRR.xq,         0, 2 * MAX_FRAME_LENGTH * sizeof( SKP_int16 ) );\r
-        SKP_memset( psEnc->sPred.prev_NLSFq_Q15, 0,        MAX_LPC_ORDER * sizeof( SKP_int ) );\r
-#if SWITCH_TRANSITION_FILTERING\r
-        SKP_memset( psEnc->sCmn.sLP.In_LP_State, 0, 2 * sizeof( SKP_int32 ) );\r
-        if( psEnc->sCmn.sLP.mode == 1 ) {\r
-            /* Begin transition phase */\r
-            psEnc->sCmn.sLP.transition_frame_no = 1;\r
-        } else {\r
-            /* End transition phase */\r
-            psEnc->sCmn.sLP.transition_frame_no = 0;\r
-        }\r
-#endif\r
-        psEnc->sCmn.LBRR_nBytes         = 0;\r
-        psEnc->sCmn.inputBufIx          = 0;\r
-        psEnc->sCmn.nFramesInPayloadBuf = 0;\r
-        psEnc->sCmn.nBytesInPayloadBuf  = 0;\r
-        psEnc->sCmn.TargetRate_bps      = 0; /* Ensures that psEnc->SNR_dB is recomputed */\r
+        SKP_memset( &psEnc->sShape,               0, sizeof( SKP_Silk_shape_state_FIX ) );\r
+        SKP_memset( &psEnc->sPrefilt,             0, sizeof( SKP_Silk_prefilter_state_FIX ) );\r
+        SKP_memset( &psEnc->sCmn.sNSQ,            0, sizeof( SKP_Silk_nsq_state ) );\r
+        SKP_memset( psEnc->sCmn.prev_NLSFq_Q15,   0, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) );\r
+        SKP_memset( &psEnc->sCmn.sLP.In_LP_State, 0, sizeof( psEnc->sCmn.sLP.In_LP_State ) );\r
+        psEnc->sCmn.inputBufIx                  = 0;\r
+        psEnc->sCmn.nFramesAnalyzed             = 0;\r
+        psEnc->sCmn.TargetRate_bps              = 0; /* Ensures that psEnc->SNR_dB is recomputed */\r
 \r
         /* Initialize non-zero parameters */\r
-        psEnc->sCmn.prevLag                 = 100;\r
-        psEnc->sCmn.first_frame_after_reset = 1;\r
-        psEnc->sPrefilt.lagPrev             = 100;\r
-        psEnc->sShape.LastGainIndex         = 1;\r
-        psEnc->sNSQ.lagPrev                 = 100;\r
-        psEnc->sNSQ.prev_inv_gain_Q16       = 65536;\r
-        psEnc->sNSQ_LBRR.prev_inv_gain_Q16  = 65536;\r
+        psEnc->sCmn.prevLag                     = 100;\r
+        psEnc->sCmn.first_frame_after_reset     = 1;\r
+        psEnc->sPrefilt.lagPrev                 = 100;\r
+        psEnc->sShape.LastGainIndex             = 10;\r
+        psEnc->sCmn.sNSQ.lagPrev                = 100;\r
+        psEnc->sCmn.sNSQ.prev_inv_gain_Q16      = 65536;\r
 \r
         psEnc->sCmn.fs_kHz = fs_kHz;\r
         if( psEnc->sCmn.fs_kHz == 8 ) {\r
-            psEnc->sCmn.predictLPCOrder = MIN_LPC_ORDER;\r
-            psEnc->sCmn.psNLSF_CB[ 0 ]  = &SKP_Silk_NLSF_CB0_10;\r
-            psEnc->sCmn.psNLSF_CB[ 1 ]  = &SKP_Silk_NLSF_CB1_10;\r
-            if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ){\r
+            if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) {\r
                 psEnc->sCmn.pitch_contour_iCDF = SKP_Silk_pitch_contour_NB_iCDF; \r
-            } else if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR / 2 ){\r
-                psEnc->sCmn.pitch_contour_iCDF = SKP_Silk_pitch_contour_10_ms_NB_iCDF;\r
             } else {\r
-                /* Unsupported number of frames */\r
-                SKP_assert( 0 );\r
+                psEnc->sCmn.pitch_contour_iCDF = SKP_Silk_pitch_contour_10_ms_NB_iCDF;\r
             }\r
         } else {\r
-            psEnc->sCmn.predictLPCOrder = MAX_LPC_ORDER;\r
-            psEnc->sCmn.psNLSF_CB[ 0 ]  = &SKP_Silk_NLSF_CB0_16;\r
-            psEnc->sCmn.psNLSF_CB[ 1 ]  = &SKP_Silk_NLSF_CB1_16;\r
-            if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ){\r
+            if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) {\r
                 psEnc->sCmn.pitch_contour_iCDF = SKP_Silk_pitch_contour_iCDF; \r
-            } else if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR / 2 ){\r
-                psEnc->sCmn.pitch_contour_iCDF = SKP_Silk_pitch_contour_10_ms_iCDF;\r
             } else {\r
-                /* Unsupported number of frames */\r
-                SKP_assert( 0 );\r
+                psEnc->sCmn.pitch_contour_iCDF = SKP_Silk_pitch_contour_10_ms_iCDF;\r
             }\r
         }\r
+        if( psEnc->sCmn.fs_kHz == 8 || psEnc->sCmn.fs_kHz == 12 ) {\r
+            psEnc->sCmn.predictLPCOrder = MIN_LPC_ORDER;\r
+            psEnc->sCmn.psNLSF_CB  = &SKP_Silk_NLSF_CB_NB_MB;\r
+        } else {\r
+            psEnc->sCmn.predictLPCOrder = MAX_LPC_ORDER;\r
+            psEnc->sCmn.psNLSF_CB  = &SKP_Silk_NLSF_CB_WB;\r
+        }\r
         psEnc->sCmn.subfr_length   = SUB_FRAME_LENGTH_MS * fs_kHz;\r
         psEnc->sCmn.frame_length   = SKP_SMULBB( psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr );\r
         psEnc->sCmn.ltp_mem_length = SKP_SMULBB( LTP_MEM_LENGTH_MS, fs_kHz ); \r
         psEnc->sCmn.la_pitch       = SKP_SMULBB( LA_PITCH_MS, fs_kHz );\r
-        psEnc->sPred.min_pitch_lag = SKP_SMULBB(  3, fs_kHz );\r
-        psEnc->sPred.max_pitch_lag = SKP_SMULBB( 18, fs_kHz );\r
-        if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ){\r
-            psEnc->sPred.pitch_LPC_win_length = SKP_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz );\r
-        } else if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR / 2 ){\r
-            psEnc->sPred.pitch_LPC_win_length = SKP_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz );\r
+        psEnc->sCmn.max_pitch_lag  = SKP_SMULBB( 18, fs_kHz );\r
+        if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) {\r
+            psEnc->sCmn.pitch_LPC_win_length = SKP_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz );\r
         } else {\r
-            /* Unsupported number of frames */\r
-            SKP_assert( 0 );\r
+            psEnc->sCmn.pitch_LPC_win_length = SKP_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz );\r
         }\r
-        if( psEnc->sCmn.fs_kHz == 24 ) {\r
-            psEnc->sCmn.mu_LTP_Q9 = SKP_FIX_CONST( MU_LTP_QUANT_SWB, 9 );\r
-            psEnc->sCmn.bitrate_threshold_up    = SKP_int32_MAX;\r
-            psEnc->sCmn.bitrate_threshold_down  = SWB2WB_BITRATE_BPS; \r
-            psEnc->sCmn.pitch_lag_low_bits_iCDF = SKP_Silk_uniform12_iCDF;\r
-        } else if( psEnc->sCmn.fs_kHz == 16 ) {\r
+        if( psEnc->sCmn.fs_kHz == 16 ) {\r
             psEnc->sCmn.mu_LTP_Q9 = SKP_FIX_CONST( MU_LTP_QUANT_WB, 9 );\r
-            psEnc->sCmn.bitrate_threshold_up    = WB2SWB_BITRATE_BPS;\r
-            psEnc->sCmn.bitrate_threshold_down  = WB2MB_BITRATE_BPS; \r
             psEnc->sCmn.pitch_lag_low_bits_iCDF = SKP_Silk_uniform8_iCDF;\r
         } else if( psEnc->sCmn.fs_kHz == 12 ) {\r
             psEnc->sCmn.mu_LTP_Q9 = SKP_FIX_CONST( MU_LTP_QUANT_MB, 9 );\r
-            psEnc->sCmn.bitrate_threshold_up    = MB2WB_BITRATE_BPS;\r
-            psEnc->sCmn.bitrate_threshold_down  = MB2NB_BITRATE_BPS;\r
             psEnc->sCmn.pitch_lag_low_bits_iCDF = SKP_Silk_uniform6_iCDF;\r
-        } else if( psEnc->sCmn.fs_kHz == 8 ) {\r
+        } else {\r
             psEnc->sCmn.mu_LTP_Q9 = SKP_FIX_CONST( MU_LTP_QUANT_NB, 9 );\r
-            psEnc->sCmn.bitrate_threshold_up    = NB2MB_BITRATE_BPS;\r
-            psEnc->sCmn.bitrate_threshold_down  = 0;\r
             psEnc->sCmn.pitch_lag_low_bits_iCDF = SKP_Silk_uniform4_iCDF;\r
-        } else {\r
-            /* unsupported sampling rate */\r
-            SKP_assert( 0 );\r
         }\r
-        psEnc->sCmn.fs_kHz_changed = 1;\r
     }\r
 \r
     /* Check that settings are valid */\r
@@ -313,12 +274,12 @@ SKP_INLINE SKP_int SKP_Silk_setup_fs(
 \r
 SKP_INLINE SKP_int SKP_Silk_setup_rate(\r
     SKP_Silk_encoder_state_FIX      *psEnc,             /* I/O                      */\r
-    SKP_int                         TargetRate_bps      /* I                        */\r
+    SKP_int32                       TargetRate_bps      /* I                        */\r
 )\r
 {\r
     SKP_int k, ret = SKP_SILK_NO_ERROR;\r
     SKP_int32 frac_Q6;\r
-    const SKP_uint16 *rateTable;\r
+    const SKP_int32 *rateTable;\r
 \r
     /* Set bitrate/coding quality */\r
     if( TargetRate_bps != psEnc->sCmn.TargetRate_bps ) {\r
@@ -332,11 +293,15 @@ SKP_INLINE SKP_int SKP_Silk_setup_rate(
         } else if( psEnc->sCmn.fs_kHz == 16 ) {\r
             rateTable = TargetRate_table_WB;\r
         } else {\r
-            rateTable = TargetRate_table_SWB;\r
+            SKP_assert( 0 );\r
+        }\r
+        /* Reduce bitrate for 10 ms modes in these calculations */\r
+        if( psEnc->sCmn.nb_subfr == 2 ) {\r
+            TargetRate_bps -= REDUCE_BITRATE_10_MS_BPS;\r
         }\r
         for( k = 1; k < TARGET_RATE_TAB_SZ; k++ ) {\r
             /* Find bitrate interval in table and interpolate */\r
-            if( TargetRate_bps < rateTable[ k ] ) {\r
+            if( TargetRate_bps <= rateTable[ k ] ) {\r
                 frac_Q6 = SKP_DIV32( SKP_LSHIFT( TargetRate_bps - rateTable[ k - 1 ], 6 ), \r
                                                  rateTable[ k ] - rateTable[ k - 1 ] );\r
                 psEnc->SNR_dB_Q7 = SKP_LSHIFT( SNR_table_Q1[ k - 1 ], 6 ) + SKP_MUL( frac_Q6, SNR_table_Q1[ k ] - SNR_table_Q1[ k - 1 ] );\r
@@ -346,55 +311,3 @@ SKP_INLINE SKP_int SKP_Silk_setup_rate(
     }\r
     return( ret );\r
 }\r
-\r
-SKP_INLINE SKP_int SKP_Silk_setup_LBRR(\r
-    SKP_Silk_encoder_state_FIX      *psEnc             /* I/O                      */\r
-)\r
-{\r
-    SKP_int   ret = SKP_SILK_NO_ERROR;\r
-\r
-#if USE_LBRR\r
-    SKP_int32 LBRRRate_thres_bps;\r
-\r
-    if( psEnc->sCmn.useInBandFEC < 0 || psEnc->sCmn.useInBandFEC > 1 ) {\r
-        ret = SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING;\r
-    }\r
-    \r
-    psEnc->sCmn.LBRR_enabled = psEnc->sCmn.useInBandFEC;\r
-    if( psEnc->sCmn.fs_kHz == 8 ) {\r
-        LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 9000;\r
-    } else if( psEnc->sCmn.fs_kHz == 12 ) {\r
-        LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 6000;;\r
-    } else if( psEnc->sCmn.fs_kHz == 16 ) {\r
-        LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 3000;\r
-    } else {\r
-        LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS;\r
-    }\r
-\r
-    if( psEnc->sCmn.TargetRate_bps >= LBRRRate_thres_bps ) {\r
-        /* Set gain increase / rate reduction for LBRR usage */\r
-        /* Coarsely tuned with PESQ for now. */\r
-        /* Linear regression coefs G = 8 - 0.5 * loss */\r
-        /* Meaning that at 16% loss main rate and redundant rate is the same, -> G = 0 */\r
-        psEnc->sCmn.LBRR_GainIncreases = SKP_max_int( 8 - SKP_RSHIFT( psEnc->sCmn.PacketLoss_perc, 1 ), 0 );\r
-\r
-        /* Set main stream rate compensation */\r
-        if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.PacketLoss_perc > LBRR_LOSS_THRES ) {\r
-            /* Tuned to give approx same mean / weighted bitrate as no inband FEC */\r
-            psEnc->inBandFEC_SNR_comp_Q8 = SKP_FIX_CONST( 6.0f, 8 ) - SKP_LSHIFT( psEnc->sCmn.LBRR_GainIncreases, 7 );\r
-        } else {\r
-            psEnc->inBandFEC_SNR_comp_Q8 = 0;\r
-            psEnc->sCmn.LBRR_enabled     = 0;\r
-        }\r
-    } else {\r
-        psEnc->inBandFEC_SNR_comp_Q8     = 0;\r
-        psEnc->sCmn.LBRR_enabled         = 0;\r
-    }\r
-#else\r
-    if( psEnc->sCmn.LBRR_enabled != 0 ) {\r
-        ret = SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING;\r
-        psEnc->sCmn.LBRR_enabled = 0;\r
-    }\r
-#endif\r
-    return ret;\r
-}\r