Update SILK code using the CELT range coder
[opus.git] / src_common / SKP_Silk_decode_core.c
similarity index 57%
rename from src/SKP_Silk_decode_core.c
rename to src_common/SKP_Silk_decode_core.c
index fec15a2..36016a2 100644 (file)
@@ -42,8 +42,10 @@ void SKP_Silk_decode_core(
     SKP_int16   sLTP[ MAX_FRAME_LENGTH ];\r
     SKP_int32   Gain_Q16, *pred_lag_ptr, *pexc_Q10, *pres_Q10, LTP_pred_Q14, LPC_pred_Q10;\r
     SKP_int32   rand_seed, offset_Q10, dither;\r
-    SKP_int32   vec_Q10[ MAX_FRAME_LENGTH / NB_SUBFR ], Atmp;\r
+    SKP_int32   vec_Q10[ MAX_SUB_FRAME_LENGTH ];\r
     SKP_int32   inv_gain_Q16, inv_gain_Q32, gain_adj_Q16, FiltState[ MAX_LPC_ORDER ];\r
+    SKP_int     j;\r
+\r
     SKP_assert( psDec->prev_inv_gain_Q16 != 0 );\r
     \r
     offset_Q10 = SKP_Silk_Quantization_Offsets_Q10[ psDecCtrl->sigtype ][ psDecCtrl->QuantOffsetType ];\r
@@ -54,6 +56,9 @@ void SKP_Silk_decode_core(
         NLSF_interpolation_flag = 0;\r
     }\r
 \r
+#ifdef SAVE_ALL_INTERNAL_DATA\r
+    DEBUG_STORE_DATA( q_dec.dat, q, psDec->frame_length * sizeof( SKP_int ));\r
+#endif\r
 \r
     /* Decode excitation */\r
     rand_seed = psDecCtrl->Seed;\r
@@ -68,13 +73,18 @@ void SKP_Silk_decode_core(
         rand_seed += q[ i ];\r
     }\r
 \r
+#ifdef SAVE_ALL_INTERNAL_DATA\r
+    DEBUG_STORE_DATA( exc_Q10.dat, psDec->exc_Q10, psDec->frame_length * sizeof( SKP_int32 ));\r
+\r
+    /* Resync LTP state here after loss */\r
+#endif\r
 \r
     pexc_Q10 = psDec->exc_Q10;\r
     pres_Q10 = psDec->res_Q10;\r
-    pxq      = &psDec->outBuf[ psDec->frame_length ];\r
-    psDec->sLTP_buf_idx = psDec->frame_length;\r
+    pxq      = &psDec->outBuf[ psDec->ltp_mem_length ];\r
+    psDec->sLTP_buf_idx = psDec->ltp_mem_length;\r
     /* Loop over subframes */\r
-    for( k = 0; k < NB_SUBFR; k++ ) {\r
+    for( k = 0; k < psDec->nb_subfr; k++ ) {\r
         A_Q12 = psDecCtrl->PredCoef_Q12[ k >> 1 ];\r
 \r
         /* Preload LPC coeficients to array on stack. Gives small performance gain */        \r
@@ -84,8 +94,8 @@ void SKP_Silk_decode_core(
         LTP_scale_Q14 = psDecCtrl->LTP_scale_Q14;\r
         sigtype       = psDecCtrl->sigtype;\r
 \r
-        inv_gain_Q16  = SKP_DIV32( SKP_int32_MAX, SKP_RSHIFT( Gain_Q16, 1 ) );\r
-        inv_gain_Q16  = SKP_min( inv_gain_Q16, SKP_int16_MAX );\r
+        inv_gain_Q16 = SKP_INVERSE32_varQ( SKP_max( Gain_Q16, 1 ), 32 );\r
+        inv_gain_Q16 = SKP_min( inv_gain_Q16, SKP_int16_MAX );\r
 \r
         /* Calculate Gain adjustment factor */\r
         gain_adj_Q16 = ( SKP_int32 )1 << 16;\r
@@ -95,7 +105,7 @@ void SKP_Silk_decode_core(
 \r
         /* Avoid abrupt transition from voiced PLC to unvoiced normal decoding */\r
         if( psDec->lossCnt && psDec->prev_sigtype == SIG_TYPE_VOICED &&\r
-            psDecCtrl->sigtype == SIG_TYPE_UNVOICED && k < ( NB_SUBFR >> 1 ) ) {\r
+            psDecCtrl->sigtype == SIG_TYPE_UNVOICED && k < ( MAX_NB_SUBFR >> 1 ) ) {\r
             \r
             SKP_memset( B_Q14, 0, LTP_ORDER * sizeof( SKP_int16 ) );\r
             B_Q14[ LTP_ORDER/2 ] = ( SKP_int16 )1 << 12; /* 0.25 */\r
@@ -104,6 +114,7 @@ void SKP_Silk_decode_core(
             psDecCtrl->pitchL[ k ] = psDec->lagPrev;\r
             LTP_scale_Q14 = ( SKP_int )1 << 14;\r
         }\r
+\r
         if( sigtype == SIG_TYPE_VOICED ) {\r
             /* Voiced */\r
             \r
@@ -111,11 +122,12 @@ void SKP_Silk_decode_core(
             /* Re-whitening */\r
             if( ( k & ( 3 - SKP_LSHIFT( NLSF_interpolation_flag, 1 ) ) ) == 0 ) {\r
                 /* Rewhiten with new A coefs */\r
-                start_idx = psDec->frame_length - lag - psDec->LPC_order - LTP_ORDER / 2;\r
-                start_idx = SKP_LIMIT( start_idx, 0, psDec->frame_length - psDec->LPC_order );\r
+                start_idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2;\r
+                start_idx = SKP_LIMIT_int( start_idx, 0, psDec->ltp_mem_length - psDec->LPC_order );\r
 \r
-                SKP_Silk_MA_Prediction( &psDec->outBuf[ start_idx + k * ( psDec->frame_length >> 2 ) ], \r
-                    A_Q12, FiltState, sLTP + start_idx, psDec->frame_length - start_idx, psDec->LPC_order );\r
+                SKP_memset( FiltState, 0, psDec->LPC_order * sizeof( SKP_int32 ) ); /* Not really necessary, but Valgrind and Coverity will complain otherwise */\r
+                SKP_Silk_MA_Prediction( &psDec->outBuf[ start_idx + k * psDec->subfr_length ], \r
+                    A_Q12, FiltState, sLTP + start_idx, psDec->ltp_mem_length - start_idx, psDec->LPC_order );\r
 \r
                 /* After rewhitening the LTP state is unscaled */\r
                 inv_gain_Q32 = SKP_LSHIFT( inv_gain_Q16, 16 );\r
@@ -124,7 +136,7 @@ void SKP_Silk_decode_core(
                     inv_gain_Q32 = SKP_LSHIFT( SKP_SMULWB( inv_gain_Q32, psDecCtrl->LTP_scale_Q14 ), 2 );\r
                 }\r
                 for( i = 0; i < (lag + LTP_ORDER/2); i++ ) {\r
-                    psDec->sLTP_Q16[ psDec->sLTP_buf_idx - i - 1 ] = SKP_SMULWB( inv_gain_Q32, sLTP[ psDec->frame_length - i - 1 ] );\r
+                    psDec->sLTP_Q16[ psDec->sLTP_buf_idx - i - 1 ] = SKP_SMULWB( inv_gain_Q32, sLTP[ psDec->ltp_mem_length - i - 1 ] );\r
                 }\r
             } else {\r
                 /* Update LTP state when Gain changes */\r
@@ -145,7 +157,6 @@ void SKP_Silk_decode_core(
         SKP_assert( inv_gain_Q16 != 0 );\r
         psDec->prev_inv_gain_Q16 = inv_gain_Q16;\r
 \r
-\r
         /* Long-term prediction */\r
         if( sigtype == SIG_TYPE_VOICED ) {\r
             /* Setup pointer */\r
@@ -170,72 +181,32 @@ void SKP_Silk_decode_core(
             SKP_memcpy( pres_Q10, pexc_Q10, psDec->subfr_length * sizeof( SKP_int32 ) );\r
         }\r
 \r
+#ifdef SAVE_ALL_INTERNAL_DATA\r
+        DEBUG_STORE_DATA( res_Q10.dat, pres_Q10, psDec->subfr_length * sizeof( SKP_int32 ) );\r
+#endif\r
 \r
-        /* Short term prediction */\r
-        /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the   */\r
-        /* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be     */\r
-        /* loaded in reverse order and the code will give the wrong result. In that case swapping   */\r
-        /* the SMLAWB and SMLAWT instructions should solve the problem.                             */\r
-        if( psDec->LPC_order == 16 ) {\r
-            for( i = 0; i < psDec->subfr_length; i++ ) {\r
-                /* unrolled */\r
-                Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 0 ] );    /* read two coefficients at once */\r
-                LPC_pred_Q10 = SKP_SMULWB(               psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  1 ], Atmp );\r
-                LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  2 ], Atmp );\r
-                Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 2 ] );\r
-                LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  3 ], Atmp );\r
-                LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  4 ], Atmp );\r
-                Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 4 ] );\r
-                LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  5 ], Atmp );\r
-                LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  6 ], Atmp );\r
-                Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 6 ] );\r
-                LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  7 ], Atmp );\r
-                LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  8 ], Atmp );\r
-                Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 8 ] );\r
-                LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  9 ], Atmp );\r
-                LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], Atmp );\r
-                Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 10 ] );\r
-                LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 11 ], Atmp );\r
-                LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 12 ], Atmp );\r
-                Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 12 ] );\r
-                LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 13 ], Atmp );\r
-                LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 14 ], Atmp );\r
-                Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 14 ] );\r
-                LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 15 ], Atmp );\r
-                LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 16 ], Atmp );\r
-                \r
-                /* Add prediction to LPC residual */\r
-                vec_Q10[ i ] = SKP_ADD32( pres_Q10[ i ], LPC_pred_Q10 );\r
-                \r
-                /* Update states */\r
-                psDec->sLPC_Q14[ MAX_LPC_ORDER + i ] = SKP_LSHIFT( vec_Q10[ i ], 4 );\r
-            }\r
-        } else {\r
-            SKP_assert( psDec->LPC_order == 10 );\r
-            for( i = 0; i < psDec->subfr_length; i++ ) {\r
-                /* unrolled */\r
-                Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 0 ] );    /* read two coefficients at once */\r
-                LPC_pred_Q10 = SKP_SMULWB(               psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  1 ], Atmp );\r
-                LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  2 ], Atmp );\r
-                Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 2 ] );\r
-                LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  3 ], Atmp );\r
-                LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  4 ], Atmp );\r
-                Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 4 ] );\r
-                LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  5 ], Atmp );\r
-                LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  6 ], Atmp );\r
-                Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 6 ] );\r
-                LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  7 ], Atmp );\r
-                LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  8 ], Atmp );\r
-                Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 8 ] );\r
-                LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  9 ], Atmp );\r
-                LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], Atmp );\r
-                \r
-                /* Add prediction to LPC residual */\r
-                vec_Q10[ i ] = SKP_ADD32( pres_Q10[ i ], LPC_pred_Q10 );\r
-                \r
-                /* Update states */\r
-                psDec->sLPC_Q14[ MAX_LPC_ORDER + i ] = SKP_LSHIFT( vec_Q10[ i ], 4 );\r
+        for( i = 0; i < psDec->subfr_length; i++ ) {\r
+            /* Partially unrolled */\r
+            LPC_pred_Q10 = SKP_SMULWB(               psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  1 ], A_Q12_tmp[ 0 ] );\r
+            LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  2 ], A_Q12_tmp[ 1 ] );\r
+            LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  3 ], A_Q12_tmp[ 2 ] );\r
+            LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  4 ], A_Q12_tmp[ 3 ] );\r
+            LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  5 ], A_Q12_tmp[ 4 ] );\r
+            LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  6 ], A_Q12_tmp[ 5 ] );\r
+            LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  7 ], A_Q12_tmp[ 6 ] );\r
+            LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  8 ], A_Q12_tmp[ 7 ] );\r
+            LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  9 ], A_Q12_tmp[ 8 ] );\r
+            LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12_tmp[ 9 ] );\r
+\r
+            for( j = 10; j < psDec->LPC_order; j ++ ) {\r
+                LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - j - 1 ], A_Q12_tmp[ j ] );\r
             }\r
+\r
+            /* Add prediction to LPC residual */\r
+            vec_Q10[ i ] = SKP_ADD32( pres_Q10[ i ], LPC_pred_Q10 );\r
+            \r
+            /* Update states */\r
+            psDec->sLPC_Q14[ MAX_LPC_ORDER + i ] = SKP_LSHIFT( vec_Q10[ i ], 4 );\r
         }\r
 \r
         /* Scale with Gain */\r
@@ -251,6 +222,10 @@ void SKP_Silk_decode_core(
     }\r
     \r
     /* Copy to output */\r
-    SKP_memcpy( xq, &psDec->outBuf[ psDec->frame_length ], psDec->frame_length * sizeof( SKP_int16 ) );\r
+    SKP_memcpy( xq, &psDec->outBuf[ psDec->ltp_mem_length ], psDec->frame_length * sizeof( SKP_int16 ) );\r
 \r
+#ifdef SAVE_ALL_INTERNAL_DATA\r
+    DEBUG_STORE_DATA( LTP_buf_Q16.dat, &psDec->sLTP_Q16[psDec->frame_length], psDec->frame_length * sizeof( SKP_int32 ));\r
+    DEBUG_STORE_DATA( xq_dec.dat, xq, psDec->frame_length * sizeof( SKP_int16 ) );\r
+#endif\r
 }\r