summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libopus/silk/PLC.c
diff options
context:
space:
mode:
authorNils Wallménius <nils@rockbox.org>2014-01-19 16:31:59 +0100
committerNils Wallménius <nils@rockbox.org>2014-07-13 11:12:40 +0200
commit9b7ec42403073ee887efc531c153e6b1b6c15bab (patch)
tree07e72fe9d817c65a6fede22955344a870842d5e6 /lib/rbcodec/codecs/libopus/silk/PLC.c
parente557951c94c1efa769900257e466900f0ffeb53b (diff)
downloadrockbox-9b7ec42403073ee887efc531c153e6b1b6c15bab.tar.gz
rockbox-9b7ec42403073ee887efc531c153e6b1b6c15bab.zip
Sync to upstream libopus
Sync to commit bb4b6885a139644cf3ac14e7deda9f633ec2d93c This brings in a bunch of optimizations to decode speed and memory usage. Allocations are switched from using the pseudostack to using the real stack. Enabled hacks to reduce stack usage. This should fix crashes on sansa clip, although some files will not play due to failing allocations in the codec buffer. Speeds up decoding of the following test files: H300 (cf) C200 (arm7tdmi) ipod classic (arm9e) 16 kbps (silk) 14.28 MHz 4.00 MHz 2.61 MHz 64 kbps (celt) 4.09 MHz 8.08 MHz 6.24 MHz 128 kbps (celt) 1.93 MHz 8.83 MHz 6.53 MHz Change-Id: I851733a8a5824b61feb363a173091bc7e6629b58
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 */