Fixes two SILK PLC issues
authorKoen Vos <koen.vos@skype.net>
Sat, 29 Oct 2011 01:05:22 +0000 (21:05 -0400)
committerJean-Marc Valin <jmvalin@jmvalin.ca>
Sat, 29 Oct 2011 01:05:22 +0000 (21:05 -0400)
- Calling the decoder for FEC when there's no LBRR should no longer crash
- There should no longer be an issue with the PLC on frame size switching

silk/PLC.c
silk/init_decoder.c [moved from silk/create_init_destroy.c with 100% similarity]
silk/silk_common.vcxproj
silk/silk_common.vcxproj.filters
silk/structs.h

index e2ad20a..264b725 100644 (file)
@@ -54,6 +54,8 @@ void silk_PLC_Reset(
 )
 {
     psDec->sPLC.pitchL_Q8 = silk_RSHIFT( psDec->frame_length, 1 );
+    psDec->sPLC.prevGain_Q16[ 0 ] = SILK_FIX_CONST( 1, 16 );
+    psDec->sPLC.prevGain_Q16[ 1 ] = SILK_FIX_CONST( 1, 16 );
 }
 
 void silk_PLC(
@@ -155,8 +157,11 @@ static inline void silk_PLC_update(
     silk_memcpy( psPLC->prevLPC_Q12, psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( opus_int16 ) );
     psPLC->prevLTP_scale_Q14 = psDecCtrl->LTP_scale_Q14;
 
-    /* Save Gains */
-    silk_memcpy( psPLC->prevGain_Q16, psDecCtrl->Gains_Q16, psDec->nb_subfr * sizeof( opus_int32 ) );
+    /* Save last two gains */
+    silk_memcpy( psPLC->prevGain_Q16, &psDecCtrl->Gains_Q16[ psDec->nb_subfr - 2 ], 2 * sizeof( opus_int32 ) );
+
+    psPLC->subfr_length = psDec->subfr_length;
+    psPLC->nb_subfr = psDec->nb_subfr;
 }
 
 static inline void silk_PLC_conceal(
@@ -182,23 +187,23 @@ static inline void silk_PLC_conceal(
     /* Find random noise component */
     /* Scale previous excitation signal */
     exc_buf_ptr = exc_buf;
-    for( k = psDec->nb_subfr - 2; k < psDec->nb_subfr; k++ ) {
-        for( i = 0; i < psDec->subfr_length; i++ ) {
+    for( k = 0; k < 2; k++ ) {
+        for( i = 0; i < psPLC->subfr_length; i++ ) {
             exc_buf_ptr[ i ] = ( opus_int16 )silk_RSHIFT(
-                silk_SMULWW( psDec->exc_Q10[ i + k * psDec->subfr_length ], psPLC->prevGain_Q16[ k ] ), 10 );
+                silk_SMULWW( psDec->exc_Q10[ i + ( k + psPLC->nb_subfr - 2 ) * psPLC->subfr_length ], psPLC->prevGain_Q16[ k ] ), 10 );
         }
-        exc_buf_ptr += psDec->subfr_length;
+        exc_buf_ptr += psPLC->subfr_length;
     }
     /* Find the subframe with lowest energy of the last two and use that as random noise generator */
-    silk_sum_sqr_shift( &energy1, &shift1, exc_buf,                         psDec->subfr_length );
-    silk_sum_sqr_shift( &energy2, &shift2, &exc_buf[ psDec->subfr_length ], psDec->subfr_length );
+    silk_sum_sqr_shift( &energy1, &shift1, exc_buf,                         psPLC->subfr_length );
+    silk_sum_sqr_shift( &energy2, &shift2, &exc_buf[ psDec->subfr_length ], psPLC->subfr_length );
 
     if( silk_RSHIFT( energy1, shift2 ) < silk_RSHIFT( energy2, shift1 ) ) {
         /* First sub-frame has lowest energy */
-        rand_ptr = &psDec->exc_Q10[ silk_max_int( 0, psDec->frame_length - psDec->subfr_length - RAND_BUF_SIZE ) ];
+        rand_ptr = &psDec->exc_Q10[ silk_max_int( 0, ( psPLC->nb_subfr - 1 ) * psPLC->subfr_length - RAND_BUF_SIZE ) ];
     } else {
         /* Second sub-frame has lowest energy */
-        rand_ptr = &psDec->exc_Q10[ silk_max_int( 0, psDec->frame_length - RAND_BUF_SIZE ) ];
+        rand_ptr = &psDec->exc_Q10[ silk_max_int( 0, psPLC->nb_subfr * psPLC->subfr_length - RAND_BUF_SIZE ) ];
     }
 
     /* Setup Gain to random noise component */
@@ -253,7 +258,7 @@ static inline void silk_PLC_conceal(
     silk_assert( idx > 0 );
     silk_LPC_analysis_filter( &sLTP[ idx ], &psDec->outBuf[ idx ], A_Q12, psDec->ltp_mem_length - idx, psDec->LPC_order );
     /* Scale LTP state */
-    inv_gain_Q16 = silk_INVERSE32_varQ( psPLC->prevGain_Q16[ psDec->nb_subfr - 1 ], 32 );
+    inv_gain_Q16 = silk_INVERSE32_varQ( psPLC->prevGain_Q16[ 1 ], 32 );
     inv_gain_Q16 = silk_min( inv_gain_Q16, silk_int16_MAX );
     inv_gain_Q30 = silk_LSHIFT( inv_gain_Q16, 14 );
     for( i = idx + psDec->LPC_order; i < psDec->ltp_mem_length; i++ ) {
@@ -326,7 +331,7 @@ static inline void silk_PLC_conceal(
         sLPC_Q14_ptr[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT32( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], LPC_pred_Q10, 4 );
 
         /* Scale with Gain */
-        frame[ i ] = ( opus_int16 )silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], psPLC->prevGain_Q16[ psDec->nb_subfr - 1 ] ), 14 ) );
+        frame[ i ] = ( opus_int16 )silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], psPLC->prevGain_Q16[ 1 ] ), 14 ) );
     }
 
     /* Save LPC state */
@@ -342,7 +347,7 @@ static inline void silk_PLC_conceal(
     }
 }
 
-/* Glues concealed frames with new good recieved frames             */
+/* Glues concealed frames with new good recieved frames */
 void silk_PLC_glue_frames(
     silk_decoder_state                  *psDec,             /* I/O decoder state        */
     opus_int16                          frame[],            /* I/O signal               */
index b10a6f2..027321c 100644 (file)
@@ -97,7 +97,6 @@
     <ClCompile Include="control_audio_bandwidth.c" />
     <ClCompile Include="control_codec.c" />
     <ClCompile Include="control_SNR.c" />
-    <ClCompile Include="create_init_destroy.c" />
     <ClCompile Include="debug.c" />
     <ClCompile Include="decoder_set_fs.c" />
     <ClCompile Include="decode_core.c" />
     <ClCompile Include="enc_API.c" />
     <ClCompile Include="gain_quant.c" />
     <ClCompile Include="HP_variable_cutoff.c" />
+    <ClCompile Include="init_decoder.c" />
     <ClCompile Include="init_encoder.c" />
     <ClCompile Include="inner_prod_aligned.c" />
     <ClCompile Include="interpolate.c" />
index f83f070..3c3d30b 100644 (file)
@@ -51,9 +51,6 @@
     <ClCompile Include="control_SNR.c">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="create_init_destroy.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="debug.c">
       <Filter>Source Files</Filter>
     </ClCompile>
     <ClCompile Include="VQ_WMat_EC.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="init_decoder.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\win32\config.h">
index 0275019..9f7fd29 100644 (file)
@@ -237,8 +237,10 @@ typedef struct {
     opus_int32                  conc_energy;
     opus_int                    conc_energy_shift;
     opus_int16                  prevLTP_scale_Q14;
-    opus_int32                  prevGain_Q16[ MAX_NB_SUBFR ];
+    opus_int32                  prevGain_Q16[ 2 ];
     opus_int                    fs_kHz;
+    opus_int                    nb_subfr;
+    opus_int                    subfr_length;
 } silk_PLC_struct;
 
 /* Struct for CNG */