summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libopus/silk/PLC.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libopus/silk/PLC.c')
-rw-r--r--lib/rbcodec/codecs/libopus/silk/PLC.c53
1 files changed, 36 insertions, 17 deletions
diff --git a/lib/rbcodec/codecs/libopus/silk/PLC.c b/lib/rbcodec/codecs/libopus/silk/PLC.c
index 01f40014c4..8b0a8fe57d 100644
--- a/lib/rbcodec/codecs/libopus/silk/PLC.c
+++ b/lib/rbcodec/codecs/libopus/silk/PLC.c
@@ -165,6 +165,30 @@ static OPUS_INLINE void silk_PLC_update(
165 psPLC->nb_subfr = psDec->nb_subfr; 165 psPLC->nb_subfr = psDec->nb_subfr;
166} 166}
167 167
168static OPUS_INLINE void silk_PLC_energy(opus_int32 *energy1, opus_int *shift1, opus_int32 *energy2, opus_int *shift2,
169 const opus_int32 *exc_Q14, const opus_int32 *prevGain_Q10, int subfr_length, int nb_subfr)
170{
171 int i, k;
172 VARDECL( opus_int16, exc_buf );
173 opus_int16 *exc_buf_ptr;
174 SAVE_STACK;
175 ALLOC( exc_buf, 2*subfr_length, opus_int16 );
176 /* Find random noise component */
177 /* Scale previous excitation signal */
178 exc_buf_ptr = exc_buf;
179 for( k = 0; k < 2; k++ ) {
180 for( i = 0; i < subfr_length; i++ ) {
181 exc_buf_ptr[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT(
182 silk_SMULWW( exc_Q14[ i + ( k + nb_subfr - 2 ) * subfr_length ], prevGain_Q10[ k ] ), 8 ) );
183 }
184 exc_buf_ptr += subfr_length;
185 }
186 /* Find the subframe with lowest energy of the last two and use that as random noise generator */
187 silk_sum_sqr_shift( energy1, shift1, exc_buf, subfr_length );
188 silk_sum_sqr_shift( energy2, shift2, &exc_buf[ subfr_length ], subfr_length );
189 RESTORE_STACK;
190}
191
168static OPUS_INLINE void silk_PLC_conceal( 192static OPUS_INLINE void silk_PLC_conceal(
169 silk_decoder_state *psDec, /* I/O Decoder state */ 193 silk_decoder_state *psDec, /* I/O Decoder state */
170 silk_decoder_control *psDecCtrl, /* I/O Decoder control */ 194 silk_decoder_control *psDecCtrl, /* I/O Decoder control */
@@ -177,19 +201,26 @@ static OPUS_INLINE void silk_PLC_conceal(
177 opus_int32 energy1, energy2, *rand_ptr, *pred_lag_ptr; 201 opus_int32 energy1, energy2, *rand_ptr, *pred_lag_ptr;
178 opus_int32 LPC_pred_Q10, LTP_pred_Q12; 202 opus_int32 LPC_pred_Q10, LTP_pred_Q12;
179 opus_int16 rand_scale_Q14; 203 opus_int16 rand_scale_Q14;
180 opus_int16 *B_Q14, *exc_buf_ptr; 204 opus_int16 *B_Q14;
181 opus_int32 *sLPC_Q14_ptr; 205 opus_int32 *sLPC_Q14_ptr;
182 VARDECL( opus_int16, exc_buf );
183 opus_int16 A_Q12[ MAX_LPC_ORDER ]; 206 opus_int16 A_Q12[ MAX_LPC_ORDER ];
207#ifdef SMALL_FOOTPRINT
208 opus_int16 *sLTP;
209#else
184 VARDECL( opus_int16, sLTP ); 210 VARDECL( opus_int16, sLTP );
211#endif
185 VARDECL( opus_int32, sLTP_Q14 ); 212 VARDECL( opus_int32, sLTP_Q14 );
186 silk_PLC_struct *psPLC = &psDec->sPLC; 213 silk_PLC_struct *psPLC = &psDec->sPLC;
187 opus_int32 prevGain_Q10[2]; 214 opus_int32 prevGain_Q10[2];
188 SAVE_STACK; 215 SAVE_STACK;
189 216
190 ALLOC( exc_buf, 2*psPLC->subfr_length, opus_int16 );
191 ALLOC( sLTP, psDec->ltp_mem_length, opus_int16 );
192 ALLOC( sLTP_Q14, psDec->ltp_mem_length + psDec->frame_length, opus_int32 ); 217 ALLOC( sLTP_Q14, psDec->ltp_mem_length + psDec->frame_length, opus_int32 );
218#ifdef SMALL_FOOTPRINT
219 /* Ugly hack that breaks aliasing rules to save stack: put sLTP at the very end of sLTP_Q14. */
220 sLTP = ((opus_int16*)&sLTP_Q14[psDec->ltp_mem_length + psDec->frame_length])-psDec->ltp_mem_length;
221#else
222 ALLOC( sLTP, psDec->ltp_mem_length, opus_int16 );
223#endif
193 224
194 prevGain_Q10[0] = silk_RSHIFT( psPLC->prevGain_Q16[ 0 ], 6); 225 prevGain_Q10[0] = silk_RSHIFT( psPLC->prevGain_Q16[ 0 ], 6);
195 prevGain_Q10[1] = silk_RSHIFT( psPLC->prevGain_Q16[ 1 ], 6); 226 prevGain_Q10[1] = silk_RSHIFT( psPLC->prevGain_Q16[ 1 ], 6);
@@ -198,19 +229,7 @@ static OPUS_INLINE void silk_PLC_conceal(
198 silk_memset( psPLC->prevLPC_Q12, 0, sizeof( psPLC->prevLPC_Q12 ) ); 229 silk_memset( psPLC->prevLPC_Q12, 0, sizeof( psPLC->prevLPC_Q12 ) );
199 } 230 }
200 231
201 /* Find random noise component */ 232 silk_PLC_energy(&energy1, &shift1, &energy2, &shift2, psDec->exc_Q14, prevGain_Q10, psDec->subfr_length, psDec->nb_subfr);
202 /* Scale previous excitation signal */
203 exc_buf_ptr = exc_buf;
204 for( k = 0; k < 2; k++ ) {
205 for( i = 0; i < psPLC->subfr_length; i++ ) {
206 exc_buf_ptr[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT(
207 silk_SMULWW( psDec->exc_Q14[ i + ( k + psPLC->nb_subfr - 2 ) * psPLC->subfr_length ], prevGain_Q10[ k ] ), 8 ) );
208 }
209 exc_buf_ptr += psPLC->subfr_length;
210 }
211 /* Find the subframe with lowest energy of the last two and use that as random noise generator */
212 silk_sum_sqr_shift( &energy1, &shift1, exc_buf, psPLC->subfr_length );
213 silk_sum_sqr_shift( &energy2, &shift2, &exc_buf[ psPLC->subfr_length ], psPLC->subfr_length );
214 233
215 if( silk_RSHIFT( energy1, shift2 ) < silk_RSHIFT( energy2, shift1 ) ) { 234 if( silk_RSHIFT( energy1, shift2 ) < silk_RSHIFT( energy2, shift1 ) ) {
216 /* First sub-frame has lowest energy */ 235 /* First sub-frame has lowest energy */