Update SILK code using the CELT range coder
[opus.git] / src_FIX / SKP_Silk_encode_frame_FIX.c
similarity index 58%
rename from src/SKP_Silk_encode_frame_FIX.c
rename to src_FIX/SKP_Silk_encode_frame_FIX.c
index 4f97ec5..7d42a4d 100644 (file)
@@ -26,6 +26,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ***********************************************************************/\r
 \r
 #include "SKP_Silk_main_FIX.h"\r
+\r
 /****************/\r
 /* Encode frame */\r
 /****************/\r
@@ -43,39 +44,44 @@ SKP_int SKP_Silk_encode_frame_FIX(
     SKP_int16   xfw[ MAX_FRAME_LENGTH ];\r
     SKP_int16   pIn_HP[ MAX_FRAME_LENGTH ];\r
     SKP_int16   res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];\r
-    SKP_int     LBRR_idx, frame_terminator, SNR_dB_Q7;\r
+    SKP_int     LBRR_idx, frame_terminator;\r
     const SKP_uint16 *FrameTermination_CDF;\r
 \r
     /* Low bitrate redundancy parameters */\r
     SKP_uint8   LBRRpayload[ MAX_ARITHM_BYTES ];\r
     SKP_int16   nBytesLBRR;\r
+    ec_byte_buffer range_enc_celt_buf;\r
 \r
-    //SKP_int32   Seed[ MAX_LAYERS ];\r
     sEncCtrl.sCmn.Seed = psEnc->sCmn.frameCounter++ & 3;\r
 \r
+TIC(ENCODE_FRAME)\r
 \r
     /**************************************************************/\r
     /* Setup Input Pointers, and insert frame in input buffer    */\r
     /*************************************************************/\r
-    x_frame         = psEnc->x_buf + psEnc->sCmn.frame_length; /* start of frame to encode */\r
-    res_pitch_frame = res_pitch    + psEnc->sCmn.frame_length; /* start of pitch LPC residual frame */\r
+    x_frame         = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /* start of frame to encode */\r
+    res_pitch_frame = res_pitch    + psEnc->sCmn.ltp_mem_length; /* start of pitch LPC residual frame */\r
 \r
     /****************************/\r
     /* Voice Activity Detection */\r
     /****************************/\r
-    ret = SKP_Silk_VAD_GetSA_Q8( &psEnc->sCmn.sVAD, &psEnc->speech_activity_Q8, &SNR_dB_Q7, \r
+TIC(VAD)\r
+    ret = SKP_Silk_VAD_GetSA_Q8( &psEnc->sCmn.sVAD, &psEnc->speech_activity_Q8, \r
                                  sEncCtrl.input_quality_bands_Q15, &sEncCtrl.input_tilt_Q15,\r
-                                 pIn,psEnc->sCmn.frame_length );\r
+                                 pIn, psEnc->sCmn.frame_length, psEnc->sCmn.fs_kHz );\r
+TOC(VAD)\r
 \r
     /*******************************************/\r
     /* High-pass filtering of the input signal */\r
     /*******************************************/\r
+TIC(HP_IN)\r
 #if HIGH_PASS_INPUT\r
     /* Variable high-pass filter */\r
     SKP_Silk_HP_variable_cutoff_FIX( psEnc, &sEncCtrl, pIn_HP, pIn );\r
 #else\r
     SKP_memcpy( pIn_HP, pIn,psEnc->sCmn.frame_length * sizeof( SKP_int16 ) );\r
 #endif\r
+TOC(HP_IN)\r
 \r
 #if SWITCH_TRANSITION_FILTERING\r
     /* Ensure smooth bandwidth transitions */\r
@@ -87,28 +93,37 @@ SKP_int SKP_Silk_encode_frame_FIX(
     /*****************************************/\r
     /* Find pitch lags, initial LPC analysis */\r
     /*****************************************/\r
+TIC(FIND_PITCH)\r
     SKP_Silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame );\r
+TOC(FIND_PITCH)\r
 \r
     /************************/\r
     /* Noise shape analysis */\r
     /************************/\r
-    SKP_Silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame );    \r
+TIC(NOISE_SHAPE_ANALYSIS)\r
+    SKP_Silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame );\r
+TOC(NOISE_SHAPE_ANALYSIS)\r
 \r
     /*****************************************/\r
     /* Prefiltering for noise shaper         */\r
     /*****************************************/\r
+TIC(PREFILTER)\r
     SKP_Silk_prefilter_FIX( psEnc, &sEncCtrl, xfw, x_frame );\r
-\r
+TOC(PREFILTER)\r
 \r
     /***************************************************/\r
     /* Find linear prediction coefficients (LPC + LTP) */\r
     /***************************************************/\r
+TIC(FIND_PRED_COEF)\r
     SKP_Silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch );\r
+TOC(FIND_PRED_COEF)\r
 \r
     /****************************************/\r
     /* Process gains                        */\r
     /****************************************/\r
+TIC(PROCESS_GAINS)\r
     SKP_Silk_process_gains_FIX( psEnc, &sEncCtrl );\r
+TOC(PROCESS_GAINS)\r
  \r
     psEnc->sCmn.sigtype[         psEnc->sCmn.nFramesInPayloadBuf ] = sEncCtrl.sCmn.sigtype;\r
     psEnc->sCmn.QuantOffsetType[ psEnc->sCmn.nFramesInPayloadBuf ] = sEncCtrl.sCmn.QuantOffsetType;\r
@@ -117,16 +132,28 @@ SKP_int SKP_Silk_encode_frame_FIX(
     /* Low Bitrate Redundant Encoding       */\r
     /****************************************/\r
     nBytesLBRR = MAX_ARITHM_BYTES;\r
+TIC(LBRR)\r
     SKP_Silk_LBRR_encode_FIX( psEnc, &sEncCtrl, LBRRpayload, &nBytesLBRR, xfw );\r
+TOC(LBRR)\r
 \r
     /*****************************************/\r
     /* Noise shaping quantization            */\r
     /*****************************************/\r
-    psEnc->NoiseShapingQuantizer( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sNSQ, xfw, \r
-        &psEnc->sCmn.q[ psEnc->sCmn.nFramesInPayloadBuf *psEnc->sCmn.frame_length ], sEncCtrl.sCmn.NLSFInterpCoef_Q2, \r
-        sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, \r
-        sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.Lambda_Q10, \r
-        sEncCtrl.LTP_scale_Q14 );\r
+TIC(NSQ)\r
+    if( psEnc->sCmn.nStatesDelayedDecision > 1 ) {\r
+        SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sNSQ, xfw,\r
+            &psEnc->sCmn.q[ psEnc->sCmn.nFramesInPayloadBuf *psEnc->sCmn.frame_length ], sEncCtrl.sCmn.NLSFInterpCoef_Q2, \r
+            sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, \r
+            sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.Lambda_Q10, \r
+            sEncCtrl.LTP_scale_Q14 );\r
+    } else {\r
+        SKP_Silk_NSQ( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sNSQ, xfw, \r
+               &psEnc->sCmn.q[ psEnc->sCmn.nFramesInPayloadBuf *psEnc->sCmn.frame_length ], sEncCtrl.sCmn.NLSFInterpCoef_Q2, \r
+               sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, \r
+               sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.Lambda_Q10, \r
+            sEncCtrl.LTP_scale_Q14 );\r
+    }\r
+TOC(NSQ)\r
 \r
     /**************************************************/\r
     /* Convert speech activity into VAD and DTX flags */\r
@@ -151,6 +178,9 @@ SKP_int SKP_Silk_encode_frame_FIX(
     /* Initialize arithmetic coder          */\r
     /****************************************/\r
     if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {\r
+        ec_byte_writeinit_buffer( &range_enc_celt_buf, psEnc->sCmn.sRC.buffer, MAX_ARITHM_BYTES );\r
+        ec_enc_init( &psEnc->sCmn.sRC.range_enc_celt_state, &range_enc_celt_buf );\r
+\r
         SKP_Silk_range_enc_init( &psEnc->sCmn.sRC );\r
         psEnc->sCmn.nBytesInPayloadBuf = 0;\r
     }\r
@@ -158,24 +188,20 @@ SKP_int SKP_Silk_encode_frame_FIX(
     /****************************************/\r
     /* Encode Parameters                    */\r
     /****************************************/\r
-    if( psEnc->sCmn.bitstream_v == BIT_STREAM_V4 ) {\r
-        SKP_Silk_encode_parameters_v4( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sCmn.sRC );\r
-        FrameTermination_CDF = SKP_Silk_FrameTermination_v4_CDF;\r
-    } else {\r
-        SKP_Silk_encode_parameters( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sCmn.sRC, \r
-            &psEnc->sCmn.q[ psEnc->sCmn.nFramesInPayloadBuf *psEnc->sCmn.frame_length ] );\r
-        FrameTermination_CDF = SKP_Silk_FrameTermination_CDF;\r
-    }\r
+TIC(ENCODE_PARAMS)\r
+    SKP_Silk_encode_parameters_v4( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sCmn.sRC );\r
+    FrameTermination_CDF = SKP_Silk_FrameTermination_v4_CDF;\r
+TOC(ENCODE_PARAMS)\r
 \r
     /****************************************/\r
     /* Update Buffers and State             */\r
     /****************************************/\r
     /* Update Input buffer */\r
-    SKP_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], ( psEnc->sCmn.frame_length + psEnc->sCmn.la_shape ) * sizeof( SKP_int16 ) );\r
+    SKP_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], ( psEnc->sCmn.ltp_mem_length + psEnc->sCmn.la_shape ) * sizeof( SKP_int16 ) );\r
     \r
     /* parameters needed for next frame */\r
     psEnc->sCmn.prev_sigtype            = sEncCtrl.sCmn.sigtype;\r
-    psEnc->sCmn.prevLag                 = sEncCtrl.sCmn.pitchL[ NB_SUBFR - 1];\r
+    psEnc->sCmn.prevLag                 = sEncCtrl.sCmn.pitchL[  psEnc->sCmn.nb_subfr - 1 ];\r
     psEnc->sCmn.first_frame_after_reset = 0;\r
 \r
     if( psEnc->sCmn.sRC.error ) {\r
@@ -188,7 +214,7 @@ SKP_int SKP_Silk_encode_frame_FIX(
     /****************************************/\r
     /* finalize payload and copy to output  */\r
     /****************************************/\r
-    if( psEnc->sCmn.nFramesInPayloadBuf * FRAME_LENGTH_MS >= psEnc->sCmn.PacketSize_ms ) {\r
+    if( psEnc->sCmn.nFramesInPayloadBuf * SUB_FRAME_LENGTH_MS * psEnc->sCmn.nb_subfr >= psEnc->sCmn.PacketSize_ms ) {\r
 \r
         LBRR_idx = ( psEnc->sCmn.oldest_LBRR_idx + 1 ) & LBRR_IDX_MASK;\r
 \r
@@ -201,24 +227,33 @@ SKP_int SKP_Silk_encode_frame_FIX(
             frame_terminator = SKP_SILK_LBRR_VER2;\r
             LBRR_idx = psEnc->sCmn.oldest_LBRR_idx;\r
         }\r
+\r
         /* Add the frame termination info to stream */\r
         SKP_Silk_range_encoder( &psEnc->sCmn.sRC, frame_terminator, FrameTermination_CDF );\r
 \r
-        if( psEnc->sCmn.bitstream_v == BIT_STREAM_V4 ) {\r
-            /* Code excitation signal */\r
-            for( i = 0; i <psEnc->sCmn.nFramesInPayloadBuf; i++ ) {\r
-                SKP_Silk_encode_pulses( &psEnc->sCmn.sRC, psEnc->sCmn.sigtype[ i ],psEnc->sCmn.QuantOffsetType[ i ], \r
-                    &psEnc->sCmn.q[ i * psEnc->sCmn.frame_length],psEnc->sCmn.frame_length );\r
-            }\r
+        /* Code excitation signal */\r
+        for( i = 0; i <psEnc->sCmn.nFramesInPayloadBuf; i++ ) {\r
+            SKP_Silk_encode_pulses( &psEnc->sCmn.sRC, psEnc->sCmn.sigtype[ i ],psEnc->sCmn.QuantOffsetType[ i ], \r
+                &psEnc->sCmn.q[ i * psEnc->sCmn.frame_length],psEnc->sCmn.frame_length );\r
         }\r
         /* payload length so far */\r
-        SKP_Silk_range_coder_get_length( &psEnc->sCmn.sRC, &nBytes );\r
+        SKP_Silk_range_encoder_get_length( &psEnc->sCmn.sRC, &nBytes );\r
 \r
         /* check that there is enough space in external output buffer, and move data */\r
         if( *pnBytesOut >= nBytes ) {\r
-            SKP_Silk_range_enc_wrap_up( &psEnc->sCmn.sRC );\r
-            SKP_memcpy( pCode, psEnc->sCmn.sRC.buffer, nBytes * sizeof( SKP_uint8 ) );\r
+            SKP_int bits_in_stream, mask;\r
+            bits_in_stream = ec_enc_tell( &psEnc->sCmn.sRC.range_enc_celt_state, 0 );\r
+            ec_enc_done( &psEnc->sCmn.sRC.range_enc_celt_state );\r
             \r
+            /* Fill up any remaining bits in the last byte with 1s */\r
+            if( bits_in_stream & 7 ) {\r
+                mask = SKP_RSHIFT( 0xFF, bits_in_stream & 7 );\r
+                if( nBytes - 1 < *pnBytesOut ) {\r
+                    psEnc->sCmn.sRC.range_enc_celt_state.buf->buf[ nBytes - 1 ] |= mask;\r
+                }\r
+            }\r
+            SKP_memcpy( pCode, psEnc->sCmn.sRC.range_enc_celt_state.buf->buf, nBytes * sizeof( SKP_uint8 ) );\r
+\r
             if( frame_terminator > SKP_SILK_MORE_FRAMES && \r
                     *pnBytesOut >= nBytes + psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes ) {\r
                 /* Get old packet and add to payload. */\r
@@ -256,13 +291,11 @@ SKP_int SKP_Silk_encode_frame_FIX(
         SKP_Silk_range_encoder( &psEnc->sCmn.sRC, frame_terminator, FrameTermination_CDF );\r
 \r
         /* payload length so far */\r
-        SKP_Silk_range_coder_get_length( &psEnc->sCmn.sRC, &nBytes );\r
-        \r
-        if( psEnc->sCmn.bitstream_v == BIT_STREAM_V4 ) {\r
-            /* Take into account the q signal that isnt in the bitstream yet */\r
-            nBytes +=  SKP_Silk_pulses_to_bytes( &psEnc->sCmn, \r
-                &psEnc->sCmn.q[ (psEnc->sCmn.nFramesInPayloadBuf - 1) * psEnc->sCmn.frame_length ] );\r
-        }\r
+        SKP_Silk_range_encoder_get_length( &psEnc->sCmn.sRC, &nBytes );\r
+\r
+        /* Take into account the q signal that isnt in the bitstream yet */\r
+        nBytes +=  SKP_Silk_pulses_to_bytes( &psEnc->sCmn, \r
+            &psEnc->sCmn.q[ (psEnc->sCmn.nFramesInPayloadBuf - 1) * psEnc->sCmn.frame_length ] );\r
     }\r
 \r
     /* Check for arithmetic coder errors */\r
@@ -275,15 +308,63 @@ SKP_int SKP_Silk_encode_frame_FIX(
         SKP_SAT32( 8 * 1000 * ( (SKP_int64)nBytes - (SKP_int64)psEnc->sCmn.nBytesInPayloadBuf ) ) );\r
     SKP_assert( psEnc->sCmn.TargetRate_bps > 0 );\r
     psEnc->BufferedInChannel_ms   += SKP_DIV32( 8 * 1000 * ( nBytes -psEnc->sCmn.nBytesInPayloadBuf ),psEnc->sCmn.TargetRate_bps );\r
-    psEnc->BufferedInChannel_ms   -= FRAME_LENGTH_MS;\r
-    psEnc->BufferedInChannel_ms    = SKP_LIMIT( psEnc->BufferedInChannel_ms, 0, 100 );\r
+    psEnc->BufferedInChannel_ms   -= SKP_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr );\r
+    psEnc->BufferedInChannel_ms    = SKP_LIMIT_int( psEnc->BufferedInChannel_ms, 0, 100 );\r
     psEnc->sCmn.nBytesInPayloadBuf = nBytes;\r
 \r
     if( psEnc->speech_activity_Q8 > WB_DETECT_ACTIVE_SPEECH_LEVEL_THRES_Q8 ) {\r
-        psEnc->sCmn.sSWBdetect.ActiveSpeech_ms = SKP_ADD_POS_SAT32( psEnc->sCmn.sSWBdetect.ActiveSpeech_ms, FRAME_LENGTH_MS ); \r
+        psEnc->sCmn.sSWBdetect.ActiveSpeech_ms = SKP_ADD_POS_SAT32( psEnc->sCmn.sSWBdetect.ActiveSpeech_ms, SKP_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) ); \r
     }\r
 \r
-\r
+TOC(ENCODE_FRAME)\r
+\r
+#ifdef SAVE_ALL_INTERNAL_DATA\r
+    {\r
+        SKP_float tmp[ MAX_NB_SUBFR * LTP_ORDER ];\r
+        int i;\r
+        DEBUG_STORE_DATA( xf.dat,                   x_frame +psEnc->sCmn.la_shape,  psEnc->sCmn.frame_length    * sizeof( SKP_int16 ) );\r
+        DEBUG_STORE_DATA( xfw.dat,                  xfw,                            psEnc->sCmn.frame_length    * sizeof( SKP_int16 ) );\r
+        //     DEBUG_STORE_DATA( q.dat,                    &psEnc->sCmn.q[ ( psEnc->sCmn.nFramesInPayloadBuf - 1)*psEnc->sCmn.frame_length ],  psEnc->sCmn.frame_length    * sizeof( SKP_int8 ) );\r
+        DEBUG_STORE_DATA( pitchL.dat,               sEncCtrl.sCmn.pitchL,           psEnc->sCmn.nb_subfr            * sizeof( SKP_int ) );\r
+        for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) {\r
+            tmp[ i ] = (SKP_float)sEncCtrl.LTPCoef_Q14[ i ] / 16384.0f;\r
+        }\r
+        DEBUG_STORE_DATA( pitchG_quantized.dat,     tmp,                            psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( SKP_float ) );\r
+        for( i = 0; i <psEnc->sCmn.predictLPCOrder; i++ ) {\r
+            tmp[ i ] = (SKP_float)sEncCtrl.PredCoef_Q12[ 1 ][ i ] / 4096.0f;\r
+        }\r
+        DEBUG_STORE_DATA( PredCoef.dat,             tmp,                            psEnc->sCmn.predictLPCOrder * sizeof( SKP_float ) );\r
+        \r
+        tmp[ 0 ] = (SKP_float)sEncCtrl.pitch_freq_low_Hz;\r
+        DEBUG_STORE_DATA( pitch_freq_low_Hz.dat,    tmp,                            sizeof( SKP_float ) );\r
+        tmp[ 0 ] = (SKP_float)sEncCtrl.LTPredCodGain_Q7 / 128.0f;\r
+        DEBUG_STORE_DATA( LTPredCodGain.dat,        tmp,                            sizeof( SKP_float ) );\r
+        tmp[ 0 ] = (SKP_float)psEnc->LTPCorr_Q15 / 32768.0f;\r
+        DEBUG_STORE_DATA( LTPcorr.dat,              tmp,                            sizeof( SKP_float ) );\r
+        tmp[ 0 ] = (SKP_float)sEncCtrl.input_tilt_Q15 / 32768.0f;\r
+        DEBUG_STORE_DATA( tilt.dat,                 tmp,                            sizeof( SKP_float ) );\r
+        for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {\r
+            tmp[ i ] = (SKP_float)sEncCtrl.Gains_Q16[ i ] / 65536.0f;\r
+        }\r
+        DEBUG_STORE_DATA( gains.dat,                tmp,                            psEnc->sCmn.nb_subfr * sizeof( SKP_float ) );\r
+        DEBUG_STORE_DATA( gains_indices.dat,        &sEncCtrl.sCmn.GainsIndices,    psEnc->sCmn.nb_subfr * sizeof( SKP_int ) );\r
+        DEBUG_STORE_DATA( nBytes.dat,               &nBytes,                        sizeof( SKP_int ) );\r
+        tmp[ 0 ] = (SKP_float)sEncCtrl.current_SNR_dB_Q7 / 128.0f;\r
+        DEBUG_STORE_DATA( current_SNR_db.dat,       tmp,                            sizeof( SKP_float ) );\r
+        DEBUG_STORE_DATA( QuantOffsetType.dat,      &sEncCtrl.sCmn.QuantOffsetType, sizeof( SKP_int ) );\r
+        tmp[ 0 ] = (SKP_float)psEnc->speech_activity_Q8 / 256.0f;\r
+        DEBUG_STORE_DATA( speech_activity.dat,      tmp,                            sizeof( SKP_float ) );\r
+        for( i = 0; i < VAD_N_BANDS; i++ ) {\r
+            tmp[ i ] = (SKP_float)sEncCtrl.input_quality_bands_Q15[ i ] / 32768.0f;\r
+        }\r
+        DEBUG_STORE_DATA( input_quality_bands.dat,  tmp,                            VAD_N_BANDS * sizeof( SKP_float ) );\r
+        DEBUG_STORE_DATA( sigtype.dat,              &sEncCtrl.sCmn.sigtype,         sizeof( SKP_int ) ); \r
+        DEBUG_STORE_DATA( ratelevel.dat,            &sEncCtrl.sCmn.RateLevelIndex,  sizeof( SKP_int ) ); \r
+        DEBUG_STORE_DATA( lag_index.dat,            &sEncCtrl.sCmn.lagIndex,        sizeof( SKP_int ) ); \r
+        DEBUG_STORE_DATA( contour_index.dat,        &sEncCtrl.sCmn.contourIndex,    sizeof( SKP_int ) ); \r
+        DEBUG_STORE_DATA( per_index.dat,            &sEncCtrl.sCmn.PERIndex,        sizeof( SKP_int ) ); \r
+    }\r
+#endif\r
     return( ret );\r
 }\r
 \r
@@ -296,10 +377,12 @@ void SKP_Silk_LBRR_encode_FIX(
     SKP_int16                       xfw[]           /* I    Input signal                            */\r
 )\r
 {\r
-    SKP_int     i, TempGainsIndices[ NB_SUBFR ], frame_terminator;\r
+    SKP_int     i, TempGainsIndices[ MAX_NB_SUBFR ], frame_terminator;\r
     SKP_int     nBytes, nFramesInPayloadBuf;\r
-    SKP_int32   TempGains_Q16[ NB_SUBFR ];\r
+    SKP_int32   TempGains_Q16[ MAX_NB_SUBFR ];\r
     SKP_int     typeOffset, LTP_scaleIndex, Rate_only_parameters = 0;\r
+    ec_byte_buffer range_enc_celt_buf;\r
+\r
     /*******************************************/\r
     /* Control use of inband LBRR              */\r
     /*******************************************/\r
@@ -307,8 +390,8 @@ void SKP_Silk_LBRR_encode_FIX(
 \r
     if( psEnc->sCmn.LBRR_enabled ) {\r
         /* Save original Gains */\r
-        SKP_memcpy( TempGainsIndices, psEncCtrl->sCmn.GainsIndices, NB_SUBFR * sizeof( SKP_int   ) );\r
-        SKP_memcpy( TempGains_Q16,    psEncCtrl->Gains_Q16,    NB_SUBFR * sizeof( SKP_int32 ) );\r
+        SKP_memcpy( TempGainsIndices, psEncCtrl->sCmn.GainsIndices, MAX_NB_SUBFR * sizeof( SKP_int   ) );\r
+        SKP_memcpy( TempGains_Q16,    psEncCtrl->Gains_Q16,         MAX_NB_SUBFR * sizeof( SKP_int32 ) );\r
 \r
         typeOffset     = psEnc->sCmn.typeOffsetPrev; // Temp save as cannot be overwritten\r
         LTP_scaleIndex = psEncCtrl->sCmn.LTP_scaleIndex;\r
@@ -334,20 +417,28 @@ void SKP_Silk_LBRR_encode_FIX(
                 psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;\r
                 /* Increase Gains to get target LBRR rate */\r
                 psEncCtrl->sCmn.GainsIndices[ 0 ] = psEncCtrl->sCmn.GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;\r
-                psEncCtrl->sCmn.GainsIndices[ 0 ] = SKP_LIMIT( psEncCtrl->sCmn.GainsIndices[ 0 ], 0, N_LEVELS_QGAIN - 1 );\r
+                psEncCtrl->sCmn.GainsIndices[ 0 ] = SKP_LIMIT_int( psEncCtrl->sCmn.GainsIndices[ 0 ], 0, N_LEVELS_QGAIN - 1 );\r
             }\r
             /* Decode to get Gains in sync with decoder         */\r
             /* Overwrite unquantized gains with quantized gains */\r
             SKP_Silk_gains_dequant( psEncCtrl->Gains_Q16, psEncCtrl->sCmn.GainsIndices, \r
-                &psEnc->sCmn.LBRRprevLastGainIndex, psEnc->sCmn.nFramesInPayloadBuf );\r
+                &psEnc->sCmn.LBRRprevLastGainIndex, psEnc->sCmn.nFramesInPayloadBuf, psEnc->sCmn.nb_subfr );\r
             /*****************************************/\r
             /* Noise shaping quantization            */\r
             /*****************************************/\r
-            psEnc->NoiseShapingQuantizer( &psEnc->sCmn, &psEncCtrl->sCmn,\r
-                &psEnc->sNSQ_LBRR, xfw, &psEnc->sCmn.q_LBRR[ psEnc->sCmn.nFramesInPayloadBuf * psEnc->sCmn.frame_length ], \r
-                psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, \r
-                psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, \r
-                psEncCtrl->Gains_Q16, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );\r
+            if( psEnc->sCmn.nStatesDelayedDecision > 1 ) {\r
+                SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &psEncCtrl->sCmn,\r
+                    &psEnc->sNSQ_LBRR, xfw, &psEnc->sCmn.q_LBRR[ psEnc->sCmn.nFramesInPayloadBuf * psEnc->sCmn.frame_length ], \r
+                    psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, \r
+                    psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, \r
+                    psEncCtrl->Gains_Q16, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );\r
+            } else {\r
+                SKP_Silk_NSQ( &psEnc->sCmn, &psEncCtrl->sCmn,\r
+                    &psEnc->sNSQ_LBRR, xfw, &psEnc->sCmn.q_LBRR[ psEnc->sCmn.nFramesInPayloadBuf * psEnc->sCmn.frame_length ], \r
+                    psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, \r
+                    psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, \r
+                    psEncCtrl->Gains_Q16, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );\r
+            }\r
         } else {\r
             SKP_memset( &psEnc->sCmn.q_LBRR[ psEnc->sCmn.nFramesInPayloadBuf *psEnc->sCmn.frame_length ], 0,\r
                 psEnc->sCmn.frame_length * sizeof( SKP_int ) );\r
@@ -357,6 +448,9 @@ void SKP_Silk_LBRR_encode_FIX(
         /* Initialize arithmetic coder          */\r
         /****************************************/\r
         if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {\r
+            ec_byte_writeinit_buffer( &range_enc_celt_buf, psEnc->sCmn.sRC_LBRR.buffer, MAX_ARITHM_BYTES );\r
+            ec_enc_init( &psEnc->sCmn.sRC_LBRR.range_enc_celt_state, &range_enc_celt_buf );\r
+\r
             SKP_Silk_range_enc_init( &psEnc->sCmn.sRC_LBRR );\r
             psEnc->sCmn.nBytesInPayloadBuf = 0;\r
         }\r
@@ -364,12 +458,7 @@ void SKP_Silk_LBRR_encode_FIX(
         /****************************************/\r
         /* Encode Parameters                    */\r
         /****************************************/\r
-        if( psEnc->sCmn.bitstream_v == BIT_STREAM_V4 ) {\r
-            SKP_Silk_encode_parameters_v4( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sCmn.sRC_LBRR );\r
-        } else {\r
-            SKP_Silk_encode_parameters( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sCmn.sRC_LBRR, \r
-                &psEnc->sCmn.q_LBRR[ psEnc->sCmn.nFramesInPayloadBuf * psEnc->sCmn.frame_length] );\r
-        }\r
+        SKP_Silk_encode_parameters_v4( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sCmn.sRC_LBRR );\r
 \r
         if( psEnc->sCmn.sRC_LBRR.error ) {\r
             /* encoder returned error: clear payload buffer */\r
@@ -381,31 +470,39 @@ void SKP_Silk_LBRR_encode_FIX(
         /****************************************/\r
         /* finalize payload and copy to output  */\r
         /****************************************/\r
-        if( SKP_SMULBB( nFramesInPayloadBuf, FRAME_LENGTH_MS ) >= psEnc->sCmn.PacketSize_ms ) {\r
+        if( SKP_SMULBB( nFramesInPayloadBuf, SKP_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) ) >= psEnc->sCmn.PacketSize_ms ) {\r
 \r
             /* Check if FEC information should be added */\r
             frame_terminator = SKP_SILK_LAST_FRAME;\r
 \r
             /* Add the frame termination info to stream */\r
-            SKP_Silk_range_encoder( &psEnc->sCmn.sRC_LBRR, frame_terminator, SKP_Silk_FrameTermination_CDF );\r
+            SKP_Silk_range_encoder( &psEnc->sCmn.sRC_LBRR, frame_terminator, SKP_Silk_FrameTermination_v4_CDF );\r
             \r
-            if( psEnc->sCmn.bitstream_v == BIT_STREAM_V4 ) {\r
-                /*********************************************/\r
-                /* Encode quantization indices of excitation */\r
-                /*********************************************/\r
-                for( i = 0; i < nFramesInPayloadBuf; i++ ) {\r
-                    SKP_Silk_encode_pulses( &psEnc->sCmn.sRC_LBRR, psEnc->sCmn.sigtype[ i ], psEnc->sCmn.QuantOffsetType[ i ],\r
-                        &psEnc->sCmn.q_LBRR[ i * psEnc->sCmn.frame_length ], psEnc->sCmn.frame_length );\r
-                }\r
+            /*********************************************/\r
+            /* Encode quantization indices of excitation */\r
+            /*********************************************/\r
+            for( i = 0; i < nFramesInPayloadBuf; i++ ) {\r
+                SKP_Silk_encode_pulses( &psEnc->sCmn.sRC_LBRR, psEnc->sCmn.sigtype[ i ], psEnc->sCmn.QuantOffsetType[ i ],\r
+                    &psEnc->sCmn.q_LBRR[ i * psEnc->sCmn.frame_length ], psEnc->sCmn.frame_length );\r
             }\r
             /* payload length so far */\r
-            SKP_Silk_range_coder_get_length( &psEnc->sCmn.sRC_LBRR, &nBytes );\r
+            SKP_Silk_range_encoder_get_length( &psEnc->sCmn.sRC_LBRR, &nBytes );\r
 \r
             /* check that there is enough space in external output buffer, and move data */\r
             if( *pnBytesOut >= nBytes ) {\r
-                SKP_Silk_range_enc_wrap_up( &psEnc->sCmn.sRC_LBRR );\r
-                SKP_memcpy( pCode, psEnc->sCmn.sRC_LBRR.buffer, nBytes * sizeof( SKP_uint8 ) );\r
-                \r
+                SKP_int bits_in_stream, mask;\r
+                bits_in_stream = ec_enc_tell( &psEnc->sCmn.sRC_LBRR.range_enc_celt_state, 0 );\r
+                ec_enc_done( &psEnc->sCmn.sRC_LBRR.range_enc_celt_state );\r
+\r
+                /* Fill up any remaining bits in the last byte with 1s */\r
+                if( bits_in_stream & 7 ) {\r
+                    mask = SKP_RSHIFT( 0xFF, bits_in_stream & 7 );\r
+                    if( nBytes - 1 < *pnBytesOut ) {\r
+                        psEnc->sCmn.sRC_LBRR.range_enc_celt_state.buf->buf[ nBytes - 1 ] |= mask;\r
+                    }\r
+                }\r
+                SKP_memcpy( pCode, psEnc->sCmn.sRC_LBRR.range_enc_celt_state.buf->buf, nBytes * sizeof( SKP_uint8 ) );\r
+//#endif\r
                 *pnBytesOut = nBytes;\r
             } else {\r
                 /* not enough space: payload will be discarded */\r
@@ -418,12 +515,12 @@ void SKP_Silk_LBRR_encode_FIX(
 \r
             /* Encode that more frames follows */\r
             frame_terminator = SKP_SILK_MORE_FRAMES;\r
-            SKP_Silk_range_encoder( &psEnc->sCmn.sRC_LBRR, frame_terminator, SKP_Silk_FrameTermination_CDF );\r
+            SKP_Silk_range_encoder( &psEnc->sCmn.sRC_LBRR, frame_terminator, SKP_Silk_FrameTermination_v4_CDF );\r
         }\r
 \r
         /* Restore original Gains */\r
-        SKP_memcpy( psEncCtrl->sCmn.GainsIndices, TempGainsIndices, NB_SUBFR * sizeof( SKP_int   ) );\r
-        SKP_memcpy( psEncCtrl->Gains_Q16,  TempGains_Q16,    NB_SUBFR * sizeof( SKP_int32 ) );\r
+        SKP_memcpy( psEncCtrl->sCmn.GainsIndices, TempGainsIndices, MAX_NB_SUBFR * sizeof( SKP_int   ) );\r
+        SKP_memcpy( psEncCtrl->Gains_Q16,         TempGains_Q16,    MAX_NB_SUBFR * sizeof( SKP_int32 ) );\r
     \r
         /* Restore LTP scale index and typeoffset */\r
         psEncCtrl->sCmn.LTP_scaleIndex = LTP_scaleIndex;\r