summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libopus/silk/CNG.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/CNG.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/CNG.c')
-rw-r--r--lib/rbcodec/codecs/libopus/silk/CNG.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/lib/rbcodec/codecs/libopus/silk/CNG.c b/lib/rbcodec/codecs/libopus/silk/CNG.c
index 8481d95dbe..bb30a7ccf2 100644
--- a/lib/rbcodec/codecs/libopus/silk/CNG.c
+++ b/lib/rbcodec/codecs/libopus/silk/CNG.c
@@ -34,7 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
34 34
35/* Generates excitation for CNG LPC synthesis */ 35/* Generates excitation for CNG LPC synthesis */
36static OPUS_INLINE void silk_CNG_exc( 36static OPUS_INLINE void silk_CNG_exc(
37 opus_int32 residual_Q10[], /* O CNG residual signal Q10 */ 37 opus_int32 exc_Q10[], /* O CNG excitation signal Q10 */
38 opus_int32 exc_buf_Q14[], /* I Random samples buffer Q10 */ 38 opus_int32 exc_buf_Q14[], /* I Random samples buffer Q10 */
39 opus_int32 Gain_Q16, /* I Gain to apply */ 39 opus_int32 Gain_Q16, /* I Gain to apply */
40 opus_int length, /* I Length */ 40 opus_int length, /* I Length */
@@ -55,7 +55,7 @@ static OPUS_INLINE void silk_CNG_exc(
55 idx = (opus_int)( silk_RSHIFT( seed, 24 ) & exc_mask ); 55 idx = (opus_int)( silk_RSHIFT( seed, 24 ) & exc_mask );
56 silk_assert( idx >= 0 ); 56 silk_assert( idx >= 0 );
57 silk_assert( idx <= CNG_BUF_MASK_MAX ); 57 silk_assert( idx <= CNG_BUF_MASK_MAX );
58 residual_Q10[ i ] = (opus_int16)silk_SAT16( silk_SMULWW( exc_buf_Q14[ idx ], Gain_Q16 >> 4 ) ); 58 exc_Q10[ i ] = (opus_int16)silk_SAT16( silk_SMULWW( exc_buf_Q14[ idx ], Gain_Q16 >> 4 ) );
59 } 59 }
60 *rand_seed = seed; 60 *rand_seed = seed;
61} 61}
@@ -85,7 +85,7 @@ void silk_CNG(
85) 85)
86{ 86{
87 opus_int i, subfr; 87 opus_int i, subfr;
88 opus_int32 sum_Q6, max_Gain_Q16; 88 opus_int32 sum_Q6, max_Gain_Q16, gain_Q16;
89 opus_int16 A_Q12[ MAX_LPC_ORDER ]; 89 opus_int16 A_Q12[ MAX_LPC_ORDER ];
90 silk_CNG_struct *psCNG = &psDec->sCNG; 90 silk_CNG_struct *psCNG = &psDec->sCNG;
91 SAVE_STACK; 91 SAVE_STACK;
@@ -125,11 +125,20 @@ void silk_CNG(
125 /* Add CNG when packet is lost or during DTX */ 125 /* Add CNG when packet is lost or during DTX */
126 if( psDec->lossCnt ) { 126 if( psDec->lossCnt ) {
127 VARDECL( opus_int32, CNG_sig_Q10 ); 127 VARDECL( opus_int32, CNG_sig_Q10 );
128
129 ALLOC( CNG_sig_Q10, length + MAX_LPC_ORDER, opus_int32 ); 128 ALLOC( CNG_sig_Q10, length + MAX_LPC_ORDER, opus_int32 );
130 129
131 /* Generate CNG excitation */ 130 /* Generate CNG excitation */
132 silk_CNG_exc( CNG_sig_Q10 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, psCNG->CNG_smth_Gain_Q16, length, &psCNG->rand_seed ); 131 gain_Q16 = silk_SMULWW( psDec->sPLC.randScale_Q14, psDec->sPLC.prevGain_Q16[1] );
132 if( gain_Q16 >= (1 << 21) || psCNG->CNG_smth_Gain_Q16 > (1 << 23) ) {
133 gain_Q16 = silk_SMULTT( gain_Q16, gain_Q16 );
134 gain_Q16 = silk_SUB_LSHIFT32(silk_SMULTT( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 );
135 gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 16 );
136 } else {
137 gain_Q16 = silk_SMULWW( gain_Q16, gain_Q16 );
138 gain_Q16 = silk_SUB_LSHIFT32(silk_SMULWW( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 );
139 gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 8 );
140 }
141 silk_CNG_exc( CNG_sig_Q10 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, gain_Q16, length, &psCNG->rand_seed );
133 142
134 /* Convert CNG NLSF to filter representation */ 143 /* Convert CNG NLSF to filter representation */
135 silk_NLSF2A( A_Q12, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order ); 144 silk_NLSF2A( A_Q12, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order );
@@ -162,7 +171,7 @@ void silk_CNG(
162 /* Update states */ 171 /* Update states */
163 CNG_sig_Q10[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT( CNG_sig_Q10[ MAX_LPC_ORDER + i ], sum_Q6, 4 ); 172 CNG_sig_Q10[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT( CNG_sig_Q10[ MAX_LPC_ORDER + i ], sum_Q6, 4 );
164 173
165 frame[ i ] = silk_ADD_SAT16( frame[ i ], silk_RSHIFT_ROUND( sum_Q6, 6 ) ); 174 frame[ i ] = silk_ADD_SAT16( frame[ i ], silk_RSHIFT_ROUND( CNG_sig_Q10[ MAX_LPC_ORDER + i ], 10 ) );
166 } 175 }
167 silk_memcpy( psCNG->CNG_synth_state, &CNG_sig_Q10[ length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); 176 silk_memcpy( psCNG->CNG_synth_state, &CNG_sig_Q10[ length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );
168 } else { 177 } else {