diff options
Diffstat (limited to 'lib/rbcodec/codecs/libopus/silk/PLC.c')
-rw-r--r-- | lib/rbcodec/codecs/libopus/silk/PLC.c | 53 |
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 | ||
168 | static 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 | |||
168 | static OPUS_INLINE void silk_PLC_conceal( | 192 | static 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 */ |