summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libopus/silk/CNG.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libopus/silk/CNG.c')
-rw-r--r--lib/rbcodec/codecs/libopus/silk/CNG.c83
1 files changed, 43 insertions, 40 deletions
diff --git a/lib/rbcodec/codecs/libopus/silk/CNG.c b/lib/rbcodec/codecs/libopus/silk/CNG.c
index bb30a7ccf2..ef8e38df9f 100644
--- a/lib/rbcodec/codecs/libopus/silk/CNG.c
+++ b/lib/rbcodec/codecs/libopus/silk/CNG.c
@@ -34,9 +34,8 @@ 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 exc_Q10[], /* O CNG excitation signal Q10 */ 37 opus_int32 exc_Q14[], /* 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 */
40 opus_int length, /* I Length */ 39 opus_int length, /* I Length */
41 opus_int32 *rand_seed /* I/O Seed to random index generator */ 40 opus_int32 *rand_seed /* I/O Seed to random index generator */
42) 41)
@@ -55,7 +54,7 @@ static OPUS_INLINE void silk_CNG_exc(
55 idx = (opus_int)( silk_RSHIFT( seed, 24 ) & exc_mask ); 54 idx = (opus_int)( silk_RSHIFT( seed, 24 ) & exc_mask );
56 silk_assert( idx >= 0 ); 55 silk_assert( idx >= 0 );
57 silk_assert( idx <= CNG_BUF_MASK_MAX ); 56 silk_assert( idx <= CNG_BUF_MASK_MAX );
58 exc_Q10[ i ] = (opus_int16)silk_SAT16( silk_SMULWW( exc_buf_Q14[ idx ], Gain_Q16 >> 4 ) ); 57 exc_Q14[ i ] = exc_buf_Q14[ idx ];
59 } 58 }
60 *rand_seed = seed; 59 *rand_seed = seed;
61} 60}
@@ -85,7 +84,7 @@ void silk_CNG(
85) 84)
86{ 85{
87 opus_int i, subfr; 86 opus_int i, subfr;
88 opus_int32 sum_Q6, max_Gain_Q16, gain_Q16; 87 opus_int32 LPC_pred_Q10, max_Gain_Q16, gain_Q16, gain_Q10;
89 opus_int16 A_Q12[ MAX_LPC_ORDER ]; 88 opus_int16 A_Q12[ MAX_LPC_ORDER ];
90 silk_CNG_struct *psCNG = &psDec->sCNG; 89 silk_CNG_struct *psCNG = &psDec->sCNG;
91 SAVE_STACK; 90 SAVE_STACK;
@@ -124,56 +123,60 @@ void silk_CNG(
124 123
125 /* Add CNG when packet is lost or during DTX */ 124 /* Add CNG when packet is lost or during DTX */
126 if( psDec->lossCnt ) { 125 if( psDec->lossCnt ) {
127 VARDECL( opus_int32, CNG_sig_Q10 ); 126 VARDECL( opus_int32, CNG_sig_Q14 );
128 ALLOC( CNG_sig_Q10, length + MAX_LPC_ORDER, opus_int32 ); 127 ALLOC( CNG_sig_Q14, length + MAX_LPC_ORDER, opus_int32 );
129 128
130 /* Generate CNG excitation */ 129 /* Generate CNG excitation */
131 gain_Q16 = silk_SMULWW( psDec->sPLC.randScale_Q14, psDec->sPLC.prevGain_Q16[1] ); 130 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) ) { 131 if( gain_Q16 >= (1 << 21) || psCNG->CNG_smth_Gain_Q16 > (1 << 23) ) {
133 gain_Q16 = silk_SMULTT( gain_Q16, gain_Q16 ); 132 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 ); 133 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 ); 134 gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 16 );
136 } else { 135 } else {
137 gain_Q16 = silk_SMULWW( gain_Q16, gain_Q16 ); 136 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 ); 137 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 ); 138 gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 8 );
140 } 139 }
141 silk_CNG_exc( CNG_sig_Q10 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, gain_Q16, length, &psCNG->rand_seed ); 140 gain_Q10 = silk_RSHIFT( gain_Q16, 6 );
141
142 silk_CNG_exc( CNG_sig_Q14 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, length, &psCNG->rand_seed );
142 143
143 /* Convert CNG NLSF to filter representation */ 144 /* Convert CNG NLSF to filter representation */
144 silk_NLSF2A( A_Q12, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order ); 145 silk_NLSF2A( A_Q12, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order, psDec->arch );
145 146
146 /* Generate CNG signal, by synthesis filtering */ 147 /* Generate CNG signal, by synthesis filtering */
147 silk_memcpy( CNG_sig_Q10, psCNG->CNG_synth_state, MAX_LPC_ORDER * sizeof( opus_int32 ) ); 148 silk_memcpy( CNG_sig_Q14, psCNG->CNG_synth_state, MAX_LPC_ORDER * sizeof( opus_int32 ) );
149 celt_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
148 for( i = 0; i < length; i++ ) { 150 for( i = 0; i < length; i++ ) {
149 silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
150 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ 151 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
151 sum_Q6 = silk_RSHIFT( psDec->LPC_order, 1 ); 152 LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 );
152 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 1 ], A_Q12[ 0 ] ); 153 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12[ 0 ] );
153 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 2 ], A_Q12[ 1 ] ); 154 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 2 ], A_Q12[ 1 ] );
154 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 3 ], A_Q12[ 2 ] ); 155 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 3 ], A_Q12[ 2 ] );
155 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 4 ], A_Q12[ 3 ] ); 156 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 4 ], A_Q12[ 3 ] );
156 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 5 ], A_Q12[ 4 ] ); 157 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 5 ], A_Q12[ 4 ] );
157 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 6 ], A_Q12[ 5 ] ); 158 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 6 ], A_Q12[ 5 ] );
158 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 7 ], A_Q12[ 6 ] ); 159 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 7 ], A_Q12[ 6 ] );
159 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 8 ], A_Q12[ 7 ] ); 160 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 8 ], A_Q12[ 7 ] );
160 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 9 ], A_Q12[ 8 ] ); 161 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 9 ], A_Q12[ 8 ] );
161 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] ); 162 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] );
162 if( psDec->LPC_order == 16 ) { 163 if( psDec->LPC_order == 16 ) {
163 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 11 ], A_Q12[ 10 ] ); 164 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 11 ], A_Q12[ 10 ] );
164 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 12 ], A_Q12[ 11 ] ); 165 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 12 ], A_Q12[ 11 ] );
165 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 13 ], A_Q12[ 12 ] ); 166 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 13 ], A_Q12[ 12 ] );
166 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 14 ], A_Q12[ 13 ] ); 167 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 14 ], A_Q12[ 13 ] );
167 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 15 ], A_Q12[ 14 ] ); 168 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 15 ], A_Q12[ 14 ] );
168 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 16 ], A_Q12[ 15 ] ); 169 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 16 ], A_Q12[ 15 ] );
169 } 170 }
170 171
171 /* Update states */ 172 /* Update states */
172 CNG_sig_Q10[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT( CNG_sig_Q10[ MAX_LPC_ORDER + i ], sum_Q6, 4 ); 173 CNG_sig_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_SAT32( CNG_sig_Q14[ MAX_LPC_ORDER + i ], silk_LSHIFT_SAT32( LPC_pred_Q10, 4 ) );
174
175 /* Scale with Gain and add to input signal */
176 frame[ i ] = (opus_int16)silk_ADD_SAT16( frame[ i ], silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( CNG_sig_Q14[ MAX_LPC_ORDER + i ], gain_Q10 ), 8 ) ) );
173 177
174 frame[ i ] = silk_ADD_SAT16( frame[ i ], silk_RSHIFT_ROUND( CNG_sig_Q10[ MAX_LPC_ORDER + i ], 10 ) );
175 } 178 }
176 silk_memcpy( psCNG->CNG_synth_state, &CNG_sig_Q10[ length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); 179 silk_memcpy( psCNG->CNG_synth_state, &CNG_sig_Q14[ length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );
177 } else { 180 } else {
178 silk_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order * sizeof( opus_int32 ) ); 181 silk_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order * sizeof( opus_int32 ) );
179 } 182 }